There is a set of UI tests in one class:
class TestMainPage(object): login = 'login' password = 'password'
def test_open_site(self, browser, url):
"""Opening browser and go to website"""
browser.go_to_site(url)
browser.check_open_auth_page()
def test_authorisation(self, browser):
"""Аuthorization on the website"""
browser.authorisation(login=self.login, password=self.password)
...
How do I run this class with different parameters for one test session in turn? Parameterization of the function is not suitable, since this test will be performed independently and only after that it will move on to the next test
I found this solution:
my_list = [1,2,3]
@pytest.fixture(scope="session", params=my_list)
def my_params(request):
return request.param
class Test_suite:
def test_1(self, my_params):
assert 1==1
def test_2(self, my_params, ):
assert 1 == 1
def test_3(self, my_params, ):
assert 1 == 1
It is executed alternately, which is what I need:
test.py::Test_suite::test_1[1]
test.py::Test_suite::test_2[1]
test.py::Test_suite::test_3[1]
test.py::Test_suite::test_1[2]
test.py::Test_suite::test_2[2]
test.py::Test_suite::test_1[3]
test.py::Test_suite::test_2[3]
test.py::Test_suite::test_3[3]
But when the second parameter is added, chaos begins(actual result):
test.py::Test_suite::test_1[1] PASSED
test.py::Test_suite::test_2[1-1] PASSED
test.py::Test_suite::test_3[1-1] PASSED
test.py::Test_suite::test_2[2-1] PASSED
test.py::Test_suite::test_3[2-1] PASSED
test.py::Test_suite::test_1[2] PASSED
test.py::Test_suite::test_2[2-2] PASSED
test.py::Test_suite::test_3[2-2] PASSED
test.py::Test_suite::test_2[1-2] PASSED
test.py::Test_suite::test_3[1-2] PASSED
test.py::Test_suite::test_2[3-2] PASSED
test.py::Test_suite::test_3[3-2] PASSED
test.py::Test_suite::test_2[3-1] PASSED
test.py::Test_suite::test_3[3-1] PASSED
test.py::Test_suite::test_1[3] PASSED
test.py::Test_suite::test_2[3-3] PASSED
...
I also need a conclusion in order (expected result):
test.py::Test_suite::test_1[1] PASSED
test.py::Test_suite::test_2[1-1] PASSED
test.py::Test_suite::test_3[1-1] PASSED
test.py::Test_suite::test_2[1-2] PASSED
test.py::Test_suite::test_3[1-2] PASSED
test.py::Test_suite::test_2[1-3] PASSED
test.py::Test_suite::test_3[1-3] PASSED
test.py::Test_suite::test_2[1-4] PASSED
test.py::Test_suite::test_3[1-4] PASSED
test.py::Test_suite::test_2[1-5] PASSED
test.py::Test_suite::test_3[1-5] PASSED
test.py::Test_suite::test_1[2] PASSED
test.py::Test_suite::test_2[2-1] PASSED
test.py::Test_suite::test_3[2-1] PASSED
And further. How to implement it?
Used script with two variables:
my_list = [1,2,3]
my_list_two = [1,2,3,4,5]
@pytest.fixture(scope="session", params=my_list)
def my_params(request):
return request.param
@pytest.fixture(scope="session", params=my_list_two)
def my_params_two(request):
return request.param
class Test_suite:
def test_1(self, my_params):
assert 1==1
def test_2(self, my_params, my_params_two):
assert 1 == 1
def test_3(self, my_params, my_params_two):
assert 1 == 1
CodePudding user response:
A quick google search will lead you to this ticket where some workarounds are outlined, on of which is moving the scope of one fixture (see below) or using some pytest_modify_collection hook but it seems like the problem you ran into is still an open issue
import pytest
LOGINS = ["l1", "l2", "l3"]
PASSWORDS = ["p1", "p2", "p3", "p4", "p5"]
@pytest.fixture(scope="session", params=LOGINS)
def logins(request):
return request.param
@pytest.fixture(scope="module", params=PASSWORDS)
def passwords(request):
return request.param
def test_one(logins):
pass
def test_two(logins, passwords):
pass
CodePudding user response:
In this particular case, if you change the scope of your fixtures to function
, you'll get the result you want:
import pytest
my_list = [1, 2, 3]
my_list_two = [1, 2, 3, 4, 5]
@pytest.fixture(params=my_list)
def my_params(request):
return request.param
@pytest.fixture(params=my_list_two)
def my_params_two(request):
return request.param
class TestSuite:
def test_1(self, my_params):
assert 1 == 1
def test_2(self, my_params, my_params_two):
assert 1 == 1
def test_3(self, my_params, my_params_two):
assert 1 == 1
test_suite.py::TestSuite::test_1[1] PASSED [ 3%]
test_suite.py::TestSuite::test_1[2] PASSED [ 6%]
test_suite.py::TestSuite::test_1[3] PASSED [ 9%]
test_suite.py::TestSuite::test_2[1-1] PASSED [ 12%]
test_suite.py::TestSuite::test_2[1-2] PASSED [ 15%]
test_suite.py::TestSuite::test_2[1-3] PASSED [ 18%]
test_suite.py::TestSuite::test_2[1-4] PASSED [ 21%]
test_suite.py::TestSuite::test_2[1-5] PASSED [ 24%]
test_suite.py::TestSuite::test_2[2-1] PASSED [ 27%]
test_suite.py::TestSuite::test_2[2-2] PASSED [ 30%]
test_suite.py::TestSuite::test_2[2-3] PASSED [ 33%]
test_suite.py::TestSuite::test_2[2-4] PASSED [ 36%]
test_suite.py::TestSuite::test_2[2-5] PASSED [ 39%]
test_suite.py::TestSuite::test_2[3-1] PASSED [ 42%]
test_suite.py::TestSuite::test_2[3-2] PASSED [ 45%]
test_suite.py::TestSuite::test_2[3-3] PASSED [ 48%]
test_suite.py::TestSuite::test_2[3-4] PASSED [ 51%]
test_suite.py::TestSuite::test_2[3-5] PASSED [ 54%]
test_suite.py::TestSuite::test_3[1-1] PASSED [ 57%]
test_suite.py::TestSuite::test_3[1-2] PASSED [ 60%]
test_suite.py::TestSuite::test_3[1-3] PASSED [ 63%]
test_suite.py::TestSuite::test_3[1-4] PASSED [ 66%]
test_suite.py::TestSuite::test_3[1-5] PASSED [ 69%]
test_suite.py::TestSuite::test_3[2-1] PASSED [ 72%]
test_suite.py::TestSuite::test_3[2-2] PASSED [ 75%]
test_suite.py::TestSuite::test_3[2-3] PASSED [ 78%]
test_suite.py::TestSuite::test_3[2-4] PASSED [ 81%]
test_suite.py::TestSuite::test_3[2-5] PASSED [ 84%]
test_suite.py::TestSuite::test_3[3-1] PASSED [ 87%]
test_suite.py::TestSuite::test_3[3-2] PASSED [ 90%]
test_suite.py::TestSuite::test_3[3-3] PASSED [ 93%]
test_suite.py::TestSuite::test_3[3-4] PASSED [ 96%]
test_suite.py::TestSuite::test_3[3-5] PASSED [100%]
Please refer to the documentation for more information on how fixtures are ordered.
CodePudding user response:
As it turned out, this problem has not been solved at the moment. The only (not official) the solution to this problem is to use priority parameters. This functionality is implemented in the pytest-param-priority library pytest-param-priority :
import pytest
import time
from pytest_param_priority import parameter_priority
@parameter_priority(0)
@pytest.fixture(scope="module", params=[1, 2, 3])
def number(request):
return request.param
@parameter_priority(2)
@pytest.fixture(scope="module", params=["a", "b", "c"])
def letter(request):
return request.param
@pytest.fixture(scope="module")
def my_expensive_setup_fixture(letter, number):
time.sleep(1)
@parameter_priority(1)
@pytest.fixture(scope="module", params=["red", "green", "blue"])
def color(request):
return request.param
@pytest.fixture(scope="module")
def intermediate_step(color, my_expensive_setup_fixture):
pass
def test_one(intermediate_step):
pass
def test_two(intermediate_step):
pass
Managing the priority to set up tests is no longer a problem
I will try to implement a similar system and test what will come out of it. A little later, I will add a solution specifically for my code, maybe it will be useful to someone