Тестирование
- Место тестирования в жизненном цикле программного продукта
- Собирается — значит, работает!
- + Проверяется анализатором кода, и потыкано end-user тестерами согласно тест-плану
- + Автоматическая проверка работоспособности там, где это возможно
- + Измерение тестового покрытия (coverage)
- Ручное, автоматизированное, автоматическое
- unit — спецификация компонентов (функций/классов и т. п.)
integration — спецификация интерфейсов между компонентами
- system — спецификация конечного продукта
- acceptacne — потребительские/рыночные/эксплутационные/… свойства продукта
- Дисциплина:
- Сначала весь код, потом некоторые тесты (когда это можно?)
- Каждая новая фича сопровождается тестом
Разработка_через_тестирование (TDD)
- сначала пишется тест и заглушка
сам код падает (иначе бесполезен)
- под тест пишется код
- код не падает
код изменяется и всё равно не падает
- green test trap: Тестирование может доказать наличие дефектов, но не их отсутствие
- red test trap: Не всякие проваленные тесты означают дефекты. Могут означать пробел в требованиях, в том числе нефункциональных
- Полезные ≠ друг другу термины:
ошибка программиста при написании программы может привести к
дефекту (багу) в программе, который в свою очередь может
проявиться (или не проявиться) в виде программного сбоя
- Стоимость исправления дефекта возрастает пропорционально его «возрасту»
- Непрерывная интеграция
Модульное тестирование в Python
doctest: тест = диалог с python-интерпретатором
- Модуль
- Тестируем вручную:
- Добавляем тесты в docstring:
def moo(oos=2, end=""): '''Издать мычание длиной oos с end в конце Оба параметра необязательны: >>> moo() 'Moo' Первый задаёт количество букв 'o' в слове 'Moo' >>> moo(4) 'Mooooo' Букв 'o' может и не быть >>> moo(0) 'M' Второй задаёт символ после всех 'o' (по умолчанию — ничего) >>> moo(end='!') 'Moo!' >>> moo(0,'?') 'M?' ''' return "M"+"o"*oos+end
- Тестирование:
george@inspiron:~/src/moo> python3 -m doctest Moo.py ********************************************************************** File "/home/george/src/moo/Moo.py", line 13, in Moo.moo Failed example: moo(4) Expected: 'Mooooo' Got: 'Moooo' ********************************************************************** 1 items had failures: 1 of 5 in Moo.moo ***Test Failed*** 1 failures.
- Отчёт (с успешными тестами):
george@inspiron:~/src/moo> python3 -m doctest -v Moo.py Trying: moo() Expecting: 'Moo' ok Trying: moo(4) Expecting: 'Mooooo' ********************************************************************** File "/home/george/src/moo/Moo.py", line 13, in Moo.moo Failed example: moo(4) Expected: 'Mooooo' Got: 'Moooo' Trying: moo(0) Expecting: 'M' ok Trying: moo(end='!') Expecting: 'Moo!' ok Trying: moo(0,'?') Expecting: 'M?' ok 1 items had no tests: Moo ********************************************************************** 1 items had failures: 1 of 5 in Moo.moo 5 tests in 2 items. 4 passed and 1 failed. ***Test Failed*** 1 failures.
TODO
- unittest
- py.test , nose
- Показатель покрытия кода тестами (coverage)
TODO pytest/cov
Д/З
- Осознать, что нуждается в unit-тестировании
- Оснастить код семестрового проекта unit-тестами (любой фреймворк)
- Зафиксировать в документации, как их запускать
- Подумать над тестированием UI
например, с помощью порождения событий tkinter