Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest exception none type object is not callable

Tags:

In test1.py I have below code

@pytest.fixture(scope="session")
def moduleSetup(request):
    module_setup = Module_Setup()
    request.addfinalizer(module_setup.teardown())
    return module_setup

def test_1(moduleSetup):
    print moduleSetup
    print '...'
    #assert 0

# def test_2(moduleSetup):
#     print moduleSetup
#     print '...'
#     #assert 0

And in conftest.py I have

class Module_Setup:
    def __init__(self):
        self.driver = webdriver.Firefox()

    def teardown(self):
        self.driver.close()

When I run it launches and closes browser.

But I also get error self = <CallInfo when='teardown' exception: 'NoneType' object is not callable>, func = <function <lambda> at 0x104580488>, when = 'teardown'

Also If I want to run both tests test_1 and test_2 with same driver object I need to use scope module or session?

like image 460
user2661518 Avatar asked May 03 '16 16:05

user2661518


1 Answers

Regarding the exception

When using request.addfinalizer(), you shall pass in reference to a function.

Your code is passing result of calling that function.

request.addfinalizer(module_setup.teardown())

You shall call it this way:

request.addfinalizer(module_setup.teardown)

Regarding fixture scope

If your fixture allows reuse across multiple test calls, use "session" scope. If it allows reuse only for tests in one module, use "module" scope.

Alternative fixture solution

The way you use the fixtures is not much in pytest style, it rather resembles unittest.

From the code you show it seems, the only think you need is to have running Firefox with driver allowing to use it in your tests, and after being done, you need to close it.

This can be accomplished by single fixture:

@pytest.fixture(scope="session")
def firefox(request):
    driver = webdriver.Firefox()
    def fin():
        driver.close()
    request.addfinalizer(fin)

or even better using @pytest.yield_fixture

@pytest.yield_fixture(scope="session")
def firefox(request):
    driver = webdriver.Firefox()
    yield driver
    driver.close()

The yield is place, where fixture stops executing, yields the created value (driver) to test cases.

After the tests are over (or better, when the scope of our fixture is over), it continues running the instructions following the yield and does the cleanup work.

In all cases, you may then modify your test cases as follows:

def test_1(firefox):
    print moduleSetup
    print '...'

and the moduleSetup fixture becomes completely obsolete.

like image 57
Jan Vlcinsky Avatar answered Sep 28 '22 03:09

Jan Vlcinsky