6. Historia de las pruebas
Período orientado a la destrucción
(1979 - 1982)
7. Historia de las pruebas
Período orientado a la evaluación
(1983 - 1987)
8. Historia de las pruebas
“Ninguna técnica puede garantizar software
sin errores, sin embargo, un conjunto de
técnicas cuidadosamente elegidas para un
proyecto en específico puede ayudar a
asegurar el desarrollo y mantenimiento de
software de calidad para un proyecto”
9. Historia de las pruebas
Período orientado a la prevención
(1988 - Hoy)
18. Carga de datos
class Profession(models.Model):
name = models.CharField(max_length=30, unique=True)
specialist = models.CharField(max_length=30, blank=True)
20. Carga de datos
class Profession(models.Model):
name = models.CharField(max_length=30, unique=True)
specialist = models.CharField(max_length=30, blank=True)
full_time = models.BooleanField(default=False) <----
24. Carga de datos
Estructura del App
my_app/
__init__.py
models.py
fixtures/base.json <------
tests.py
25. Carga de datos
class UserTest(TestCase):
fixtures = ['base.json']
def setUp(self):
pass
def tearDown(self):
pass
def test_coolness(self):
# usuario con id == 1 existe gracias al fixture
user = User.objects.get(id=1)
self.assertTrue(user.is_cool, False)
user.become_a_hipster()
self.assertTrue(user.is_cool, True)
26. Carga de datos
Factories
https://github.com/dnerdy/factory_boy
28. Carga de datos
from django.db import models
class Receipt(models.Model):
user_id = fields.IntegerField()
merchant = fields.CharField(max_length=30)
class ReceiptItem(models.Model):
name = models.CharField(max_length=30)
quantity = models.IntegerField(default=1)
alert_sent = models.BooleanField(default=False)
receipt = models.ForeignKey(Receipt)
class Attach(models.Model):
name = models.CharField(max_length=30)
item = models.ForeignKey(ReceiptItem)
29. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
rep = Receipt(user_id=1, merchant='mami')
rep.save()
ri = ReceiptItem(name='medias', quantity=2,
receipt=rep)
ri.save()
att = Attach(name='foto_de_juanita.jpg', item=ri)
att.save()
...
30. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
rep = Receipt(user_id=1, merchant='mami')
rep.save()
ri = ReceiptItem(name='medias', quantity=2)
ri.save()
att = Attach(name='foto_de_juanita.jpg', item=ri)
att.save()
...
31. Carga de datos
Estructura del App
my_app/
__init__.py
models.py
fixtures/base.json
factories.py <-------
tests.py
32. Carga de datos
class ReceiptFactory(factory.Factory):
FACTORY_FOR = Receipt
user_id = 1
merchant = "mami"
class ReceiptItemFactory(factory.Factory):
FACTORY_FOR = ReceiptItem
name = factory.Sequence(lambda n: 'item-%s' % n)
quantity = 1
receipt = ReceiptFactory()
class AttachmentFactory(factory.Factory):
FACTORY_FOR = Attachment
name = factory.Sequence(lambda n: 'attachment-%s' % n)
item = ReceiptItemFactory()
33. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
ReceiptFactory()
...
37. Carga de datos
Factories
●
Organizado
●
Flexible <-------
38. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
# No se crea en base de datos
ReceiptFactory.build()
...
39. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
# Crear muchos objects
ReceiptFactory.create_batch(5)
...
40. Carga de datos
Factories
●
Organizado
●
Flexible
●
Facil de migrar
<-------
41. Carga de datos
from mongoengine.document import Document, EmbeddedDocument
class Attach(EmbeddedDocument):
name = fields.StringField(required=True)
class ReceiptItem(EmbeddedDocument):
name = fields.StringField(required=True)
quantity = fields.DecimalField(default=Decimal(1))
alert_sent = fields.BooleanField(default=False)
attachments = fields.ListField(fields.EmbeddedDocumentField(Attach))
class Receipt(Document):
user_id = fields.IntField(required=True)
merchant = fields.StringField(required=True)
items = fields.ListField(fields.EmbeddedDocumentField(ReceiptItem))
42. Carga de datos
class AttachmentFactory(factory.Factory):
FACTORY_FOR = Attachment
name = factory.Sequence(lambda n: 'attachment-%s' % n)
class ReceiptItemFactory(factory.Factory):
FACTORY_FOR = ReceiptItem
name = factory.Sequence(lambda n: 'item-%s' % n)
quantity = 1
Attachments = [AttachmentFactory.build()]
class ReceiptFactory(factory.Factory):
FACTORY_FOR = Receipt
user_id = 2
merchant = "Amazon"
items = [ReceiptItemFactory.build()]
43. Carga de datos
class ReceiptTest(TestCase):
fixtures = ['base.json']
def setUp(self):
ReceiptFactory()
...
51. Tips
MAL
def test_gmail(self):
expected_msg = {
'subject': 'SeamlessWeb Order',
'plain': '[image: Seamless Web Logo] ...' # MAL
'html': 'n<table width="640" border=...' # MAL
}
m = Message.objects.get(pk=1)
msg = {
'subject': m.subject,
'html': m.body_mimetype_html,
'plain': m.body_mimetype_plain
}
msg = strip_forwarding(msg)
self.assertEqual(msg['subject'], expected_msg['subject'])
self.assertEqual(msg['plain'], expected_msg['plain'])
self.assertEqual(msg['html'], expected_msg['html'])
52. Tips
BIEN
def test_gmail(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
checks = {'subject': u'SeamlessWeb Order'}
msg = strip_forwarding(msg)
# Validar que los valores sean los esperados
for key, val in checks.items():
self.assertEqual(val, msg[key])
# Asegurar que estos valores no se encuentren en el email
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m)
54. Tips
MAL
def test_emails(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
checks = {'subject': u'SeamlessWeb Order'}
gmail, aol, hotmail = message.objects.all()[:2]
msgs = (strip_forwarding(gmail),
strip_forwarding(aol), strip_forwarding(hotmail))
for msg in msgs:
for key, val in checks.items():
self.assertEqual(val, msg[key])
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m)
55. Tips
BIEN
def test_gmail(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
checks = {'subject': u'SeamlessWeb Order'}
gmail = message.objects.get(id=1)
msgs = strip_forwarding(gmail)
for key, val in checks.items():
self.assertEqual(val, msg[key])
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m)
def test_aol(self):
strips = ('---------- Forwarded message ----------',...
56. Tips
BIEN
def test_gmail(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
checks = {'subject': u'SeamlessWeb Order'}
gmail = message.objects.get(id=1)
msgs = strip_forwarding(gmail)
for key, val in checks.items():
self.assertEqual(val, msg[key])
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m)
def test_aol(self):
strips = ('---------- Forwarded message ----------',...
57. Tips
Pruebas por Aserción
def test_gmail_checks(self):
checks = {'subject': u'SeamlessWeb Order'}
gmail = message.objects.get(id=1)
msgs = strip_forwarding(gmail)
for key, val in checks.items():
self.assertEqual(val, msg[key]) <---- Asercion
def test_gmail_strips(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
gmail = message.objects.get(id=1)
msgs = strip_forwarding(gmail)
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m) <---- Asercion
58. Tips
Pruebas por Acción
def test_gmail(self):
strips = ('---------- Forwarded message ----------',
'Fwd: ', 'From: ', 'Date: ', 'Subject: ', 'To: ')
checks = {'subject': u'SeamlessWeb Order'}
gmail = message.objects.get(id=1)
msgs = strip_forwarding(gmail) <---- ACCION
for key, val in checks.items():
self.assertEqual(val, msg[key])
for strip in strips:
for m in msg.values():
self.assertNotIn(strip, m)
59. Tips
Probar todas las ramas
def handle_coolness(self, user):
if user.is_cool:
do_cool_stuff(user)
else:
raise NotCoolDudeException
65. Continuous Deployment
Integrado por django_jenkins
Correr Pruebas unitarias
Verificacion de codigo (Pep8, jslint, etc)
Reportes
Emails
66. Continuous Deployment
if len(sys.argv) > 1 and sys.argv[1] in ['test', 'jenkins']:
# test mongo db
MONGO_DBNAME = 'db_test'
db = mongoengine.connect(MONGO_DBNAME,
username=MONGO_USERNAME,
password=MONGO_PASSWORD,
host=MONGO_HOST,
port=MONGO_PORT, safe=True)
db.drop_database(MONGO_DBNAME) # drop entire database