2016-06-21 2 views
1

Допустим, у меня есть pytest светильник, установленный в моем файле conftest.py, который выглядит как:Автоматическое оформление pytest.mark основано на приспособлении

def live_fixture(): 
    # network access here... 
    pass 

Я использую этот же прибор во многих тестовых функций, говорят, что test_spam. ру имеют некоторые функции тестирования:

@pytest.mark.live 
def test_one(live_fixture): 
    assert 1 


def test_one(): 
    assert 2 

@pytest.mark.live 
def test_three(live_fixture): 
    assert 3 

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

py.test -m "not live" test_spam.py --blockage 

будет надежно проходить (используя изящную pytest-blockage модуль для обеспечения соблюдения ограничений нет-сети доступа).

Но оформление украшения @pytest.mark.live на каждой тестовой функции, которая использует live_fixture, является утомительным и подверженным ошибкам. Есть ли какой-нибудь способ объявить, что любая функция тестирования, которая его использует, должна автоматически иметь приложенное к ней украшение @pytest.mark.live или каким-то образом обнаружить внутри файла test_spam.py то, что test_one и test_three используют это live_fixture и таким образом должны быть эффективно оформлены @pytest.mark.live?

ответ

1

Я нашел другое правдоподобное решение, пытаясь выяснить, как работает pytest.mark.

Я нашел класс Узел имеет метод «add_marker», который должен быть точным методом реализации функции pytest.mark. И элемент класса расширен от узла.

Так что мое решение:

  1. Пытаясь найти, если прибор используется тест.
  2. Пусть Item объект тестового вызова add_marker

Пример: Добавить следующий метод в conftest.py

def pytest_itemcollected(item): 
    """ we just collected a test item. """ 
    if 'live_fixture' in item.fixturenames: 
     item.add_marker('live') 

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

+0

Это действительно опрятное решение, спасибо! Я также надеялся автоматически применить украшение 'pytest.mark.skipif' на любые тестовые функции, используя' live_fixture', вы знаете, если это возможно? –

+0

@JoshKupershmidt Да, add_marker также принимает объект MarkDecorator в качестве входных данных, а 'pytest.mark.skipif' возвращает объект MarkDecorator. Итак, все, что вам нужно сделать, это создать маркер skipif и добавить его. Например: 'marker = pytest.mark.skipif (condition, reason = '')', затем 'item.add_marker (marker)' –

+0

Очень аккуратно, спасибо! –

0

Ну, я обманул себя этим чуть больше и получил что-то очень грубое. Я определяю функцию как это:

import sys, inspect, pytest 

def mark_live_fixtures(module_name): 
    testfunctions = [obj for name,obj 
        in inspect.getmembers(sys.modules[module_name]) 
        if (inspect.isfunction(obj) and 
         name.startswith('test') and name != 'testall')] 

    for func in testfunctions: 
     if 'live_fixture' in inspect.getargspec(func).args: 
      func = pytest.mark.live(func) 

И тогда я в состоянии придерживаться вызова mark_live_fixtures(__name__) в нижней части тестового файла, и это, кажется, относится pytest.mark.live украшения для всех тестовых функций в этом модуле с помощью live_fixture. Но есть, по крайней мере, две проблемы, связанные с этим подходом:

  1. Я считаю, что это будет работать только с пробными функциями, определенными на верхнем уровне тестового модуля, я сомневаюсь, что он будет работать с пробными функциями внутри test class.
  2. Любые тестовые функции, которые, например, @mock.patch или другое обычное тестовое оформление будет не имеют правильную аргументацию интроспекции, доступную для проверки.getargspec (по этой причине существует модуль decorator), поэтому они не будут оформлены, как ожидалось.

Это, по общему признанию, немного уродливое, может быть, у кого-то есть более чистое решение?

Смежные вопросы