TestProject Forum

Driver.quit test_methods

Hi all

I have a framework that uses python / pytest and I am having an issue with the test project reports.

I use the Page Object Model with a one-time set up fixture in Conftest which grabs the driver from a Webdriver file and passes this into the test Class.

The test class has multiple tests within it.

When I run the test and report this on TestProject, it only shows 1 test with all the steps of all the test methods in that class.
I was under the impression that Test Project reports a test on the driver.quit command so this sort of makes sense but I was also under the impression that it was clever enough to identify when a test_method name changes and then also report this individually as a separate test.

I don’t really want to have to quit the driver at the end of each test method and grab a new instance for each test method as this would slow my tests down quite a bit but I was wondering what is the best around this issue?

Thanks

Hello @marklane2001

Can you please provide a code example?

My conftest file has the follwoing fixture in it:

@pytest.fixture(scope="class")
def oneTimeSetUp(request, browser):
    print("Running one time setUp")
    wdf = WebDriverFactory(browser)
    driver = wdf.getWebDriverInstance()

My Webdriver file takes a config of browser type and then just grabs the driver instance from TestProject and passes back to the fixture:

from src.testproject.sdk.drivers import webdriver

class WebDriverFactory:

    def __init__(self, browser):

        self.browser = browser

    def getWebDriverInstance(self):

        baseURL = "https://somewhere"
        if self.browser == "iexplorer":
            # Set ie driver
            driver = webdriver.Ie()
        elif self.browser == "firefox":
            driver = webdriver.Firefox()
        elif self.browser == "chrome":
            # Set chrome driver
            driver = webdriver.Chrome
driver.get(baseURL)
return driver

And then my test file takes the set up fixture in he class and I have multiple test methods within that class:

@pytest.mark.usefixtures("oneTimeSetUp", "setUp")
class LoginTests(unittest.TestCase):

    @pytest.fixture(autouse=True)
    def classSetup(self, oneTimeSetUp):
        self.lp = LoginPage(self.driver)
        self.hp = HomePage(self.driver)

    def test_method1
          test stuff

    def test_method2
         test some more stuff 

etc

Thanks, so you say in your report you see test_method2 and test_method1 under the same test in the report or under the same Job just different tests?

Please do share the report if you can so I can see exactly the issue.

Yes of course, how do I upload a file as I can’t seem to see there is an option to do this?

The below screenshot of the generated report - I passed in the project and job name but the name of the test seems to be the Test Class Name where all the test methods are stored. All the steps in the report are a total of all the steps in all of the test methods. These all currently use the same Driver object.

Thanks, so you run both tests in sequence without a quit in between correct?

If you add the quit after each test, the report is generated correctly?

Yes, if I run the whole file then I would expect Test Project to pick up each of the methods to report a test for each but it is just reporting the Test Class as a whole.

I can’t add driver.quit after each method as the driver instance is passed in once for the class. If I driver.quit after each method then the first method will run and then all others will fail due to the driver object being quit

You can try to change your fixture:

@pytest.fixture(scope="class")
def oneTimeSetUp(request, browser):
    print("Running one time setUp")
    wdf = WebDriverFactory(browser)
    driver = wdf.getWebDriverInstance()
    yield driver
    driver.quit()

and your methods can take the driver as an instance parameter

def test_method1(driver)
      test stuff

Give it a try and let me know how it process the report.

Just an FYI, our example tests are built as POM as well:

I removed the fixture scope so it defaulted to function so the fixture is destroyed at the end of the test ie driver.quit was called on the teardown of each test. The report did show a run for each test but it still used the test class name for each test name.

Also, it did slow the test run down as it needed to load a new browser for each test

Okay then, I will check it out and get back to you.

Thanks again for all your help so far

Hello @marklane2001
I have applied the same code structure as you have, and indeed it took the test names from the class instead of the name of the test, I have applied a fix and will push it soon.

Just note, you still need to apply a teardown hook to report the final test, all tests will be reported correctly like so, once you apply a teardown hook in your test (the shutdown needs to happen only once, after all tests have finished executing, so it won’t slow down the test execution):

Teardown hook example:

import pytest
from webdriver_facotry import WebDriverFactory


@pytest.fixture(scope="class")
def driver(request):
    print("Started running, setting up driver one time..")
    factory = WebDriverFactory("chrome")
    driver = factory.get_webdriver_instance()
    request.cls.driver = driver
    yield driver
    driver.quit()

Tests:

@pytest.mark.usefixtures("driver")
class DemoTests(unittest.TestCase):

    @pytest.fixture(autouse=True)
    def classSetup(self, driver):
        self.login_page = LoginPage(driver)
        self.profile_page = ProfilePage(driver)
        self.driver = driver

    def test_1(self):
        self.login_page.open().login_as("Test 1", "12345")
        assert self.profile_page.greetings_are_displayed() is True

    def test_2(self):
        self.login_page.open().login_as("Test 2", "12345")
        assert self.profile_page.greetings_are_displayed() is True

    def test_3(self):
        self.login_page.open().login_as("Test 3", "12345")
        assert self.profile_page.greetings_are_displayed() is True

Here is the issue:

Many thanks for your reply. I do have a teardown hook currently on the conftest :

@pytest.fixture(scope="class")
def oneTimeSetUp(request, browser):
    print("Running one time setUp")
    wdf = WebDriverFactory(browser)
    driver = wdf.getWebDriverInstance()

    if request.cls is not None:
        request.cls.driver = driver
    yield driver
    driver.quit()
    print("Running one time tearDown")

I assume that this is fine in the conftest rather than the Test Page itself as this gets called each time a new Test Class is started?

Did you say that your fix will be pushed in today?

Thanks again
Mark

Your conftest is fine, the fix is up on testPypi so you can give it a try.
Run:
pip install -i https://test.pypi.org/simple/ testproject-python-sdk==1.0.0.dev11

Thanks. Do I just need to pip install this? Do I need to change anything else SDK / Project wise?

That is all, just install that version and run your tests.

Worked perfectly. Thanks so much

Happy to help :slight_smile:

Feel free to reach out on Github as well for any further questions.