Параметрирование Py.Test на основе параметризованного прибора

У меня есть параметризированный прибор с привязкой к классу, который получает 3 базы данных для своих параметров и возвращает соединение с каждым из них.

Тесты в классе используют этот прибор для проверки каждого атрибута соединения с БД.

Теперь у меня есть новый класс с тестами таблиц базы данных, которые я хочу использовать вышеприведенным прибором, но для параметризации в каждой таблице соединений.

Любое предложение по пути pistest реализовать это? Я не могу найти способ параметризации на основе уже параметризованного элемента.

благодаря

One Solution collect form web for “Параметрирование Py.Test на основе параметризованного прибора”

Тестовые классы используются для:

  • предоставлять функции настройки и разборки для тестовых случаев
  • делиться некоторыми общими значениями во время тестирования

С помощью pytest это необязательно, так как установка и отключение могут выполняться на уровне крепления.

По этой причине мое решение не использует классы (но, вероятно, с ними можно было бы использовать).

Чтобы показать, что (поддельные) соединения создаются, а затем закрываются, смотрите вывод на stdout. Фокус в том, чтобы использовать @pytest.yield_fixture , который не использует return но yield значение, используемое в параметре, введенном в тестовый файл. Независимо от того, что следует за первым оператором yield выполняется как код разрыва.

«прямоугольник»: тест M x N выполняется двумя параметризованными светильниками

Первый случай естественен для py.test , где все варианты крепления объединены.

Поскольку он имеет тестовый пример M x N, я называю его «прямоугольником».

Мои тесты находятся в tests/test_it.py :

 import pytest @pytest.yield_fixture(scope="class", params=["mysql", "pgsql", "firebird"]) def db_connect(request): print("\nopening db") yield request.param print("closing db") @pytest.fixture(scope="class", params=["user", "groups"]) def table_name(request): return request.param def test_it(db_connect, table_name): print("Testing: {} + {}".format(db_connect, table_name)) 

Если вам нужно больше тестовых примеров, например test_it , просто создайте их с другим именем.

Запуск моего тестового примера ::

 $ py.test -sv tests ========================================= test session starts ========================================= platform linux2 -- Python 2.7.9 -- py-1.4.30 -- pytest-2.7.2 -- /home/javl/.virtualenvs/stack/bin/python2 rootdir: /home/javl/sandbox/stack/tests, inifile: collected 6 items tests/test_it.py::test_it[mysql-user] opening db Testing: mysql + user PASSEDclosing db tests/test_it.py::test_it[pgsql-user] opening db Testing: pgsql + user PASSEDclosing db tests/test_it.py::test_it[pgsql-groups] opening db Testing: pgsql + groups PASSEDclosing db tests/test_it.py::test_it[mysql-groups] opening db Testing: mysql + groups PASSEDclosing db tests/test_it.py::test_it[firebird-groups] opening db Testing: firebird + groups PASSEDclosing db tests/test_it.py::test_it[firebird-user] opening db Testing: firebird + user PASSEDclosing db ====================================== 6 passed in 0.01 seconds ======================================= - $ py.test -sv tests ========================================= test session starts ========================================= platform linux2 -- Python 2.7.9 -- py-1.4.30 -- pytest-2.7.2 -- /home/javl/.virtualenvs/stack/bin/python2 rootdir: /home/javl/sandbox/stack/tests, inifile: collected 6 items tests/test_it.py::test_it[mysql-user] opening db Testing: mysql + user PASSEDclosing db tests/test_it.py::test_it[pgsql-user] opening db Testing: pgsql + user PASSEDclosing db tests/test_it.py::test_it[pgsql-groups] opening db Testing: pgsql + groups PASSEDclosing db tests/test_it.py::test_it[mysql-groups] opening db Testing: mysql + groups PASSEDclosing db tests/test_it.py::test_it[firebird-groups] opening db Testing: firebird + groups PASSEDclosing db tests/test_it.py::test_it[firebird-user] opening db Testing: firebird + user PASSEDclosing db ====================================== 6 passed in 0.01 seconds ======================================= 

«Взрывающие треугольники» от одного крепления к N-зависимым светильникам

Идея такова:

  • создать пару приборов db_connect , используя параметризующее приспособление
  • для каждого db_connect генерируют N вариантов атрибутов table_name
  • test_it(db_connect, table_name) только соответствующими комбинациями db_connect и table_name .

