Страницы

Поиск по вопросам

четверг, 25 октября 2018 г.

Как заменить префикс 'test_' на 'should_' в модульных тестах с примением unittest?

При использовании библиотеки unittest, которая входит в стандартную python библиотеку программист свои тестовые методы вынужден сопровождать test_. Мне хочется уточнить, это обязательное требование или же все-таки есть способ заменить его другим, к примеру should_?


Ответ

Во всех примерах кода ниже буду считать, что доступен класс с тестами:
class MyTests(unittest.TestCase): def test_simple(self): self.assertTrue(True)
def test_complicated(self): self.assertTrue(False)
def should_pass(self): self.assertTrue(True)
def should_fail(self): self.assertTrue(False)
Использование поля testMethodPrefix в TestLoader
Нашёл способ с использованием ручного запуска через TestLoader
import unittest
def run_tests(): loader = unittest.TestLoader() loader.testMethodPrefix = 'should' # задаём требуемый префикс тестов suite = loader.loadTestsFromTestCase(MyTests) unittest.TextTestRunner().run(suite)
if __name__ == '__main__': run_tests()
TestLoader имеет поле testMethodPrefix, в которое можно записать требуемый префикс тестов. В этом случае будут запущены только методы, которые начинаются с указанной строки.

Создание собственного TestLoader, использующего регулярные выражения для поиска тестов в классе
Как вариант, можно перегрузить класс TestLoader и сделать так, чтобы он искал не просто по совпадению префикса, а по регулярному выражению (использовал camelCase для соответствия стилю именования, принятому в unittest):
import unittest import functools import re
class MyTestLoader(unittest.TestLoader): def getTestCaseNames(self, testCaseClass): """Return a sorted sequence of method names found within testCaseClass """ def isTestMethod(attrname, testCaseClass=testCaseClass, pattern=self.testMethodPrefix): return (re.match(pattern, attrname) and callable(getattr(testCaseClass, attrname))) testFnNames = list(filter(isTestMethod, dir(testCaseClass))) if self.sortTestMethodsUsing: testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing)) return testFnNames
def run_tests(): loader = MyTestLoader() loader.testMethodPrefix = 'should|test' suite = loader.loadTestsFromTestCase(MyTests) unittest.TextTestRunner().run(suite)
if __name__ == '__main__': run_tests()
Такой загрузчик тестов запустит и стандартные тесты, и тесты, начинающиеся с should

Использование протокола load_tests
Ещё один способ -- это создать функцию load_tests, которая возвращает TestSuit для модуля. Если в модуле определена такая функция, то библиотека попробует вызвать её для получения списка тестов:
def load_tests(loader, tests, pattern): loader.testMethodPrefix = 'should' return loader.loadTestsFromTestCase(MyTests)

Источники:
Документация по библиотеке unittest Документация по TestLoader Протокол load_tests

Комментариев нет:

Отправить комментарий