Если вы пишете библиотеку или приложение, куда идут файлы модульного теста?
Приятно отделить тестовые файлы от основного кода приложения, но неудобно помещать их в подкаталог «tests» внутри корневого каталога приложения, потому что это затрудняет импорт модулей, которые вы будете тестировать.
Есть ли здесь лучшая практика?
python
unit-testing
code-organization
Readonly
источник
источник
Ответы:
Для файла
module.py
обычноtest_module.py
вызывается модульный тест , следуя соглашениям Python по присвоению имен.Есть несколько общепринятых мест для размещения
test_module.py
:module.py
.../tests/test_module.py
(на том же уровне, что и каталог кодов).tests/test_module.py
(один уровень под каталогом кода).Я предпочитаю № 1 за простоту поиска тестов и их импорта. Какую бы систему сборки вы не использовали, ее можно легко настроить для запуска файлов, начиная с
test_
. На самом деле, шаблон по умолчаниюunittest
, используемый для обнаружения теста, являетсяtest*.py
.источник
Только 1 тестовый файл
Если имеется только 1 тестовый файл, рекомендуется поместить его в каталог верхнего уровня:
Запустите тест в CLI
Множество тестовых файлов
Если есть много тестовых файлов, поместите его в
tests
папку:Запустите тест в CLI
использование
unittest discovery
unittest discovery
найдете все тесты в папке пакета.Создать
__init__.py
вtests/
папкеЗапустите тест в CLI
Ссылка
pytest
Хорошая практика для макета тестаunittest
Модуль модульного тестирования
источник
Обычной практикой является размещение каталога tests в том же родительском каталоге, что и ваш модуль / пакет. Так что, если ваш модуль называется foo.py, ваш макет каталога будет выглядеть так:
Конечно, нет единого способа сделать это. Вы также можете создать подкаталог test и импортировать модуль, используя абсолютный импорт .
Куда бы вы ни ставили свои тесты, я бы порекомендовал вам использовать нос для их проведения. Нос ищет в ваших каталогах тесты. Таким образом, вы можете ставить тесты там, где они наиболее целесообразны с организационной точки зрения.
источник
У нас был тот же вопрос при написании Pythoscope ( https://pypi.org/project/pythoscope/ ), который генерирует модульные тесты для программ на Python. Мы опрашивали людей на тестировании в списке Python, прежде чем мы выбрали каталог, было много разных мнений. В итоге мы решили поместить каталог «tests» в тот же каталог, что и исходный код. В этом каталоге мы генерируем тестовый файл для каждого модуля в родительском каталоге.
источник
Я также склоняюсь к тому, чтобы помещать свои модульные тесты в сам файл, как замечает Джереми Кантрелл, хотя я склонен не помещать тестовую функцию в основной корпус, а скорее помещать все в
блок. Это завершает добавление документации к файлу в качестве «примера кода» о том, как использовать проверяемый файл python.
Я должен добавить, я склонен писать очень узкие модули / классы. Если ваши модули требуют очень большого количества тестов, вы можете поместить их в другой, но даже тогда я бы добавил:
Это позволяет любому, кто читает ваш исходный код, знать, где искать тестовый код.
источник
Время от времени я проверяю тему размещения тестов, и каждый раз большинство рекомендует отдельную структуру папок рядом с кодом библиотеки, но я нахожу, что каждый раз аргументы совпадают и не настолько убедительны. Я заканчиваю тем, что помещаю свои тестовые модули где-то рядом с основными модулями.
Основная причина для этого: рефакторинг .
Когда я перемещаю вещи, я хочу, чтобы тестовые модули перемещались вместе с кодом; легко потерять тесты, если они находятся в отдельном дереве. Давайте будем честными, рано или поздно вы получите совершенно другую структуру папок, такую как django , flask и многие другие. Что хорошо, если тебе все равно.
Главный вопрос, который вы должны задать себе:
Я пишу:
Если:
Отдельная папка и дополнительные усилия по поддержанию ее структуры могут быть более подходящими. Никто не будет жаловаться на то, что ваши тесты будут внедрены в производство .
Но также легко исключить распространение тестов, когда они смешаны с основными папками; поместите это в setup.py :
Если б:
Вы можете пожелать - как и каждый из нас - что вы пишете многократно используемые библиотеки, но большую часть времени их жизнь связана с жизнью проекта. Возможность легко поддерживать ваш проект должна быть приоритетом.
Тогда, если вы хорошо поработали, и ваш модуль хорошо подходит для другого проекта, он, вероятно, будет скопирован - не разветвлен или превращен в отдельную библиотеку - в этот новый проект и перенесет расположенные рядом с ним тесты в ту же структуру папок. это легко по сравнению с тестированием в беспорядке, в которое превратилась отдельная папка. (Вы можете утверждать, что это не должно быть беспорядком, но давайте будем реалистичны здесь).
Так что выбор остается за вами, но я бы сказал, что с помощью смешанных тестов вы достигаете того же, что и с отдельной папкой, но с меньшими усилиями по поддержанию порядка.
источник
Я использую
tests/
каталог, а затем импортирую основные модули приложения, используя относительный импорт. Так что в MyApp / tests / foo.py могут быть:импортировать
MyApp.foo
модуль.источник
Я не верю, что существует установленная «лучшая практика».
Я поместил свои тесты в другой каталог за пределами кода приложения. Затем я добавляю основной каталог приложения в sys.path (позволяя вам импортировать модули из любого места) в моем скрипте бегуна тестов (который также выполняет некоторые другие вещи) перед запуском всех тестов. Таким образом, мне никогда не придется удалять каталог tests из основного кода, когда я его выпускаю, что экономит мое время и усилия, если даже очень мало.
источник
os.sys.path.append(os.dirname('..'))
Исходя из моего опыта разработки сред тестирования на Python, я бы предложил поместить модульные тесты Python в отдельный каталог. Поддерживать симметричную структуру каталогов. Это было бы полезно для упаковки только основных библиотек, а не для пакетных тестов. Ниже реализована принципиальная схема.
Таким образом, когда вы упаковываете эти библиотеки, используя rpm, вы можете просто упаковать модули основной библиотеки (только). Это помогает ремонтопригодности, особенно в гибкой среде.
источник
Я рекомендую вам проверить некоторые основные проекты Python на GitHub и получить некоторые идеи.
Когда ваш код становится больше и вы добавляете больше библиотек, лучше создать тестовую папку в том же каталоге, где у вас есть файл setup.py, и отразить структуру каталогов вашего проекта для каждого типа теста (unittest, интеграция, ...)
Например, если у вас есть структура каталогов, например:
После добавления тестовой папки у вас будет такая структура каталогов, как:
Многие правильно написанные пакеты Python используют одну и ту же структуру. Очень хороший пример - пакет Boto. Проверьте https://github.com/boto/boto
источник
matplotlib
имеет его вmatplotlib/lib/matplotlib/tests
( github.com/matplotlib/matplotlib/tree/… ),sklearn
имеет его вscikitelearn/sklearn/tests
( github.com/scikit-learn/scikit-learn/tree/master/sklearn/tests )Как я это делаю ...
Структура папки:
Setup.py указывает на src / как местоположение, содержащее мои модули проектов, затем я запускаю:
Который добавляет мой проект в пакеты сайтов, указывая на мою рабочую копию. Для запуска моих тестов я использую:
Используя тот тестовый бегун, который я настроил.
источник
code.py
. Было бы разумнее называть каталог верхнего уровня «проектом».Я предпочитаю выполнять тестовый каталог. Это означает, что импорт становится немного сложнее. Для этого у меня есть два решения:
test_suite='tests.runalltests.suite'
вsetup()
, и может запускать тесты просто:python setup.py test
PYTHONPATH=. python tests/runalltests.py
Вот как эта штука поддерживается кодом в M2Crypto:
Если вы предпочитаете проводить тесты с тестами носа, вам может потребоваться сделать что-то немного другое.
источник
Мы используем
В каждом тестовом файле мы вставляем
../src/
вsys.path
. Это не самое лучшее решение, но оно работает. Я думаю, было бы замечательно, если бы кто-то придумал что-то вроде maven в java, которое дает вам стандартные соглашения, которые просто работают, независимо от того, над каким проектом вы работаете.источник
Если тесты просты, просто поместите их в строку документации - большинство тестовых сред для Python смогут использовать это:
Для других более сложных тестов я бы поставил их либо в,
../tests/test_module.py
либо вtests/test_module.py
.источник
В C # я обычно разделял тесты на отдельную сборку.
В Python - пока что - я обычно пишу тесты документов, где тест находится в строке документации функции, или помещаю их в
if __name__ == "__main__"
блок в нижней части модуля.источник
При написании пакета с именем "foo" я помещу модульные тесты в отдельный пакет "foo_test". Модули и подпакеты будут иметь то же имя, что и модуль пакета SUT. Например, тесты для модуля foo.xy находятся в файле foo_test.xy. Файлы __init__.py каждого пакета тестирования содержат набор AllTests, который включает все наборы тестов пакета. setuptools предоставляет удобный способ указать основной пакет тестирования, так что после «python setup.py development» вы можете просто использовать «python setup.py test» или «python setup.py test -s foo_test.x.SomeTestSuite» для просто конкретный набор.
источник
Я помещаю свои тесты в ту же директорию, что и тестируемый код (CUT); для
foo.py
тестов будет вfoo_ut.py
или подобное. (Я настраиваю тестовый процесс обнаружения, чтобы найти их.)Это помещает тесты рядом с кодом в список каталогов, делая очевидным наличие тестов, и делает открытие тестов настолько простым, насколько это возможно, когда они находятся в отдельном файле. (Для редакторов командной строки
vim foo*
и при использовании графического браузера файловой системы просто щелкните файл CUT, а затем непосредственно смежный файл теста.)Как уже отмечали другие , это также облегчает рефакторинг и извлечение кода для использования в других местах, если это когда-либо понадобится.
Мне действительно не нравится идея помещать тесты в совершенно другое дерево каталогов; зачем усложнять разработчикам открытие тестов при открытии файла с помощью CUT? Не то, чтобы подавляющее большинство разработчиков так увлеклись написанием или настройкой тестов, что игнорировали бы любой барьер для этого, вместо того, чтобы использовать этот барьер в качестве оправдания. (Напротив, по моему опыту; даже когда вы делаете это как можно проще, я знаю многих разработчиков, которые не могут быть обеспокоены написанием тестов.)
источник
Я недавно начал программировать на Python, поэтому у меня пока не было возможности найти лучшие практики. Но я написал модуль, который находит и находит все тесты и запускает их.
Так что я:
Мне нужно будет посмотреть, как это пойдет по мере продвижения к более крупным проектам.
источник