user4794170
user4794170

Reputation: 213

py.test conftest - Modify Fixture Parameter Based on sys.argv

I have a working pytest environment for Selenium testing. I use a parameterized fixture in conftest.py that allows me to test all the different browsers without having to rewrite the test. I'd like to pass a command line argument to my script so that I can have it run only a specific browser, rather than all of them. To do this, I would need to modify the variables passed into my fixture. So far, I haven't been able to figure out how to do this. My example below doesn't work, likely because pytest parses the conftest.py seperately from the variable my startup script describes.

#conftest.py
browsers = { "ff" : webdriver.Firefox, "ie" : webdriver.Ie }
@pytest.yield_fixture(params=browsers.keys())
def browser(request):
    driver = browsers[request.param]()
    yield driver
    driver.quit()

#test_simple.py
def test_simple(browser):
    browser.get("http://stackoverflow.com")

#main.py
browsers = {}
if __name__ == "__main__":
    if len(sys.argv) > 1:
        for arg in sys.argv[1:]:
            if arg == "-ff":
                browsers = { "ff" : webdriver.Firefox }
            elif arg == "-ie":
                browsers = { "ie" : webdriver.Ie }
            elif arg == "-all":
                browsers = { "ff" : webdriver.Firefox, "ie" : webdriver.Ie }

    pytest.main()

How can I pass values to a parameterized fixture in conftest.py?


Upvotes: 2

Views: 2658

Answers (3)

Sachinlionel
Sachinlionel

Reputation: 75

 pytest -k test_simple['ie'] 

Above line will selectively run matched test

Upvotes: 0

Bruno Oliveira
Bruno Oliveira

Reputation: 15255

See: Pass different values to a test function, depending on command line options.

You can't actually change parametrization using command-line options because parametrization definition occurs during import, but you can easily skip tests for other browsers if the user specifies one in the command line:

# conftest.py
import pytest

browsers = {"ff": 'FIREFOX', 'ie': 'INTERNETEXPLORER'}

def pytest_addoption(parser):
    parser.addoption("--browser", default='',
        type='choice', choices=sorted(browsers),
        help="runs tests only for given browser")    

@pytest.yield_fixture(params=browsers.keys())
def browser(request):
    selected = request.config.getoption('browser')
    if selected and selected != request.param:
        pytest.skip('browser {} selected in the command line'.format(selected))
    driver = browsers[request.param]
    yield driver

With this, when the user runs pytest without passing any value to --browser, all tests run as usual:

============================= test session starts =============================
platform win32 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.7.0.dev1 -- X:\temp\sandbox\.env27\Scripts\python.exe
plugins: xdist
collecting ... collected 2 items

test_simple.py::test_simple[ie] PASSED
test_simple.py::test_simple[ff] PASSED

========================== 2 passed in 0.01 seconds ===========================

But if the user for example passes --browser=ie, firefox tests are then skipped:

============================= test session starts =============================
platform win32 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.7.0.dev1 -- X:\temp\sandbox\.env27\Scripts\python.exe
plugins: xdist
collecting ... collected 2 items

test_simple.py::test_simple[ie] PASSED
test_simple.py::test_simple[ff] SKIPPED

===================== 1 passed, 1 skipped in 0.01 seconds =====================

Upvotes: 1

Stan
Stan

Reputation: 3461

Just use ENV variables:

#conftest.py
browsers = { "ff" : webdriver.Firefox, "ie" : webdriver.Ie }
@pytest.yield_fixture(params=browsers.keys())
def browser(request):
    driver = browsers[request.param]()
    yield driver
    driver.quit()

#test_simple.py
def test_simple(browser):
    browser.get("http://stackoverflow.com")

#main.py
browsers = {}
browserToRun = os.environ.get('BROWSER_TO_RUN')
if __name__ == "__main__":
            if browserToRun == "ff":
                browsers = { "ff" : webdriver.Firefox }
            elif browserToRun == "ie":
                browsers = { "ie" : webdriver.Ie }
            elif browserToRun == "all":
                browsers = { "ff" : webdriver.Firefox, "ie" : webdriver.Ie }

    pytest.main()

and run tests like:

BROWSER_TO_RUN=ff run_tests.py

Upvotes: 1

Related Questions