Make 'browser_name' parameter indirect#284
Conversation
|
9b912a3 to
4ac040c
Compare
| def pytest_generate_tests(metafunc: Any) -> None: | ||
| if "browser_name" in metafunc.fixturenames: | ||
| browsers = metafunc.config.option.browser or ["chromium"] | ||
| metafunc.parametrize("browser_name", browsers, scope="session") | ||
| metafunc.parametrize("browser_name", browsers, scope="session", indirect=True) |
There was a problem hiding this comment.
If check the browser_name in metafuc.params the browser_name can support get browser from marker.parametrize of testcase. Such as the code:
| def pytest_generate_tests(metafunc: Any) -> None: | |
| if "browser_name" in metafunc.fixturenames: | |
| browsers = metafunc.config.option.browser or ["chromium"] | |
| metafunc.parametrize("browser_name", browsers, scope="session") | |
| metafunc.parametrize("browser_name", browsers, scope="session", indirect=True) | |
| def pytest_generate_tests(metafunc: Any) -> None: | |
| if "browser_name" in metafunc.fixturenames: | |
| browsers = metafunc.config.option.browser or ["chromium"] | |
| if hasattr(metafunc, "params") and "browser_name" not in metafunc.params: | |
| metafunc.parametrize("browser_name", browsers, scope="session") |
And the fixture browser_name changes is not required.
There was a problem hiding this comment.
I think that, in this case, it should better be:
if "browser_name" not in getattr(metafunc, "params", {}):
metafunc.parametrize("browser_name", browsers, scope="session")Because, I've seen that "params" could not be present if not parameters have been defined yet and "brower_name" parametrization is not added then.
But, apart from that, how does this fix the problem? Tests are still wrongly sorted with this change:
pytest --browser chromium --browser firefox
tests/gui_e2e/my_tests/test_a.py::test_aa[chromium-case_1] PASSED [ 6%]
tests/gui_e2e/my_tests/test_a.py::test_ab[chromium-case_1] PASSED [ 12%]
tests/gui_e2e/my_tests/test_b.py::test_ba[chromium-case_1] PASSED [ 18%]
tests/gui_e2e/my_tests/test_b.py::test_bb[chromium-case_1] PASSED [ 25%]
tests/gui_e2e/my_tests/test_a.py::test_aa[chromium-case_2] PASSED [ 31%]
tests/gui_e2e/my_tests/test_a.py::test_ab[chromium-case_2] PASSED [ 37%]
tests/gui_e2e/my_tests/test_b.py::test_ba[chromium-case_2] PASSED [ 43%]
tests/gui_e2e/my_tests/test_b.py::test_bb[chromium-case_2] PASSED [ 50%]
tests/gui_e2e/my_tests/test_a.py::test_aa[firefox-case_1] PASSED [ 56%]
tests/gui_e2e/my_tests/test_a.py::test_ab[firefox-case_1] PASSED [ 62%]
tests/gui_e2e/my_tests/test_b.py::test_ba[firefox-case_1] PASSED [ 68%]
tests/gui_e2e/my_tests/test_b.py::test_bb[firefox-case_1] PASSED [ 75%]
tests/gui_e2e/my_tests/test_a.py::test_aa[firefox-case_2] PASSED [ 81%]
tests/gui_e2e/my_tests/test_a.py::test_ab[firefox-case_2] PASSED [ 87%]
tests/gui_e2e/my_tests/test_b.py::test_ba[firefox-case_2] PASSED [ 93%]
tests/gui_e2e/my_tests/test_b.py::test_bb[firefox-case_2] PASSED [100%]
There was a problem hiding this comment.
My suggestion does not keep the indirect=Ture.
There was a problem hiding this comment.
I see, but then it does not fix the sorting problem
There was a problem hiding this comment.
Do you mean using this?
@pytest.hookimpl(trylast=True)
def pytest_generate_tests(metafunc: Any) -> None:
if "browser_name" in metafunc.fixturenames:
browsers = metafunc.config.option.browser or ["chromium"]
metafunc.parametrize("browser_name", browsers, scope="session")The order is even worse:
pytest --browser chromium --browser firefox
my_tests/test_a.py::test_aa[case_1-chromium] PASSED [ 6%]
my_tests/test_a.py::test_ab[case_1-chromium] PASSED [ 12%]
my_tests/test_b.py::test_ba[case_1-chromium] PASSED [ 18%]
my_tests/test_b.py::test_bb[case_1-chromium] PASSED [ 25%]
my_tests/test_a.py::test_aa[case_1-firefox] PASSED [ 31%]
my_tests/test_a.py::test_ab[case_1-firefox] PASSED [ 37%]
my_tests/test_b.py::test_ba[case_1-firefox] PASSED [ 43%]
my_tests/test_b.py::test_bb[case_1-firefox] PASSED [ 50%]
my_tests/test_a.py::test_aa[case_2-chromium] PASSED [ 56%]
my_tests/test_a.py::test_ab[case_2-chromium] PASSED [ 62%]
my_tests/test_b.py::test_ba[case_2-chromium] PASSED [ 68%]
my_tests/test_b.py::test_bb[case_2-chromium] PASSED [ 75%]
my_tests/test_a.py::test_aa[case_2-firefox] PASSED [ 81%]
my_tests/test_a.py::test_ab[case_2-firefox] PASSED [ 87%]
my_tests/test_b.py::test_ba[case_2-firefox] PASSED [ 93%]
my_tests/test_b.py::test_bb[case_2-firefox] PASSED [100%]
There was a problem hiding this comment.
Can you apply the changes about browser_name first? We need set browser_name list for part cases not all.
if "browser_name" not in getattr(metafunc, "params", {}):
metafunc.parametrize("browser_name", browsers, scope="session")There was a problem hiding this comment.
Do you mean this?
@pytest.hookimpl(trylast=True)
def pytest_generate_tests(metafunc: Any) -> None:
if "browser_name" in metafunc.fixturenames and "browser_name" not in getattr(metafunc, "params", {}):
browsers = metafunc.config.option.browser or ["chromium"]
metafunc.parametrize("browser_name", browsers, scope="session")It is the same than in the previous case:
pytest --browser chromium --browser firefox
my_tests/test_a.py::test_aa[case_1-chromium] PASSED [ 6%]
my_tests/test_a.py::test_ab[case_1-chromium] PASSED [ 12%]
my_tests/test_b.py::test_ba[case_1-chromium] PASSED [ 18%]
my_tests/test_b.py::test_bb[case_1-chromium] PASSED [ 25%]
my_tests/test_a.py::test_aa[case_1-firefox] PASSED [ 31%]
my_tests/test_a.py::test_ab[case_1-firefox] PASSED [ 37%]
my_tests/test_b.py::test_ba[case_1-firefox] PASSED [ 43%]
my_tests/test_b.py::test_bb[case_1-firefox] PASSED [ 50%]
my_tests/test_a.py::test_aa[case_2-chromium] PASSED [ 56%]
my_tests/test_a.py::test_ab[case_2-chromium] PASSED [ 62%]
my_tests/test_b.py::test_ba[case_2-chromium] PASSED [ 68%]
my_tests/test_b.py::test_bb[case_2-chromium] PASSED [ 75%]
my_tests/test_a.py::test_aa[case_2-firefox] PASSED [ 81%]
my_tests/test_a.py::test_ab[case_2-firefox] PASSED [ 87%]
my_tests/test_b.py::test_ba[case_2-firefox] PASSED [ 93%]
my_tests/test_b.py::test_bb[case_2-firefox] PASSED [100%]
Fixes #195.
Using
"browser_name"as an indirect parameter, pytest keeps the original order of the tests.Without pytest-playwright:
With pytest-playwright before the fix:
With pytest-playwright after the fix: