Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

Нескучное тестирование с pytest

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité

Consultez-les par la suite

1 sur 34 Publicité

Нескучное тестирование с pytest

Télécharger pour lire hors ligne

Написание юнит-тестов большинству представляется занятием скучным и до некоторой степени бесполезным. Мое мнение — это всё оттого, что сама "классическая" схема юнит-тестов подразумевает непродуктивное написание унылого линейного кода.

В докладе я расскажу о том, как с помощью pytest начать писать тесты, которые приятно читать и поддерживать, почему setUp и tearDown — это прошлый век, как с помощью правильной организации fixtures ускорить исполнение тестов, а также какие ещё уловки могут помочь вам в вашей нелегкой борьбе с рутиной.

Написание юнит-тестов большинству представляется занятием скучным и до некоторой степени бесполезным. Мое мнение — это всё оттого, что сама "классическая" схема юнит-тестов подразумевает непродуктивное написание унылого линейного кода.

В докладе я расскажу о том, как с помощью pytest начать писать тесты, которые приятно читать и поддерживать, почему setUp и tearDown — это прошлый век, как с помощью правильной организации fixtures ускорить исполнение тестов, а также какие ещё уловки могут помочь вам в вашей нелегкой борьбе с рутиной.

Publicité
Publicité

Plus De Contenu Connexe

Diaporamas pour vous (20)

Similaire à Нескучное тестирование с pytest (20)

Publicité

Plus récents (15)

Нескучное тестирование с pytest

  1. 1. Нескучное тестирование с pytest Роман Иманкулов / @rdotpy / 27 июня 2014
  2. 2. Почему программисты не любят писать тесты?
  3. 3. Тестирование в Python — это религия • Врождённая греховность • Очищение через страдание • Мистический опыт
  4. 4. Врождённая греховность  Врожденные пороки — нестрогая типизация и duck typing • Как следствие — природная склонность программиста на Python к совершению маленьких и глупых ошибок
  5. 5. Очищение через страдание Boilerplate Code     class TestSequenceFunctions(unittest.TestCase):         def setUp(self):             ...         def tearDown(self):             ...         def testFoo(self):             ...
  6. 6. Очищение через страдание Многословные ассерты          self.assertEqual(foo, 1,                       'foo is not equal to one')
  7. 7. Мистический опыт Django testing setups & teardowns
  8. 8. Есть ли альтернатива?
  9. 9. pytest
  10. 10. pytest — это не еще один xUnit фреймворк!
  11. 11. pytest fixtures То, что отличает pytest от других фреймворков
  12. 12. pytest fixtures Наивный подход. Как это бы сделал я сам file: fixtures.py     def get_user():         return User(name='Roman', age=30, ...)         file: test_user.py     def test_user():         user = get_user()         assert user.name == 'Roman'
  13. 13. pytest fixtures Подход pytest file: conftest.py     @pytest.fixture     def user():         return User(name='Roman', age=30, ...)         file: test_user.py     def test_user(user):         assert user.name == 'Roman'
  14. 14. Зависимости между fixtures
  15. 15. @pytest.fixture def user():     return User(name='Roman', age=30, ...)        @pytest.fixture def task(user):     return Task(user=user, name='...') def test_task(task):     assert task.user.name == 'Roman'
  16. 16. Fixture dependencies. Patching object @pytest.fixture def premium(user)     user.set_premium() def test_premium(user, premium):     assert user.is_premum()
  17. 17. yield_fixture setup и teardown в одном флаконе
  18. 18. @pytest.yield_fixture def user():     obj = User(name='Roman', age=30, ...)            yield obj     obj.delete()
  19. 19. Fixture scopes • function scope • module scope • session scope
  20. 20. Session fixture. Локальный кеш @pytest.yield_fixture(scope='session', autouse=True) def local_cache():     old_settings = settings.CACHES     settings.CACHES = {'default': {…}}     yield     settings.CACHES = old_settings
  21. 21. Function fixture. Database transaction rollback @pytest.yield_fixture def tx():     db().start_transaction()     yield     db().rollback() def test_user(user, tx, project, task):     # project & task will be removed automatically
  22. 22. Session fixture. Чистый redis @pytest.yield_fixture(scope='session') def redis_server():     proc = subp.Popen(['redis­server', '­­port', 7777], ... )     yield proc     proc.terminate() @pytest.fixture def rc(redis_server):     client = redis.StrictRedis('redis://127.0.0.1:7777')     client.flushall()     return client
  23. 23. fixtures parametrization
  24. 24. Функция возвращает функцию @pytest.fixture def set_lang(user):     def func(lang_code):             user.set_lang(lang_code)     return func def test_languages(user, set_lang):     set_lang('ru')     ...
  25. 25. Странные вещи
  26. 26. Fixtures в отдельном потоке http://bit.ly/test_pool @pytest.fixture(scope='session') def item_gen():     gen = Generator(lambda: .)     gen.start()     return gen @pytest.yield_fixture def item(item_gen, item_rel):     item = item_gen.get()     yield item     item_rel.put(item) @pytest.fixture(scope='session') def item_rel():     rel = Releaser(lambda o: ...)     rel.start()     return rel
  27. 27. Как ещё использовать fixtures • warnings: turn MySQL warnings to errors • mock: подготовка mockup объектов • freezegun: управление временем • selenium: запуск веб-драйвера
  28. 28. О чём я ещё не рассказал def pytest_addoption(parser):     parser.addoption("­­clean­mysql",   action="store_true", default=False) @pytest.fixture(scope='session', autouse=True) def clean_mysql(request):     if not request.config.getoption('­­clean­mysql'):            return      # clean MySQL tables heres
  29. 29. О чём я ещё не рассказал @pytest.mark.parametrize("input,expected", [     ("3+5", 8),     ("2+4", 6), ]) def test_eval(input, expected):     assert eval(input) == expected
  30. 30. О чём я ещё не рассказал • pytest-django: интеграция с Django • pytest-xdist: параллельные и распределенные тесты
  31. 31. О чём я ещё не рассказал • tox: выполнение тестов для разных python • detox: то же самое, только параллельно [tox] envlist = py26,py27 [testenv] deps=pytest   commands=py.test
  32. 32. Спасибо! Вопросы? Роман Иманкулов / @rdotpy / http://imankulov.name

×