@ilyakomarov

Запуск тестов с опции командной строки?

Пишу тесты с использованием фреймворка pytest. Есть необходимость запускать тесты используя опции командной строки.

Структура такая: файл #conftest где описываю фикстуры для трех разных тестов и файл #test в котором описаны три разных теста соотвественно. Под каждую фикстуру свой тест, то есть fixture1 - test1, fixture2 - test2 и все в двух файлах.

Я решил использовать пайтестовский pytest_addoption (наследуется от argparse).
В файле #conftest записываю опиции:

def pytest_addoption(parser):
    parser.addoption("--url1", action="store", default="None", help="For service_1")
    parser.addoption("--url2", action="store", default="None", help="For service 2")
    parser.addoption("--url3", action="store", default="None", help="For service 3")


Далее описываются фикстуры для каждого теста:
pytest.fixture()
def use_url1(request):
    return request.config.getoption("-url1")

@pytest.fixture()
def requests_get_service_1(use_url1):
    return requests.get(use_url1)
#########################
@pytest.fixture()
def use_url2(request):
    return request.config.getoption("-url2")

@pytest.fixture()
def request_get_service_2(use_url2):
    return requests.get(use_url2)
#########################
@pytest.fixture()
def use_url3(request):
    return request.config.getoption("-url3")

@pytest.fixture()
def request_get_service_3(use_url3):
    return requests.get(use_url3)

Далее все прокидывается в тесты.

Опции командной строки должны позволять выбрать один из URL, который тестируем или все.
Проще говоря каким образом описать фикстуры так, чтобы при запуске командной строки я указывал одну из трех опции (например "--url2" ya.ru) и файл исполнял фикстуру и тесты только с url2, а остальные фикстуры и тесты он не трогал?

полагаю что можно описать условием, но это не точно:
if что-то == "--url2":
    запустить фикстуру  request_get_service_2 и передать в тест для этой фикстуры
else:
    pass
  • Вопрос задан
  • 1609 просмотров
Пригласить эксперта
Ответы на вопрос 2
@javedimka
Хочу сока
import pytest

@pytest.fixture()
def fixture1():
    print "Fixture 1"

@pytest.fixture()
def fixture2():
   print "Fixture 2"

В pytest_addoption в опциональных аргументах default убрать кавычки вокруг None и использовать
Маркер skipif:
import pytest

def skip_non_matching_url(option):
    return pytest.mark.skipif(
        not getattr(pytest.config.option, option, None),
        reason="Url doesn't match command line option"
    )

@skip_non_matching_url("url2")
def test_my_url2(fixture2):
    print "Test my url2"

@skip_non_matching_url("url1")
def test_my_url1(fixture1):
    print "Test my ulr1"


$ python -m pytest -vs --url1 ya.ru

collected 2 items

test_something.py::test_my_url2 SKIPPED
test_something.py::test_my_url1 Fixture 1
Test my ulr1
PASSED


$ python -m pytest -vs --url2 ya.ru

collected 2 items

test_something.py::test_my_url2 Fixture 2
Test my url2
PASSED
test_something.py::test_my_url1 SKIPPED


Или кастомные маркеры:

import pytest

@pytest.mark.url2
def test_my_url2(fixture2):
    print "Test my url2"

@pytest.mark.url1
def test_my_url1(fixture1):
    print "Test my ulr1"


$ python -m pytest -vs -m url2

collected 2 items

test_something.py::test_my_url2 Fixture 2
Test my url2
PASSED


$ python -m pytest -vs -m url1

collected 2 items

test_something.py::test_my_url1 Fixture 1
Test my ulr1
PASSED
Ответ написан
Я бы более явно разметил все тесты mark.url1 .. mark.urln.
Но если хотите пропускать тесты на основе фикстур то тогда вам в помощь pytest_collection_modifyitems

def pytest_collection_modifyitems(items):
    mark = pytest.mark.skip('Test is not present in test run.')
    # Тут любая магия которая придет к вам в голову.
    for item in items:
        if item.config.getoption('url2') is None:
            item.add_marker(mark)

# UPD я бы посмотрел, в сторону того что бы не пложить фикстуру request_get_service, а прокидывать ей url, 
# запрашивая её в нужных местах,  что-то типо такого.
#########################
@pytest.fixture()
def request_get_service(requests, url):
    return requests.get(url)


#########################
@pytest.fixture()
def use_url2(request_get_service, requests):
    url = requests.config.getoption('url2')
    return request_get_service(requests, url)


@pytest.fixture()
def use_url3(request_get_service, requests):
    url = requests.config.getoption('url2')
    return request_get_service(requests, url)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы