Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Использование фикстур для unittest.TextTestRunner.run()

pytest
unittest
python
Теги: #<Tag:0x00007f7b68cb4ab8> #<Tag:0x00007f7b68cb48b0> #<Tag:0x00007f7b68cb46a8>

(Влад Давидченко) #1

Есть определенный набор тестов, объединенных в сьют.
Идея: запускать одни и те же тесты, но используя разный прекондишн и посткондишн - т.е. логин и логаут под разными юзерами

Генерация сьюта:

import unittest
import pytest

from adminzone_tests.Clients import TestClients

def collect_suite():
    suite = unittest.TestSuite()
    suite.addTest(TestClients)
    return suite

@pytest.mark.usefixtures('admin_session')
def run():
    unittest.TextTestRunner(verbosity=2).run(collect_suite())

@pytest.mark.usefixtures('client_session')
def run():
    unittest.TextTestRunner(verbosity=2).run(collect_suite())

conftest.py файл:

import pytest

from base.Common import Common
from base.Users import Users


@pytest.fixture(scope='session')
def admin_session(request):
    Users.users('admin')

    def admin_session_teardown():
        Common.logout()
    request.addfinalizer(admin_session_teardown)

@pytest.fixture(scope='session')
def client_session(request):
    Users.users('client')

    def client_session_teardown():
        Common.logout()
    request.addfinalizer(client_session_teardown)

Если у фикстуры нет параметра autouse=True, то она не применяется для метода run()

Как можно реализовать запуск одного сьюта с разными логинами?


(Igor Balagurov) #2

Надо фикстуру вызывать, а ещё можно посмотреть для таких случаев на параметризацию фикстур.
https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures
и в догонку хороший видос с примерами работы с фикстурами:


(Влад Давидченко) #3

фикстура вызывается же для теста, а не для метода, в котором будет выполняться запуск, как это будет выглядеть структурно?


(Влад Давидченко) #4

с помощью фикстур можно вызывать один и тот же тест с разными параметрами, а как это сделать для всего рана?


(Igor Balagurov) #5

если надо весь тестовый набор несколько раз с разными параметрами вызывать, то вариантов два:

  1. Везде вставить нужную параметризованную фикстуру
  2. Пробрасывать переменные и несколько раз с разными переменными запустить тесты (делается через CI-tool или скрипт написать)

(Влад Давидченко) #6

пробрасывать как аргументы командной строки? если можно, пример скрипта


(Igor Balagurov) #7

проще через environment variable
выглядит примерно так:

  1. в консоли устанавливаете значение export USER=admin
  2. в тестах вытягиваете его user = os.environ.get('USER')
  3. используете в тестах эту переменную

скрипт будет выглядеть примерно так:
export USER=admin
py.test …
export USER=…
py.test …
и т.д.


(Влад Давидченко) #8

сделал немного по другому, через агрументы командной строки
В принципе, получилось как и хотел: выполняет suite под одним пользователем, потом под другим, в параллели в 4 потока прекрасно отработало

conftest.py

def pytest_addoption(parser):
    parser.addoption('--users', action='append', default=['user1'])

def pytest_generate_tests(metafunc):
    if 'users' in metafunc.fixturenames:
        us = set(metafunc.config.option.users)
        if not us:
            us = ['user1']
        elif 'all' in us:
            us = ['user2', 'user1']
        else:
            us = list(us)
        metafunc.parametrize('users', us, scope='session')

@pytest.yield_fixture(scope='session', autouse=True)
def define_users(request, users):
   # execute login as user
   .........

    def teardown():
        # execute logout
        ........
        request.addfinalizer(teardown)

Cases.py:

................
suite = unittest.TestSuite()
def collect_suite():
    suite.addTest(TestClass1)
    .........................................

def run():
    unittest.TextTestRunner(verbosity=2).run(suite)

Запуск этого дела(из под винды, надо находиться в корневой папке проекта):

python -m pytest Cases.py -v -n auto --users all