Как сделать "досрочное возвращение" импорта под Nose?

Я курирую большое количество юнит-тестов для большого проекта Python. Мы используем нос, чтобы сделать наш тест обнаружения и выполнения. У меня есть несколько тестовых файлов, которые действительно не должны запускаться в определенных условиях. Например, может быть, у меня есть тестовый модуль, который никогда не должен запускаться в Windows (только в Mac и Linux).

Вот некоторые решения, которые я использовал:

  1. Пометьте методы или классы испытаний условиями, используя отличный плагин attrib для Nose.
  2. Используйте unittest.skipIf() для тестовых методов или классов
  3. Используйте исключения из шаблона носа, чтобы пропустить файлы с 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 если необходимо.

Другие вопросы по тегам