Это просто не работает

Единственные решения – использовать какие-то сценарии, которые явно определяют, какие комбинации правильны.

«Сценарии»: косвенная параметризация на уровне тестовой функции

Вместо параметризующих приборов мы должны параметризовать тестовую функцию.

Обычно значение параметра передается непосредственно в тестовую функцию как есть. Если мы хотим, чтобы прибор (названный именем параметра) заботился о создании значения для использования, мы должны указать параметр как indirect . Если мы скажем indirect=True , все параметры будут обработаны таким образом, если мы предоставим список имен параметров, в прибор будут переданы только указанные параметры, а оставшиеся будут проходить, как они есть, в тестовом fuction. Здесь я использую явный список косвенных аргументов.

 import pytest DBCFG = {"pgsql": "postgresql://scott:tiger@localhost:5432/mydatabaser", "mysql": "mysql://scott:tiger@localhost/foo", "oracle": "oracle://scott:tiger@127.0.0.1:1521/sidname" } @pytest.yield_fixture(scope="session") def db_connect(request): connect_name = request.param print("\nopening db {connect_name}".format(connect_name=connect_name)) assert connect_name in DBCFG yield DBCFG[connect_name] print("\nclosing db {connect_name}".format(connect_name=connect_name)) @pytest.fixture(scope="session") def table_name(request): return "tabname-by-fixture {request.param}".format(request=request) scenarios = [ ("mysql", "myslq-user"), ("mysql", "myslq-groups"), ("pgsql", "pgsql-user"), ("pgsql", "pgsql-groups"), ("oracle", "oracle-user"), ("oracle", "oracle-groups"), ] @pytest.mark.parametrize("db_connect,table_name", scenarios, indirect=["db_connect", "table_name"]) def test_it(db_connect, table_name): print("Testing: {} + {}".format(db_connect, table_name)) 

Запуск тестового набора:

 $ py.test -sv tests/test_indirect.py py.test========================================= test session starts ================================== ======= platform linux2 -- Python 2.7.9, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- /home/javl/.virtualenvs/stack /bin/python2 cachedir: tests/.cache rootdir: /home/javl/sandbox/stack/tests, inifile: collected 6 items tests/test_indirect.py::test_it[mysql-myslq-user] opening db mysql Testing: mysql://scott:tiger@localhost/foo + tabname-by-fixture myslq-user PASSED closing db mysql tests/test_indirect.py::test_it[mysql-myslq-groups] opening db mysql Testing: mysql://scott:tiger@localhost/foo + tabname-by-fixture myslq-groups PASSED closing db mysql tests/test_indirect.py::test_it[pgsql-pgsql-user] opening db pgsql Testing: postgresql://scott:tiger@localhost:5432/mydatabaser + tabname-by-fixture pgsql-user PASSED closing db pgsql tests/test_indirect.py::test_it[pgsql-pgsql-groups] opening db pgsql Testing: postgresql://scott:tiger@localhost:5432/mydatabaser + tabname-by-fixture pgsql-groups PASSED closing db pgsql tests/test_indirect.py::test_it[oracle-oracle-user] opening db oracle Testing: oracle://scott:tiger@127.0.0.1:1521/sidname + tabname-by-fixture oracle-user PASSED closing db oracle tests/test_indirect.py::test_it[oracle-oracle-groups] opening db oracle Testing: oracle://scott:tiger@127.0.0.1:1521/sidname + tabname-by-fixture oracle-groups PASSED closing db oracle ====================================== 6 passed in 0.01 seconds ======================================= 

мы видим, что это работает.

Во всяком случае, есть одна небольшая проблема – область « db_connect » «сеанс» не выполняется, и она создается и уничтожается на уровне функции. Это известная проблема .

  • Дженкинс: связь между Stacktrace и GitLab
  • Запуск py.test от emacs
  • Как определить, прошел или не прошел тест, изучив объект Item, переданный в pytest_runtest_teardown?
  • Порядок выполнения тестового примера в pytest
  • pytest: как передать параметр класса в setup_class
  • Управление протоколом py.test
  • Как и где py.test находит светильники
  • Проверка допустимых типов перечислений из protobufs
  • Проверить, выполняется ли код из сеанса py.test
  • Pytest - привязка к функциональному уровню
  • Выполнение тестовых функций pytest внутри ноутбука jupyter
  • Python - лучший язык программирования в мире.