Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing of Django applications with pytest

Testing of Django applications with pytest

Slides of talk by Simone Dalla on testing of Django applications with pytest at Pycon6, DjangoVillage, Florence, Italy, April 2015.

Simone Dalla

April 17, 2015
Tweet

More Decks by Simone Dalla

Other Decks in Programming

Transcript

  1. CTO @ SIA Unione dei Comuni Valli del Reno Lavino

    e Samoggia (Bologna, IT), Pythonista and Django programmer, I use Python into my work environment for.....ALL! about me Simone Dalla twitter @simodalla slides http://speakerdeck.com/simodalla
  2. plugin driven - pytest-django, Django integration - pytest-cov, coverage reporting

    - pytest-xdist, distributed/parallelized tests - … and more at: http://pytest.org/latest/plugins.html#external-plugins
  3. discovery - just run doctest and unittest - run any

    function prefixed with test_ as a test - run tests written for nose address/ __init__.py envelope.py geo.py test_envelope.py # checked for tests test_geo.py # checked for tests records/ # pytest WON'T look here because it lacks __init__.py records.csv records.py test_records.py # skipped because records/ lacks __init__.py __init__.py main.py test_main.py # checked for tests
  4. testing exception with context manager raises import pytest def test_an_exception():

    with pytest.raises(IndexError) as excinfo: [1,2,3][100] assert 'out of range' in str(excinfo.value)
  5. marking test functions with attributes, markers import pytest @pytest.mark.xfail def

    test_yes_this_fail(): ... @pytest.mark.skipif(sys.version_info<(3.3), reason='requires py3.3') def test_new_py33_feature(): ...
  6. change behaviour # pytest.ini (or tox.ini or setup.cfg) [pytest] #

    You must put pytest-related # controls in a 'pytest' block python_files=*.py # Run tests against all # python modules norecursedirs = _build # Don't look inside of # _build directories # conftest.py collect_ignore = ["setup.py", "conftest.py"]
  7. pytest fixtures - Replacement for unittest setUp/tearDown - Django fixture

    != pytest fixture [{"pk": 1, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐09T09:10:00Z", "is_scheduled": true, "stop": "2011-­‐08-­‐09T09:40:00Z", "logged_time": 31946}}, {"pk": 2, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐10T09:00:00Z", "is_scheduled": true, "stop": "2011-­‐08-­‐10T09:30:00Z", "logged_time": 32038}}, {"pk": 3, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐10T09:10:00Z", "is_scheduled": true, "stop": "2011-­‐08-­‐10T09:40:00Z", "logged_time": 32039}}, {"pk": 4, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐11T09:10:00Z", "is_scheduled": true, "stop": "2011-­‐08-­‐11T09:40:00Z", "logged_time": 32104}}, {"pk": 5, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐11T09:00:00Z", "is_scheduled": true, "stop": "2011-­‐08-­‐11T09:30:00Z", "logged_time": 32105}}, {"pk": 6, "model": "tracker.loggedtimebreak", "fields": {"start": "2011-­‐08-­‐12T09:00:00Z", ……………...
  8. Run all the tests $ py.test Run all the tests

    in a specific file $ py.test test_views.py Run all the tests in a specific directory $ py.test tests/ Run all the tests cases that are named *test_foo* $ py.test -k test_foo
  9. run tests in parallel Run tests in four parallel processes

    $ py.test -n 4 pip install pytest-xdist Install xdist plugin that provide distributed testing
  10. ...no-boilerplate testing def test_hello_world(client): response = client.get(‘/home/’) assert response.status_code ==

    200 assert ‘Hello’ in response.content.decode(‘utf-8’) from django.test import TestCase class TestHelloWorld(TestCase): def test_hello_world(self): response = self.client.get(‘/home/’) self.assertEqual(response.status_code, 200) self.assertIn(‘Hello’, response.content.decode(‘utf-8’))
  11. test database reuse Reuse database from last run $ py.test

    --reuse-db Put this in pytest.ini to always reuse the database [pytest] addopts = --reuse-db Recreate database schema if models is changed $ py.test --reuse-db --create-db
  12. pytest-django and database import pytest from polls.models import Question @pytest.mark.django_db

    def test_how_many_questions(): assert Question.object.count() == 0 This will allow database access
  13. import pytest from polls.models import Question def test_how_many_questions(): assert Question.object.count()

    == 0 _________test_how_many_questions__________ def test_how_many_questions(): > Question.objects.count() == 0 … E Failed: Database access not allowed, use the "django_db" mark to enable FAIL!
  14. pytest fixture # conftest.py import pytest from django.utils import timezone

    from polls.models import Question @pytest.fixture def question_in_db(db): return Question.objects.create( question_text="What's new?", pub_date=timezone.now()) # test_models.py from polls.models import Question def test_db_has_one_question(question_in_db): assert Question.objects.count() == 1 assert question_in_db.question_text == "What's new?" pytest fixture != django fixture
  15. django-pytest helpers • rf = instance of django.test.RequestFactory • client

    = instance of django.test.Client • admin_client = instance of a superuser, with username “admin” and password “password” • django_user_model = user model used by Django • django_username_field = field name used for the username on the user model • db = ensure the Django database is set up • transactional_db = database including transaction support • live_server = runs a live Django server in a background thread • settings = provide a handle on the django settings module • pytest.mark.django_db = mark a test function as requiring the database • pytest.mark.urls = override the urlconf, specifing a different settings. ROOT_URLCONF module for the marked tests FIXTURES MARKERS
  16. More pytest fixtures feauters • writing test for fixtures •

    parametrization • scoping (reuse expensive setup) • auto use fixtures (=~ setUp of unittest) • executing “finalization/teardown” code • modularity, using fixture from a fixture • introspect requesting test context
  17. More info? Help? Docs? • Carl Meyer, Testing and Django

    - Pycon 2012: https://www.youtube.com/watch?v=ickNQcNXiS4 • Holger Krekel, Improving automated testing with py.test - PyCon 2014 https://www.youtube.com/watch?v=AiThU6JQbE8 • Andreas Pelme, Pytest: help you write better Django apps, DjangoCon Europe 2014 https://www.youtube.com/watch?v=aaArYVh6XSM • official Django testing documentation https://docs.djangoproject.com/en/1.8/topics/testing/ • pytest documentation http://pytest.org/ • pytest-django documentation https://pytest-django.readthedocs.org
  18. Thank you!!! .... questions? email [email protected] twitter @simodalla github simodalla

    linkedIn http://it.linkedin.com/in/simodalla slides http://speakerdeck.com/simodalla