Passing command line arguments in python by pytest

Your pytest <filename>.py arg1 command is trying to call pytest on two modules <filename>.py and arg1 , But there is no module arg1.

If you want to pass some argument before running pytest then run the pytest from a python script after extracting your variable.

As others suggested though you would probably want to parameterize your tests in some other way, Try:Parameterized pytest.

# run.py
import pytest
import sys

def main():
    # extract your arg here
    print('Extracted arg is ==> %s' % sys.argv[2])
    pytest.main([sys.argv[1]])

if __name__ == '__main__':
    main()

call this using python run.py filename.py arg1


Here's the method I just cooked up from reading the parameterized pytest docs and hacking for a while... I don't know how stable or good it is going to be overall since I just got it working. I did however check that HTML coverage generation works with this method.

  • add a file to your test directory for configuring the command-line args you want to pass:
    • tests\conftest.py
# this is just so we can pass --server and --port from the pytest command-line
def pytest_addoption(parser):
    ''' attaches optional cmd-line args to the pytest machinery '''
    parser.addoption("--server", action="append", default=[], help="real server hostname/IP")
    parser.addoption("--port", action="append", default=[], help="real server port number")
  • and then add a test file, with this special pytest_generate_tests function which is called when collecting a test function
    • tests\test_junk.py
def pytest_generate_tests(metafunc):
    ''' just to attach the cmd-line args to a test-class that needs them '''
    server_from_cmd_line = metafunc.config.getoption("server")
    port_from_cmd_line = metafunc.config.getoption("port")
    print('command line passed for --server ({})'.format(server_from_cmd_line))
    print('command line passed for --port ({})'.format(port_from_cmd_line))
    # check if this function is in a test-class that needs the cmd-line args
    if server_from_cmd_line and port_from_cmd_line and hasattr(metafunc.cls, 'real_server'):
        # now set the cmd-line args to the test class
        metafunc.cls.real_server = server_from_cmd_line[0]
        metafunc.cls.real_port = int(port_from_cmd_line[0])


class TestServerCode(object):
    ''' test-class that might benefit from optional cmd-line args '''
    real_server=None
    real_port = None

    def test_valid_string(self):
        assert self.real_server!=None
        assert self.real_port!=None

    def test_other(self):
        from mypackage import my_server_code
        if self.real_server !=  None:
            assert "couldn\'t find host" not in my_server_code.version(self.real_server, self.real_port)
  • then run (with HTML coverage, for example) with:

    • pytest tests\test_junk.py --server="abc" --port=123 --cov-report html --cov=mypackage

Tags:

Python