19. Тестирование программ.
Почему нужно писать тесты
- Python - динамически типизированный язык программирования, нет привычной по другим языкам статической проверки типов.
- Удобно авматоматизировать ручные проверки старых и новых функций и их взаимодействия.
- При внесении изменений в код хотелось бы иметь простой способ быстро убедиться, что ничего не сломал.
- При работе в команде это способ отслеживания состояния и работоспособности проекта.
- Тесты - некоторого рода документация, описывающая как взаимодействовать с кодом.
Юнит-тестирование
- Существует ряд различных типов тестирования, которые применяются так или иначе для проверки отдельных аспектов работы программы.
- Нас интересует один из часто используемых - юнит-тестирование.
- Юнит-тестирование (unit testing) предполагает написание тестов для небольших частей кода (функций или классов).
- В таких тестах проверяется выполнение ожидаемых инвариантов работы с помощью различных вариантов функции assert.
- Проверяем: что вернулось ожидаемое значение, что два значения равны, что было выброшено (или не выброшено) исключение, что вызов завершился до истечения таймаута и т.п.
Python unittest
- В результате развития подходом и библиотек для языка Java в какой-то момент появилась успешная библиотека JUnit.
- unittest - реализации идей этой библиотеки для языка Python.
Основные концепции выполнения тестов:
- создание начальных условий для отдельного теста
- задание завершающих действий для отдельного теста
- объединение тестов в группы
- автоматизированный запуск наборов тестов
- независимое отображение результатов выполнения тестов
Для реализации этих концепций используются понятия:
- Отдельный тест (test case, класс TestCase) - описывает действия подготовки и завершения (setUp и tearDown), а также сам тест.
- Набор тестов (test suite, TestSuite) - объединяет в себе несколько тестов.
- Тестовые установки (test fixture, TestFixture) - представляют действия для подготовки и завершения одного или нескольких тестов (создание временных таблиц, директорий и т.п.)
- Исполнитель тестов (test runner, TestRunner) - компонент, отвечающий за запуск тестов и отображения их результатов (текстовы, графический интерфейсы).
Пример отдельного теста:
import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('Foo'.isupper()) def test_split(self): s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # check that s.split fails when the separator is not a string with self.assertRaises(TypeError): s.split(2)
suite = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods) unittest.TextTestRunner(verbosity=2).run(suite) test_isupper (__main__.TestStringMethods) ... ok test_split (__main__.TestStringMethods) ... ok test_upper (__main__.TestStringMethods) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.004s OK
<unittest.runner.TextTestResult run=3 errors=0 failures=0>