Скорость имеет значение.Старайтесь писать тесты, которые работают быстро. Если для того, чтобы тест отработал, нужно несколько миллисекунд, разработка будет замедлена или тесты будут запускаться не так часто, как вам бы этого хотелось. В некоторых случаях тесты не могут быть быстрыми, поскольку для их работы требуется сложная структура данных, которая должна подгружаться каждый раз, когда запускается тест. Держите подобные тесты в отдельном наборе, который запускается какой-нибудь задачей по графику, а остальные тесты запускайте так часто, как вам это нужно.
RTMF (Read the manual, friend! — «Читай руководство, друг!»).Изучайте свои инструменты, чтобы знать, как запустить отдельный тест или набор тестов. При разработке функции внутри модуля почаще запускайте тесты для нее, в идеале всякий раз, когда вы сохраняете код.
Тестируйте все в начале работы и затем опять тестируйте по ее завершении.Всегда запускайте полный набор тестов перед тем, как писать код, и по завершении работы. Это позволит убедиться, что вы ничего «не сломали» в остальной части кода.
Автоматические функции перехвата для системы управления версиями фантастически хороши.Реализовать функцию перехвата, которая запускает все тесты перед тем, как отправить код в общий репозиторий, — хорошая идея. Вы можете непосредственно добавлять функции перехвата в вашу систему контроля версий, некоторые IDE предоставляют способы сделать это с помощью их собственных сред. Далее приведены ссылки на документацию к популярным системам контроля версий, в которой содержится информация о том, как это реализовать:
• GitHub ( https://developer.github.com/webhooks/);
• Mercurial ( http://bit.ly/mercurial-handling-repo);
• Subversion ( http://bit.ly/svn-repo-hook).
Напишите тест, если хотите сделать перерыв.Если вы остановились на середине сессии разработки и вам нужно прервать работу, можете написать неработающий тест, который связан с тем, что вы планируете реализовать. По возвращении к работе у вас будет указатель на то место, где вы остановились (вы сможете приступить быстрее).
В случае неопределенности выполните отладку для теста.Первый шаг отладки кода — написание еще одного теста, который указывает на ошибку. Несмотря на то что это не всегда можно сделать, тесты, отлавливающие ошибки, являются наиболее ценными фрагментами кода вашего проекта.
Если тест сложно объяснить, то желаем вам удачи в поиске коллег.Если что-то идет не так или что-то нужно изменить и для вашего кода написано множество тестов, вы или другие сотрудники, работающие над проектом, будете полагаться на набор тестов для решения проблемы или изменения поведения. Поэтому код теста должен быть читаемым на том же уровне (или даже больше ), чем рабочий код. Юнит-тест, чье предназначение неясно, не принесет большой пользы.
Если тест просто объяснить, он почти всегда хорош.Код теста можно использовать в качестве руководства для новых разработчиков. Если другим людям нужно работать с базой кода, запуск и чтение соответствующих тестов — это лучшее, что они могут сделать. Они обнаружат (по крайней мере должны обнаружить) проблемные места, вызывающие больше всего трудностей, а также пограничные случаи. Если им нужно добавить какую-то функциональность, в первую очередь следует добавить тест (это гарантирует ее появление).
Не паникуйте!Это же ПО с открытым исходным кодом! Вас поддержит весь мир.
В этом разделе приводятся основы тестирования, чтобы у вас было представление о доступных вариантах, и примеры из проектов Python, которые мы рассмотрим в главе 5. Есть целая книга, посвященная TDD в Python, мы не хотим переписывать ее здесь. Она называется Test-Driven Development with Python (издательство O’Reilly).
unittest
unittest — это тестовый модуль стандартной библиотеки Python, готовый к работе сразу после установки. Его API будет знаком всем, кто пользовался любым из этих инструментов — JUnit (Java)/nUnit (.NET)/CppUnit (C/C++).
Создать тест в этом модуле можно путем создания подкласса для unittest.TestCase. В этом примере функция тестирования определяется как новый метод в MyTest:
# test_example.py
import unittest
def fun(x):
····return x + 1
class MyTest(unittest.TestCase):
····def test_that_fun_adds_one(self):
········self.assertEqual(fun(3), 4)
class MySecondTest(unittest.TestCase):
····def test_that_fun_fails_when_not_adding_number(self):
········self.assertRaises(TypeError, fun, "multiply six by nine")
Читать дальше