1

I have the following as conftest.py -->

def pytest_addoption(parser):
    parser.addoption("--browser")
    parser.addoption("--osType", help="Type of operating system")
    parser.addoption("--hostURL", action="store", help="prod, stage, or dev")

@pytest.fixture(scope="session")
def browser(request):
    return request.config.getoption("--browser")

@pytest.fixture(scope="session")
def osType(request):
    return request.config.getoption("--osType")

@pytest.fixture(autouse=True)
def hostURL(request):
    return request.config.getoption("--hostURL")

I would like to use the --hostURL flag to pass in value such as prod, stage or dev.

Here's how my test_TheMainTest.py looks -->

import unitest
import pytest

class CheckStatusCodeTest(unittest.TestCase, LoginPage, CustomSeleniumDriver):

    def test_CheckStatusCodeOfPages(self, hostURL):
        self.login(hostURL)

When I run the above test using pytest -q -s --hostURL prod I get the following error -->

   TypeError: test_CheckStatusCodeOfCRPages() missing 1 required positional argument: 'hostURL'
Ash
  • 67
  • 1
  • 2
  • 9

1 Answers1

2

Quoting the docs:

Note

unittest.TestCase methods cannot directly receive fixture arguments as implementing that is likely to inflict on the ability to run general unittest.TestCase test suites.

However, you can still pass regular fixture values to unittest-style tests using autouse fixtures:

class CheckStatusCodeTest(unittest.TestCase):

    @pytest.fixture(autouse=True)
    def _pass_fixture_value(self, hostURL):
        self._hostURL = hostURL

    def test_CheckStatusCodeOfPages(self):
        assert self._hostURL

You can also check out this answer of mine tackling the same issue for more examples.

Another possibility is to implement an autouse fixture that modifies the test class explicitly. This is useful if you have lots of test classes that should have the identical setup:

@pytest.fixture(scope="class")
def set_fixture_value_to_class(request, hostURL):
    request.cls._hostURL = hostURL


@pytest.mark.usefixtures('set_fixture_value_to_class')
class CheckStatusCodeTest(unittest.TestCase):

    def test_CheckStatusCodeOfPages(self):
        assert self._hostURL


@pytest.mark.usefixtures('set_fixture_value_to_class')
class AnotherTest(unittest.TestCase):

    def test_spam(self):
        assert self._hostURL

In this case, no need to copy the same fixture to each test class. Just mark all relevant test classes and you're good to go.

Community
  • 1
  • 1
hoefling
  • 59,418
  • 12
  • 147
  • 194
  • Glad I could help! – hoefling Jan 03 '19 at 22:30
  • quick question.. I'm trying to access that hostURL as a command line args. Will your solution help me do that? – Ash Jan 04 '19 at 15:58
  • Shouldn't be an issue, just include `request` in the fixture parameters and get the value via `request.config.getoption("--hostURL")`, like you're already doing it in your original code. Or do you have another problem with that? – hoefling Jan 04 '19 at 16:02
  • so in the conftest.py I've added this --> `@pytest.fixture(autouse=True) def heyheyhey(request): return request.config.getoption("--hostURL")` and in my test_MainTest.py I have --> `class CheckStatusCodeTest(unittest.TestCase, CheckStatusCode, LoginPage): def test_CheckStatusCodeOfCRPages(self, heyheyhey): self.login(heyheyhey)` I'm still getting the `missing 1 required positional argument: 'heyheyhey'` error. @hoefling – Ash Jan 04 '19 at 16:12
  • I've updated the codebase above in the original post @hoefling – Ash Jan 04 '19 at 16:30
  • Check out the answer again - you can't pass fixtures to unittest methods. `def test_CheckStatusCodeOfCRPages(self, heyheyhey)` is not allowed. Define an autouse fixture that sets `self.heyheyhey = heyheyhey` which you can then use in test methods. – hoefling Jan 04 '19 at 16:40
  • I'm an idiot!! Sorry dude. It's working now. I will update the original post. THANK YOU!! – Ash Jan 04 '19 at 16:47