Как сделать "досрочное возвращение" импорта под Nose?
Я курирую большое количество юнит-тестов для большого проекта Python. Мы используем нос, чтобы сделать наш тест обнаружения и выполнения. У меня есть несколько тестовых файлов, которые действительно не должны запускаться в определенных условиях. Например, может быть, у меня есть тестовый модуль, который никогда не должен запускаться в Windows (только в Mac и Linux).
Вот некоторые решения, которые я использовал:
- Пометьте методы или классы испытаний условиями, используя отличный плагин attrib для Nose.
- Используйте unittest.skipIf() для тестовых методов или классов
- Используйте исключения из шаблона носа, чтобы пропустить файлы с
windows
в названии, например.
Моя жалоба на 1 и 2 заключается в том, что они вынуждают меня импортировать модуль, что, по крайней мере, является пустой тратой времени и может привести к ошибкам при наличии зависимого от платформы импорта. Мне не нравится № 3, потому что я чувствую, что он хрупкий, и при чтении теста не всегда очевидно, что он будет пропущен. Все три, кажется, чрезмерно зависят от взаимодействия между тестом и организатором теста, я хотел бы что-то, что только в тесте.
Я хотел бы сделать что-то вроде следующего в верхней части тестового модуля:
"""This module should not be run on Windows"""
import platform
if platform.system() == 'Windows':
<stop reading this module. nothing to see here>
# do the tests.
Как я могу сказать Python или Nose прекратить чтение модуля, но в этом нет ошибки? Я думаю, что я ищу импортный эквивалент досрочного возврата.
3 ответа
Под Nose и unittest исключение SkipTest обрабатывается специально - это не сбой. Таким образом, следующий код остановит выполнение, и никакой ошибки не будет сообщено бегуну unittest:
import unittest
import platform
if platform.system() == 'Windows':
raise unittest.case.SkipTest("The rest of this code will not be run on Windows.")
Возможность досрочного возврата из выполнения модуля была предложена ранее, но она получила некоторые отрицательные голоса, и функция не была добавлена к языку.
Вы можете прочитать ветку списка рассылки, но, как правило, не было ощущения, что проблема с отступом больших частей модуля на дополнительном уровне не была достаточной причиной для добавления этой функции "возврата". Некоторые говорили, что почти весь код в модулях должен быть внутри функций и классов в любом случае, почти не оставляя код уровня модуля, который будет подвержен этой проблеме.
Вы можете поднять ImportError
там с этим сообщением. Вызывающий, скорее всего, завершит работу с необработанным исключением, объясняющим, что эта ошибка выдается, но он может перехватить ImportError
если необходимо.