1

I have hundreds of test scripts that I am adding to a pytest framework I'm creating. Each script needs to open a connection to our device being tested, run a number of tasks and close. The connection is being created and closed via a fixture. Also want to add that a new connection needs to be made for each individual script that runs (i.e. module level and not scope or function level).

I have this working with a fixture in the same file as the tasks. Something like this.

my_test.py

...
@pytest.fixture(scope='module')
def setup(request):
    global connection
    with target.Connect() as connection:
        yield connection

    def teardown():
        connection.close
    request.addfinalizer(teardown)

@pytest.mark.usefixtures("setup")
def test_query_device_info():
    global connection
    connection.write('echo $PATH')
    connection.write('echo $HOME')
    ...

As I have hundreds of tests I don't want to replicate this same code for each file so I need a common fixture that can be used by every test. I've tried adding this fixture to conftest.py and the connection is being created but fails when it gets to the connection.write command.

conftest.py

...
@pytest.fixture
def setup(request):
    global connection
    with target.Connect() as connection:
        yield connection

    def teardown():
        connection.close
    request.addfinalizer(teardown)

my_test.py

...
@pytest.mark.usefixtures("setup")
def test_query_device_info():
    global connection
    connection.write('echo $PATH')

How can I have this fixture in a common location that is accessible to all my tests and properly creates a connection that I can use in my scripts?

Note that these are being executed though the pyCharm IDE and not directly on the command line.

Jason Templeman
  • 431
  • 5
  • 21
  • Have you considered putting the tests into a class with `setup_method` and `teardown_method`? – Klaus D. Sep 20 '18 at 17:57
  • Yes but was having some troubles with the certain tasks we are running and with hundreds of files I would want a common setup and teardown. – Jason Templeman Sep 20 '18 at 18:37
  • Why not just pass `setup` fixture as a test parameter? `def test_query_device_info(setup): setup.write('echo $PATH')` etc. – hoefling Sep 20 '18 at 21:20
  • That would work but my example may be too simplistic. We may have dozens of functions that we will be executing as part of our tests all using the same connection therefore I need this to run at the module level and not the function level. – Jason Templeman Sep 21 '18 at 12:03
  • When you say `run at module level` do you mean running your code just one time? A session/module scoped fixture does not fit? – José María Sep 27 '18 at 03:12
  • By module_level I mean it needs to run one time per each "test". We have 100 "tests" called test_1.py > test_100.py and each "test" performs dozens of different tasks. I need to do the following when I run our suite of 100 tests. For each test we: create a connection, execute all the tasks within that test, close the connection then run the next test. This sequence is performed 100 times, once for each test. We cannot make a connection, run all 100 tests then close the connection (session_level). – Jason Templeman Sep 27 '18 at 17:24
  • Use pytest_collection_modifyitems and you can modify the function to do what you need to do – rottweilers_anonymous May 17 '19 at 22:18

1 Answers1

0

The framework was reworked to that the connection was done through a class that uses the __enter__ and __exit__ methods which control the context automatically.

Jason Templeman
  • 431
  • 5
  • 21
  • What does this mean exactly? – Minix Jan 21 '21 at 00:01
  • It's been awhile since I worked on this and have moved on from this type if work but basically, we were using a context with x as y: do something within the context do something else outside the context We wanted to do something with classes and I found 2 method (listed) that handle this. When you run with "class" it executes evertyhing in the __enter__ method and when the context is closed it executes everything in the __exit__ method. You can see a good example/answer here https://stackoverflow.com/questions/1984325/explaining-pythons-enter-and-exit – Jason Templeman Feb 02 '21 at 16:22