Как зарегистрировать отметку в pytest 2.5.1?

Я прочитал документацию pytest. Раздел 7.4.3 содержит инструкции по регистрации маркеров. Я точно следовал инструкциям, но, похоже, это не сработало для меня.

Я использую Python 2.7.2 и pytest 2.5.1.

У меня есть файл pytest.ini в корне моего проекта. Вот все содержимое этого файла:

[pytest]
python_files=*.py
python_classes=Check
python_functions=test
rsyncdirs = . logs
rsyncignore = docs archive third_party .git procs
markers =
    mammoth: mark a test as part of the Mammoth regression suite

Немного предыстории для контекста: люди, создавшие систему автоматизации, над которой я работаю, больше не работают в компании. Они создали собственный плагин, который расширил функциональность стандартного pytest.mark. Насколько я понимаю, единственное, что делает пользовательский плагин, — это делает так, чтобы я мог добавлять отметки к тесту следующим образом:

@pytest.marks(CompeteMarks.MAMMOTH, CompeteMarks.QUICK_TEST_A, CompeteMarks.PROD_BVT)
def my_test(self):

вместо такого:

@pytest.mark.mammoth
@pytest.mark.quick_test_a
@pytest.mark.prod_bvt
def my_test(self):

Пользовательский код плагина остается в базе кода. Я не знаю, оказывает ли это какое-либо негативное влияние на попытку зарегистрировать знак, но подумал, что стоит упомянуть, если кто-то знает иное.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я выполняю следующую команду в командной строке, я НЕ вижу свою гигантскую метку в списке других зарегистрированных меток.

py.test --markers

Вывод, возвращаемый после выполнения вышеуказанной команды, таков:

@pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value.  Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html

@pytest.mark.xfail(condition, reason=None, run=True): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. See http://pytest.org/latest/skipping.html

@pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples.

@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures

@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.

@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.

Что я делаю не так и как мне зарегистрировать свой знак?

Еще одна информация: я применил метку мамонта к одному тесту (показанному ниже), когда запустил команду py.test --markers:

@pytest.mark.mammoth
def my_test(self):

person A_R    schedule 04.02.2014    source источник
comment
Хорошо, я понял это. Я понятия не имею, как все это работает, но вот что произошло: Вот файловая структура проекта, над которым я работаю: /Users/user/projects/fh/consumersites/ Однако среда автоматизации живет здесь: /Users/user/projects/fh/consumersites/automation Итак, когда я запускал py.test --markers, я запустил это из каталога Consumersites верхнего уровня и получил вывод, который я вставил в свой вопрос. Однако по какой-то причине, когда я запускаю команду из каталога автоматизации, я вижу, что моя гигантская метка действительно зарегистрирована.   -  person A_R    schedule 05.02.2014
comment
Кто-нибудь знает, почему я получаю два разных вывода при запуске команды из двух разных каталогов? Автоматизация - это подкаталог потребительских сайтов, поэтому я не понимаю, почему я получаю разные результаты. Спасибо!   -  person A_R    schedule 05.02.2014
comment
Важно отметить, что вы не сказали, где находится pytest.ini, если он находится в подкаталоге consumersites/automation/, то вызов py.test в consumersites/ без каких-либо аргументов будет означать (я думаю), что py.test не найдет файл pytest.ini. Если я прав, вызов py.test automation в consumersites/ должен работать.   -  person flub    schedule 05.02.2014
comment
@flub, спасибо большое! Я только что попробовал ваше предложение, и оно действительно работает! Я был довольно многословен в своем вопросе, поэтому я вижу, как вы могли пропустить ссылку на местоположение pytest.ini. I have a pytest.ini file **at the root of my project**. Here is the entire contents of that file: Когда я впервые задал вопрос, я не осознавал, что место, откуда я запускал команду, было фактором, определяющим, что я делаю неправильно. Еще раз спасибо за ответ!!   -  person A_R    schedule 11.02.2014
comment
Еще один комментарий, прежде чем этот будет полностью избит. Я по-прежнему считаю НЕ интуитивно понятным, что py.test не найдет файл pytest.ini из каталога consumersites. Если automation является подкаталогом consumersites, разве это не должно работать? Или такой дизайн сделан специально, чтобы люди могли иметь несколько файлов pytest.ini в разных местах? Зачем кому-то иметь более 1 файла pytest.ini в кодовой базе платформы автоматизации?   -  person A_R    schedule 11.02.2014
comment
Или, может быть, другой способ взглянуть на это так: py.test --markers очень похож на запуск сценария, и вам нужно запускать его из того места, где живет сценарий... и в этом случае сценарий - это pytest.ini, поэтому команду нужно запустить оттуда, где живет pytest.ini. Опять же, я понятия не имею, как все это работает, но если у кого-то есть больше информации об этом, я хотел бы услышать больше просто ради обучения. Таких пояснений нюансов нигде нет в документации, так что еще раз спасибо!   -  person A_R    schedule 11.02.2014


Ответы (2)


Если я правильно понял ваши комментарии, макет проекта выглядит следующим образом:

~/customersites/
~/customersites/automation/
~/customersites/automation/pytest.ini

Затем вызов py.test следующим образом:

~/customersites$ py.test --markers

заставит py.test искать файл конфигурации в ~/customersites/, а затем и во всех родителях: ~/, /home/, /. В этом случае это не заставит его найти pytest.ini.

Однако, когда вы вызываете его с одним или несколькими аргументами, py.test попытается интерпретировать каждый аргумент как файл или каталог и начнет искать файл конфигурации из этого каталога и его родителей. Затем он перебирает все аргументы по порядку, пока не найдет первый файл конфигурации.

Таким образом, с приведенным выше макетом каталога вызов py.test следующим образом заставит его найти pytest.ini и показать зарегистрированные в нем маркеры:

~/customersites$ py.test automation --markers

так как теперь py.test будет сначала искать файл конфигурации в ~/customersites/automation/, а затем подниматься по дереву каталогов и искать в ~/customersites/. Но поскольку он находит его в ~/customersites/automation/pytest.ini, он останавливается на этом и использует его.

person flub    schedule 13.02.2014
comment
Да сэр! 100% правильно. Должно быть, я пропустил это в документации или что-то в этом роде, но я не знал, что py.test просматривает структуру каталогов при поиске файла pytest.ini. Спасибо всем за помощь в решении такой мелкой и утомительной проблемы!! Нубы вроде меня очень ценят такую ​​помощь! - person A_R; 19.02.2014

Вы пробовали здесь?

Из документов:

Справочник по API для объектов, связанных с метками

класс MarkGenerator[источник]

Factory for MarkDecorator objects - exposed as a pytest.mark singleton
instance.

Example:
import py
@pytest.mark.slowtest
def test_function():
    pass

установит самый медленный объект MarkInfo для объекта test_function.

class MarkDecorator(name, args=None, kwargs=None)[source]

 A decorator for test functions and test classes. When applied it will
 create MarkInfo objects which may be retrieved by hooks as item keywords.
 MarkDecorator instances are often created like this:

 mark1 = pytest.mark.NAME              # simple MarkDecorator
 mark2 = pytest.mark.NAME(name1=value) # parametrized MarkDecorator

и затем могут применяться в качестве декораторов для проверки функций:

@mark2
def test_function():
    pass
person JS.    schedule 04.02.2014