Предоставление параметров в TestCase из пакета в python
из документации python(http://docs.python.org/library/unittest.html):
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
self.widget = None
def test_default_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
вот, как вызвать те testcase:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
return suite
можно ли вставить параметр custom_parameter в WidgetTestCase, например:
class WidgetTestCase(unittest.TestCase):
def setUp(self,custom_parameter):
self.widget = Widget('The widget')
self.custom_parameter=custom_parameter
?
5 ответов
что я сделал в модуле test_suite просто добавил
WidgetTestCase.CustomParameter="some_address"
самые простые решения являются лучшими :)
Я нашел способ сделать это, но это немного cludge.
в основном, то, что я делаю, это добавить в тестовый набор __init__
метод, который определяет параметр "по умолчанию" и __str__
Так что мы можем различать случаи:
class WidgetTestCase(unittest.TestCase):
def __init__(self, methodName='runTest'):
self.parameter = default_parameter
unittest.TestCase.__init__(self, methodName)
def __str__(self):
''' Override this so that we know which instance it is '''
return "%s(%s) (%s)" % (self._testMethodName, self.currentTest, unittest._strclass(self.__class__))
затем в suite () я перебираю параметры теста, заменяя параметр по умолчанию одним конкретным для каждого теста:
def suite():
suite = unittest.TestSuite()
for test_parameter in test_parameters:
loadedtests = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
for t in loadedtests:
t.parameter = test_parameter
suite.addTests(loadedtests)
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(OtherWidgetTestCases))
return suite
здесь OtherWidgetTestCases
- это тесты, которые не нужно параметризовать.
например I есть куча тестов на реальных данных, для которых набор тестов должен быть применен к каждому, но у меня также есть некоторые синтетические наборы данных, предназначенные для тестирования определенных крайних случаев, обычно не присутствующих в данных, и мне нужно только применить определенные тесты к ним, поэтому они получают свои собственные тесты в OtherWidgetTestCases
.
это то, что было у меня на уме в последнее время. Да, это очень возможно сделать. Я назвал его тесты, но я думаю, что параметризованный может быть более точным. Я поставил доказательство концепции как gist здесь. Короче говоря, это мета-класс, который позволяет определить сценарий и запустить тесты против него кучу. С его помощью ваш пример может быть примерно таким:
class WidgetTestCase(unittest.TestCase):
__metaclass__ = ScenarioMeta
class widget_width(ScenerioTest):
scenarios = [
dict(widget_in=Widget("One Way"), expected_tuple=(50, 50)),
dict(widget_in=Widget("Another Way"), expected_tuple=(100, 150))
]
def __test__(self, widget_in, expected_tuple):
self.assertEqual(widget_in.size, expected_tuple)
при запуске мета-класс записывает 2 отдельных теста, поэтому вывод было бы что-то вроде:
$ python myscerariotest.py -v test_widget_width_0 (__main__.widget_width) ... ok test_widget_width_1 (__main__.widget_width) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
Как вы можете видеть, сценариев преобразуются в тесты во время выполнения.
теперь я еще не уверен, что это хорошая идея. Я использую его в тестах, где у меня много текстовых случаев, которые повторяют одни и те же утверждения на немного разных данных, что помогает мне поймать маленькие крайние случаи. Но классы в этом gist работают, и я считаю, что он выполняет то, что вам нужно.
отметим, что с некоторым обманом тестовые случаи можно дать имена и даже вытащить из внешнего источника, такого как текстовый файл или база данных. Его еще не задокументировано, но некоторые раскопки в мета-классе должны заставить вас начать. На моем посту также есть дополнительная информация и примеры здесь.
редактировать
это уродливый хак, который я больше не поддерживаю. Реализация должна была быть выполнена как подкласс TestCase, а не как взломанный мета-класс. Жить и учить. Еще лучшим решением было бы использовать генераторы нос.
Я так не считаю, подпись для установки должна быть тем, что ожидает unittest, afaik, setUp автоматически вызывается в методе запуска testcase как setUp()... вы не сможете передать его, если не переопределите run для передачи в var, который вы хотите. Но я думаю, что то, что вы хотите, побеждает цель блок тестирование. Не пытайтесь использовать сухую философию с этим, каждый блок, который вы тестируете, должен быть частью класса или даже частью функции/метода.
Я не думаю, что это хорошая идея. Модульные тесты должны быть достаточно тщательными, чтобы вы тестировали все функции в своих случаях, поэтому передача разных параметров не требуется.
вы упоминаете, что вы проходите по адресу www-это почти наверняка не хорошая идея. Что произойдет, если вы попытаетесь запустить тесты на машине, где сетевое соединение не работает? Тесты должны быть:
автоматическое - они будут работать на всех машинах и платформах где поддерживается ваше приложение,без вмешательства пользователя. Они не должны полагаться на внешнюю среду, чтобы пройти. Это означает (среди прочего), что полагаться на правильно настроенное подключение к интернету-плохая идея. Вы можете обойти это, предоставив фиктивные данные. Вместо того, чтобы передавать URL-адрес ресурсу, абстрагируйте источник данных и передайте его в поток данных или что-то еще. Это особенно легко в python, так как вы можете использовать утку python для представления stream-like object (python часто использует "файловый" объект именно по этой причине!).
тщательный-ваши модульные тесты должны иметь 100% покрытие кода и охватывать все возможные ситуации. Вы хотите проверить свой код на нескольких сайтах? Вместо этого проверьте свой код со всеми возможными функциями, которые может включать сайт. Не зная больше о том, что делает ваше приложение, я не могу предложить много советов в этом вопросе.
теперь, похоже, ваши тесты будут сильно зависеть от данных. Существует множество инструментов, позволяющих определить наборы данных для модульных тестов и загрузить их в тесты. Например, проверьте тестовые приспособления python.
Я понимаю, что это не тот ответ, который вы ищете, но я думаю, что вы будете иметь больше радости в долгосрочной перспективе, если вы будете следовать этим принципам.