Diferencia entre revisiones de «Usuario:Luis.perez/sistemaspyaytozgz/testing»
De WikiEducator
(Página creada con '{{Conocimiento previo| Tests con python: * http://en.wikipedia.org/wiki/Portal:Software_Testing * http://docs.python.org/2/library/unittest.html * https://nose.readthedocs.org/e…') |
|||
(2 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 5: | Línea 5: | ||
* https://nose.readthedocs.org/en/latest/index.html | * https://nose.readthedocs.org/en/latest/index.html | ||
* http://ivory.idyll.org/articles/nose-intro.html | * http://ivory.idyll.org/articles/nose-intro.html | ||
− | }} | + | }} |
+ | |||
+ | == Instalar nose == | ||
+ | |||
+ | Puedes usar pip o easy_install: | ||
− | |||
− | |||
easy_install nose | easy_install nose | ||
− | o | + | |
+ | o | ||
+ | |||
pip install nose | pip install nose | ||
− | O instalar desde el código fuente: | + | O instalar desde el código fuente: |
+ | |||
python setup.py install | python setup.py install | ||
+ | <br> | ||
− | = Doctests = | + | = Doctests = |
− | * Documentación de código que además sirve como tests | + | *Documentación de código que además sirve como tests |
− | * Buena forma de obligar a mantener los docstrings actualizados | + | *Buena forma de obligar a mantener los docstrings actualizados |
− | * Tests junto al código, facilitan su mantenimiento | + | *Tests junto al código, facilitan su mantenimiento |
<source lang="python"> | <source lang="python"> | ||
Línea 32: | Línea 38: | ||
7 | 7 | ||
""" | """ | ||
− | </source> | + | </source> |
+ | |||
+ | Ejecutamos los doctests de dos formas: | ||
+ | |||
+ | *Con el módulo doctest: | ||
− | |||
− | |||
<source lang="python"> | <source lang="python"> | ||
Línea 43: | Línea 51: | ||
import doctest | import doctest | ||
doctest.add() | doctest.add() | ||
− | </source> | + | </source> |
+ | |||
+ | *Con nose: | ||
− | |||
<source lang="bash"> | <source lang="bash"> | ||
$ nosetests --with-doctest | $ nosetests --with-doctest | ||
− | </source> | + | </source> |
+ | <br> | ||
− | = Unittest = | + | = Unittest = |
− | http://docs.python.org/2/library/unittest.html | + | http://docs.python.org/2/library/unittest.html |
− | * Parte de la librería estandar | + | *Parte de la librería estandar |
− | * NUnit | + | *NUnit |
− | === Caracteristicas === | + | === Caracteristicas === |
− | * Test cases: Clases que encapsulan un conjunto de tests. Extienden de unittest.TestCase | + | *Test cases: Clases que encapsulan un conjunto de tests. Extienden de unittest.TestCase |
− | * fixtures: métodos para preparar o destruir objetos que puedan necesitar todos los tests | + | *fixtures: métodos para preparar o destruir objetos que puedan necesitar todos los tests |
− | + | <br> Ejemplo | |
− | Ejemplo | + | |
<source lang="python"> | <source lang="python"> | ||
Línea 92: | Línea 101: | ||
self.assertTrue(element in self.seq) | self.assertTrue(element in self.seq) | ||
− | </source> | + | </source> |
− | === Ejecutando los tests === | + | === Ejecutando los tests === |
− | Se puede hacer añadiendo al código: | + | Se puede hacer añadiendo al código: <source lang="python"> |
− | <source lang="python"> | + | |
#... | #... | ||
if __name__ == '__main__': | if __name__ == '__main__': | ||
unittest.main() | unittest.main() | ||
− | </source> | + | </source> |
− | + | <br> O bien por línea de comando: | |
− | O bien por línea de comando: | + | |
<source lang="bash"> | <source lang="bash"> | ||
Línea 113: | Línea 120: | ||
python -m unittest seqtests.TestSequenceFunctions.test_shuffle | python -m unittest seqtests.TestSequenceFunctions.test_shuffle | ||
− | </source> | + | </source> |
$ python -m unittest seqtests.TestSequenceFunctions | $ python -m unittest seqtests.TestSequenceFunctions | ||
− | + | ... | |
− | + | ---------------------------------------------------------------------- | |
− | + | Ran 3 tests in 0.000s | |
− | + | OK | |
− | Se puede usar el autodiscover: | + | Se puede usar el autodiscover: |
<source lang="bash"> | <source lang="bash"> | ||
$ python -m unittest discover | $ python -m unittest discover | ||
− | </source> | + | </source> |
− | Busca módulos de test que se llamen test*.py (se puede modificar este comportamiento) | + | Busca módulos de test que se llamen test*.py (se puede modificar este comportamiento) |
+ | |||
+ | === Fixtures === | ||
+ | |||
+ | *setUp: Se invoca antes de la ejecución de cada test | ||
+ | *tearDown: Se invoca después de la ejecución de cada test | ||
+ | *setUpClass: Se invoca una única vez antes de la ejecución de los tests del TestCase | ||
− | |||
− | |||
− | |||
− | |||
<source lang="python"> | <source lang="python"> | ||
@classmethod | @classmethod | ||
def setUpClass(cls): | def setUpClass(cls): | ||
... | ... | ||
− | </source> | + | </source> |
− | * tearDownClass: Se invoca una única vez después de la ejecución de los tests del TestCase | + | |
+ | *tearDownClass: Se invoca una única vez después de la ejecución de los tests del TestCase | ||
+ | |||
<source lang="python"> | <source lang="python"> | ||
@classmethod | @classmethod | ||
def tearDownClass(cls): | def tearDownClass(cls): | ||
... | ... | ||
− | </source> | + | </source> |
− | + | ||
+ | === Asserts === | ||
+ | {| width="300" border="1" cellpadding="1" cellspacing="1" class="prettytable" | ||
+ | |- | ||
+ | | assertEqual(a, b) | ||
+ | | a == b | ||
+ | |- | ||
+ | | assertNotEqual(a, b) | ||
+ | | a != b | ||
+ | |- | ||
+ | | assertTrue(x) | ||
+ | | bool(x) is True | ||
+ | |- | ||
+ | | assertFalse(x) | ||
+ | | bool(x) is False | ||
+ | |- | ||
+ | | assertIs(a, b) | ||
+ | | a is b | ||
+ | |- | ||
+ | | assertIsNot(a, b) | ||
+ | | a is not b | ||
+ | |- | ||
+ | | assertIsNone(x) | ||
+ | | x is None | ||
+ | |- | ||
+ | | assertIsNotNone(x) | ||
+ | | x is not None | ||
+ | |- | ||
+ | | assertIn(a, b) | ||
+ | | a in b | ||
+ | |- | ||
+ | | assertNotIn(a, b) | ||
+ | | a not in b | ||
+ | |- | ||
+ | | assertIsInstance(a, b) | ||
+ | | isinstance(a, b) | ||
+ | |- | ||
+ | | assertNotIsInstance(a, b) | ||
+ | | not isinstance(a, b) | ||
+ | |} | ||
− | + | * assertRaises | |
− | + | <source lang="python"> | |
− | + | with self.assertRaises(SomeException) as cm: | |
− | + | do_something() | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | = | + | the_exception = cm.exception |
− | + | self.assertEqual(the_exception.error_code, 3) | |
+ | </source> | ||
+ | == Nose == | ||
+ | |||
+ | https://nose.readthedocs.org/en/latest/ | ||
+ | * Librería no estandar, pero muy usada en el mundo python | ||
+ | * No hace falta que los tests extiendan de unittest.TestCase, pueden ser funciones | ||
+ | * Soporta agrupaciones a nivel de paquete, módulo y clase, con sus correspondientes fixtures. | ||
+ | |||
+ | Ejemplo | ||
<source lang="python"> | <source lang="python"> | ||
− | def | + | |
− | + | #roomtests.py | |
+ | |||
+ | from nose.tools import * | ||
+ | from room import Room | ||
+ | |||
+ | |||
+ | def test_room(): | ||
+ | gold = Room("GoldRoom", | ||
+ | """This room has gold in it you can grab. There's a | ||
+ | door to the north.""") | ||
+ | assert_equal(gold.name, "GoldRoom") | ||
+ | assert_equal(gold.paths, {}) | ||
</source> | </source> | ||
− | |||
− | + | === Ejecutando los tests === | |
+ | |||
+ | <source lang="bash"> | ||
+ | $ nosetests | ||
+ | $ nosetests roomtests.py | ||
+ | $ nosetests roomtests | ||
+ | $ nosetests roomtests:test_room | ||
+ | |||
+ | </source> | ||
+ | |||
+ | |||
+ | === Asserts === | ||
+ | |||
+ | * Soporta todos los asserts de unittest (recomiendan usar la forma assert_equals en lugar de assertEquals) | ||
+ | * mas algunas funciones como: | ||
+ | ** nose.tools.ok_(expr, msg=None): asserTrue | ||
+ | ** nose.tools.eq_(a, b, msg=None): assertEquals | ||
+ | ** nose.tools.raises(*exceptions): | ||
+ | <source lang="python"> | ||
+ | @raises(TypeError, ValueError) | ||
+ | def test_raises_type_error(): | ||
+ | raise TypeError("This test passes") | ||
+ | </source> | ||
+ | ** nose.tools.timed(limit): Tiempo máximo que tiene un test para pasar | ||
+ | |||
+ | <source lang="python"> | ||
+ | @timed(.1) | ||
+ | def test_that_fails(): | ||
+ | time.sleep(.2) | ||
+ | </source> |
Última revisión de 01:07 21 ene 2013
Tests con python:
|
Instalar nose
Puedes usar pip o easy_install:
easy_install nose
o
pip install nose
O instalar desde el código fuente:
python setup.py install
Doctests
- Documentación de código que además sirve como tests
- Buena forma de obligar a mantener los docstrings actualizados
- Tests junto al código, facilitan su mantenimiento
def add(a, b): """ Suma dos números >>> add(5, 2) 7 """
Ejecutamos los doctests de dos formas:
- Con el módulo doctest:
# ... if __name__ == "__main__": import doctest doctest.add()
- Con nose:
$ nosetests --with-doctest
Unittest
http://docs.python.org/2/library/unittest.html
- Parte de la librería estandar
- NUnit
Caracteristicas
- Test cases: Clases que encapsulan un conjunto de tests. Extienden de unittest.TestCase
- fixtures: métodos para preparar o destruir objetos que puedan necesitar todos los tests
Ejemplo
# randomtests.py import random import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.seq = range(10) def test_shuffle(self): # make sure the shuffled sequence does not lose any elements random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) def test_choice(self): element = random.choice(self.seq) self.assertTrue(element in self.seq) def test_sample(self): with self.assertRaises(ValueError): random.sample(self.seq, 20) for element in random.sample(self.seq, 5): self.assertTrue(element in self.seq)
Ejecutando los tests
Se puede hacer añadiendo al código:#... if __name__ == '__main__': unittest.main()
O bien por línea de comando:
#... python -m unittest seqtests python -m unittest seqtests.TestSequenceFunctions python -m unittest seqtests.TestSequenceFunctions.test_shuffle
$ python -m unittest seqtests.TestSequenceFunctions ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Se puede usar el autodiscover:
$ python -m unittest discover
Busca módulos de test que se llamen test*.py (se puede modificar este comportamiento)
Fixtures
- setUp: Se invoca antes de la ejecución de cada test
- tearDown: Se invoca después de la ejecución de cada test
- setUpClass: Se invoca una única vez antes de la ejecución de los tests del TestCase
@classmethod def setUpClass(cls): ...
- tearDownClass: Se invoca una única vez después de la ejecución de los tests del TestCase
@classmethod def tearDownClass(cls): ...
Asserts
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
- assertRaises
with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)
Nose
https://nose.readthedocs.org/en/latest/
- Librería no estandar, pero muy usada en el mundo python
- No hace falta que los tests extiendan de unittest.TestCase, pueden ser funciones
- Soporta agrupaciones a nivel de paquete, módulo y clase, con sus correspondientes fixtures.
Ejemplo
#roomtests.py from nose.tools import * from room import Room def test_room(): gold = Room("GoldRoom", """This room has gold in it you can grab. There's a door to the north.""") assert_equal(gold.name, "GoldRoom") assert_equal(gold.paths, {})
Ejecutando los tests
$ nosetests $ nosetests roomtests.py $ nosetests roomtests $ nosetests roomtests:test_room
Asserts
- Soporta todos los asserts de unittest (recomiendan usar la forma assert_equals en lugar de assertEquals)
- mas algunas funciones como:
- nose.tools.ok_(expr, msg=None): asserTrue
- nose.tools.eq_(a, b, msg=None): assertEquals
- nose.tools.raises(*exceptions):
@raises(TypeError, ValueError) def test_raises_type_error(): raise TypeError("This test passes")
- nose.tools.timed(limit): Tiempo máximo que tiene un test para pasar
@timed(.1) def test_that_fails(): time.sleep(.2)