В настоящее время у меня есть несколько модульных тестов, которые используют общий набор тестов. Вот пример:
import unittest
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Результат вышеупомянутого:
Calling BaseTest:testCommon
.Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK
Есть ли способ переписать вышесказанное, чтобы testCommon
не назывался самый первый ?
РЕДАКТИРОВАТЬ: вместо запуска 5 тестов выше, я хочу, чтобы он запускал только 4 теста, 2 из SubTest1 и еще 2 из SubTest2. Кажется, что Python unittest запускает оригинальный BaseTest сам по себе, и мне нужен механизм, чтобы предотвратить это.
python
unit-testing
testing
Тьерри Лам
источник
источник
Ответы:
Используйте множественное наследование, поэтому ваш класс с общими тестами сам по себе не наследуется от TestCase.
источник
setUp
иtearDown
методы вCommonTests
класс и хотите, чтобы они вызывались для каждого теста в производных классах, вы должны изменить порядок базовых классов, так что это будет:class SubTest1(CommonTests, unittest.TestCase)
.unittest.TestCase
иCommonTests
. Я думаю, чтоsetUpClass
метод ниже является лучшим и менее подвержен человеческим ошибкам. Либо это, либо упаковка класса BaseTest в контейнерный класс, который немного более хакерский, но позволяет избежать пропуска сообщения в распечатке тестового прогона.CommonTests
вызывает методы, которые не существуют в этом классе.Не используйте множественное наследование, это укусит вас позже .
Вместо этого вы можете просто переместить ваш базовый класс в отдельный модуль или обернуть его пустым классом:
Выход:
источник
Вы можете решить эту проблему с помощью одной команды:
Таким образом, код будет выглядеть так:
источник
self.assert*
методы не существуют в стандартном объекте.super( BaseTest, cls ).setUpClass( )
BaseTest
можно ссылаться черезsuper(self.__class__, self)
или простоsuper()
в подклассах, хотя, очевидно, нет, если вы должны были наследовать конструкторы . Возможно, существует и такая «анонимная» альтернатива, когда базовый класс должен ссылаться на себя (не то чтобы я имел представление, когда класс должен ссылаться на себя).Ответ Мэтью Маршалла великолепен, но он требует, чтобы вы унаследовали от двух классов в каждом из ваших тестовых случаев, что подвержено ошибкам. Вместо этого я использую это (python> = 2.7):
источник
Чего ты пытаешься достичь? Если у вас есть общий тестовый код (утверждения, тесты шаблонов и т. Д.), Поместите их в методы, для которых нет префикса,
test
поэтомуunittest
не будут загружать их.источник
Ответ Мэтью - тот, который мне нужно было использовать, так как я все еще на 2.5. Но начиная с версии 2.7 вы можете использовать декоратор @ unittest.skip () для любых методов тестирования, которые хотите пропустить.
http://docs.python.org/library/unittest.html#skipping-tests-and-expected-failures
Вам нужно будет реализовать собственный пропускающий декоратор, чтобы проверить базовый тип. Раньше я не использовал эту функцию, но в верхней части моей головы вы можете использовать BaseTest в качестве типа маркера для условия пропуска:
источник
Я решил решить эту проблему, скрыв методы тестирования, если используется базовый класс. Таким образом, тесты не пропускаются, поэтому результаты теста могут быть зелеными, а не желтыми во многих инструментах отчетов о тестировании.
По сравнению с методом mixin, ide как PyCharm не будет жаловаться на то, что в базовом классе отсутствуют методы модульного тестирования.
Если базовый класс наследует от этого класса, то нужно будет переопределить
setUpClass
иtearDownClass
методу.источник
Вы можете добавить
__test_ = False
класс BaseTest, но если вы добавите его, помните, что вы должны добавить__test__ = True
в производные классы, чтобы иметь возможность запускать тесты.источник
Другой вариант не выполнить
Вместо этого вы можете использовать
Таким образом, вы выполняете только тесты в классе
TestClass
источник
unittest.main()
собирается в набор по умолчанию, вы формируете явный набор и запускаете его тесты.Я сделал примерно то же самое, что @Vladim P. ( https://stackoverflow.com/a/25695512/2451329 ), но немного изменил:
и там мы идем.
источник
Начиная с Python 3.2, вы можете добавить функцию test_loader в модуль, чтобы контролировать, какие тесты (если таковые имеются) обнаруживаются механизмом обнаружения тестов.
Например, следующее будет загружать только оригинальные плакаты
SubTest1
иSubTest2
тестовые случаи, игнорируяBase
:Должна быть возможность перебора
standard_tests
(TestSuite
содержащая тесты, найденный загрузчик по умолчанию) и копирование всего, кромеBase
какsuite
вместо этого, но вложенная природаTestSuite.__iter__
делает это намного сложнее.источник
Просто переименуйте метод testCommon во что-то другое. Unittest (обычно) пропускает все, что не имеет «test».
Быстро и просто
источник
Так что это своего рода старая тема, но я столкнулся с этой проблемой сегодня и подумал о своем собственном взломе. Он использует декоратор, который делает значения функций None при обращении через базовый класс. Не нужно беспокоиться о настройке и настройке класса, потому что если в базовом классе нет тестов, они не запустятся.
источник
Вот решение, которое использует только документированные функции unittest и позволяет избежать «пропуска» статуса в результатах вашего теста:
Как это работает: согласно
unittest.TestCase
документации , «Каждый экземпляр TestCase будет запускать один базовый метод: метод с именем methodName». По умолчанию «runTests» запускает все методы test * в классе - именно так обычно работают экземпляры TestCase. Но при работе в самом абстрактном базовом классе вы можете просто переопределить это поведение с помощью метода, который ничего не делает.Побочным эффектом является то, что число ваших тестов увеличится на единицу: runNoTestsInBaseClass «test» будет считаться успешным тестом при запуске на BaseClass.
(Это также работает в Python 2.7, если вы все еще на этом. Просто перейдите
super()
наsuper(BaseTest, self)
.)источник
Измените имя метода BaseTest на setUp:
Вывод:
Из документации :
источник
setUp
?test...
метод, онsetUp
выполняется снова и снова, один раз для такого метода; так что не стоит ставить там тесты!