У меня есть каталог, содержащий мои модульные тесты Python. Каждый модуль модульного тестирования имеет форму теста _ *. Py . Я пытаюсь создать файл с именем all_test.py , который, как вы уже догадались, запустит все файлы в вышеупомянутой тестовой форме и вернет результат. Я пробовал два метода до сих пор; оба потерпели неудачу. Я покажу два метода, и я надеюсь, что кто-то там знает, как на самом деле сделать это правильно.
Для моей первой отважной попытки я подумал: «Если я просто импортирую все свои модули тестирования в файл, а затем назову этот unittest.main()
doodad, он будет работать, верно?» Ну, оказывается, я был не прав.
import glob
import unittest
testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
if __name__ == "__main__":
unittest.main()
Это не сработало, результат, который я получил:
$ python all_test.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Для моей второй попытки, хотя, хорошо, может быть, я попытаюсь сделать все это тестирование более «ручным» способом. Поэтому я попытался сделать это ниже:
import glob
import unittest
testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
[__import__(str) for str in module_strings]
suites = [unittest.TestLoader().loadTestsFromName(str) for str in module_strings]
[testSuite.addTest(suite) for suite in suites]
print testSuite
result = unittest.TestResult()
testSuite.run(result)
print result
#Ok, at this point I have a result
#How do I display it as the normal unit test command line output?
if __name__ == "__main__":
unittest.main()
Это тоже не сработало, но похоже так близко!
$ python all_test.py
<unittest.TestSuite tests=[<unittest.TestSuite tests=[<unittest.TestSuite tests=[<test_main.TestMain testMethod=test_respondes_to_get>]>]>]>
<unittest.TestResult run=1 errors=0 failures=0>
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Кажется, у меня есть какой-то набор, и я могу выполнить результат. Я немного обеспокоен тем фактом, что в нем говорится только run=1
, кажется, что так и должно быть run=2
, но это прогресс. Но как мне передать и отобразить результат на главном? Или как мне заставить его работать, чтобы я мог просто запустить этот файл, и при этом запустить все модульные тесты в этом каталоге?
источник
Ответы:
С Python 2.7 и выше вам не нужно писать новый код или использовать сторонние инструменты для этого; Выполнение рекурсивного теста через командную строку является встроенным. Поместите
__init__.py
в свой тестовый каталог и:Вы можете прочитать больше в документации по тестированию модулей Python 2.7 или Python 3.x.
источник
Вы можете использовать тестовый бегун, который сделает это за вас. нос очень хорош например. При запуске он находит тесты в текущем дереве и запускает их.
Обновлено:
Вот некоторый код из моих дней перед носом. Возможно, вам не нужен явный список имен модулей, но, возможно, остальные будут вам полезны.
источник
В Python 3, если вы используете
unittest.TestCase
:__init__.py
файл в вашемtest
каталоге ( должен быть названtest/
)test/
соответствуют шаблонуtest_*.py
. Они могут находиться внутри подкаталогаtest/
, и эти подкаталоги могут быть названы как угодно.Затем вы можете запустить все тесты с помощью:
Готово! Решение менее 100 строк. Надеюсь, другой начинающий питон сэкономит время, найдя это.
источник
Теперь это возможно прямо из unittest: unittest.TestLoader.discover .
источник
.... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
Почему? Разница, откуда она берется?python file.py
Ну, немного изучив приведенный выше код (в частности, используя
TextTestRunner
иdefaultTestLoader
), я смог довольно близко подойти. В конце концов я исправил свой код, просто передав все наборы тестов одному конструктору наборов, а не добавляя их «вручную», что решило другие мои проблемы. Так вот мое решение.Да, возможно, проще просто использовать нос, чем делать это, но это не главное.
источник
Если вы хотите запустить все тесты из различных классов тестовых случаев и готовы указать их явно, вы можете сделать это следующим образом:
где
uclid
мой проект иTestSymbols
иTestPatterns
являются подклассамиTestCase
.источник
TestSuite
принимается итерируемое , вы можете создать итеративное в цикле, чтобы избежать повторенияloader.loadTestsFromTestCase
.Я использовал
discover
метод и перегрузкуload_tests
для достижения этого результата в (минимальных, я думаю) числовых строках кода:Исполнение на пятерках что-то вроде
источник
Я пробовал разные подходы, но все они кажутся ошибочными, или мне приходится придумывать какой-то код, это раздражает. Но в Linux есть удобный способ - просто найти каждый тест по определенному шаблону и затем вызывать их один за другим.
и самое главное, это определенно работает.
источник
В случае упакованной библиотеки или приложения вы не хотите этого делать.
setuptools
сделаю это для вас .Просто скажите, где находится ваш корневой тестовый пакет, например:
И беги
python setup.py test
.Обнаружение на основе файлов может быть проблематичным в Python 3, если только вы не избегаете относительного импорта в свой набор тестов, потому что
discover
использует импорт файлов. Несмотря на то, что он поддерживает необязательныеtop_level_dir
, но у меня были бесконечные ошибки рекурсии. Таким образом, простое решение для неупакованного кода - поместить в__init__.py
ваш тестовый пакет следующее (см. Протокол load_tests ).источник
Я использую PyDev / LiClipse и не совсем понял, как запустить все тесты сразу из графического интерфейса. (редактировать: вы щелкаете правой кнопкой мыши корневую тестовую папку и выбираете
Run as -> Python unit-test
Это мой текущий обходной путь:
Я поместил этот код в модуль, который называется
all
в моей тестовой директории. Если я запускаю этот модуль как юнит-тест из LiClipse, тогда все тесты запускаются. Если я попрошу повторить только определенные или неудачные тесты, то будут запущены только эти тесты. Это также не мешает моему тестировщику командной строки (тесты на нос) - оно игнорируется.Возможно, вам придется изменить аргументы на
discover
основе настроек вашего проекта.источник
Основываясь на ответе Стивена Кейгла, я добавил поддержку вложенных тестовых модулей.
Код ищет все подкаталоги
.
для*Tests.py
файлов , которые затем загружаются. Ожидается, что каждый из них*Tests.py
будет содержать один класс,*Tests(unittest.TestCase)
который загружается по очереди и выполняется один за другим.Это работает с произвольным глубоким вложением каталогов / модулей, но каждый каталог между ними должен содержать как
__init__.py
минимум пустой файл. Это позволяет тесту загружать вложенные модули, заменяя косую черту (или обратную косую черту) точками (см.replace_slash_by_dot
).источник
Это старый вопрос, но что сработало для меня сейчас (в 2019 году):
Все мои тестовые файлы находятся в той же папке, что и исходные файлы, и они заканчиваются на
_test
.источник
Поскольку тестовое обнаружение, кажется, является полной темой, существует некоторая специальная структура для тестирования обнаружения:
Подробнее читайте здесь: https://wiki.python.org/moin/PythonTestingToolsTaxonomy
источник
Этот BASH-скрипт будет выполнять тестовый каталог python unittest из ЛЮБОГО места в файловой системе, независимо от того, в каком рабочем каталоге вы находитесь: его рабочий каталог всегда будет находиться там, где находится этот
test
каталог.ВСЕ ИСПЫТАНИЯ, независимые $ PWD
Модуль Python unittest чувствителен к вашему текущему каталогу, если вы не укажете его где (используя
discover -s
опцию).Это полезно, когда вы остаетесь в рабочем
./src
или./example
рабочем каталоге, и вам нужен быстрый общий юнит-тест:ИЗБРАННЫЕ ИСПЫТАНИЯ, независимые $ PWD
Я называю этот служебный файл:
runone.py
и использую его так:Не нужно, чтобы
test/__init__.py
файл загружал ваши пакеты / память во время производства.источник
Вот мой подход к созданию оболочки для запуска тестов из командной строки:
Для простоты прошу прощения за мои не- PEP8 стандарты кодирования.
Затем вы можете создать класс BaseTest для общих компонентов для всех ваших тестов, чтобы каждый ваш тест выглядел просто так:
Для запуска вы просто указываете тесты как часть аргументов командной строки, например:
источник