3

I have a python file with some code and simple tests on that code.

I would like to invoke pytest from that python file, have it collect only the tests in that file, and run them.

For example, foo.py:

# ... various code above...

def test_foo():
    foo = Foo()
    assert foo()

def test_bar():
    bar = Bar()
    assert bar.baz

if __name__ == '__main__':
    import pytest
    pytest.main()

I now would like to run python foo.py and have pytest run the two tests in that file, and those tests only.

However, when I run python foo.py, pytest collects ALL tests from all modules that are rooted from the path in which I ran the command.

How can I run python foo.py and have the pytest.main() invoked in foo.py only call the tests in foo.py and no others?

Alnitak
  • 2,068
  • 2
  • 12
  • 24
  • You usually call `pytest` directly, without using `pytest.main()`. So just calling `pytest foo.py` should do what you need. `pytest.main` does the same as calling `pytest` from the command line, e.g. collects all tests it finds and runs them - it is not used like `unittest.main()` and is usually not needed (see the [documentation](https://docs.pytest.org/en/7.1.x/how-to/usage.html#how-to-invoke-pytest)). – MrBean Bremen Jun 11 '22 at 18:06
  • 1
    @MrBeanBremen thanks! I agree it's better to directly call `pytest foo.py`. There was some convenience to invoking `pytest.main` in the code, and I was not able to find a solution to only run my file, so hopefully folks find the accepted solution helpful as well. – Alnitak Jun 13 '22 at 01:36

1 Answers1

3

According to the pytest documentation, options and arguments can be passed to pytest.main. To run tests in foo.py, this would work:

# ... various code above...

def test_foo():
    foo = Foo()
    assert foo()

def test_bar():
    bar = Bar()
    assert bar.baz

if __name__ == '__main__':
    import pytest
    pytest.main(["foo.py"])
    # consider using below
    # pytest.main([__file__])
Matthew Flamm
  • 448
  • 3
  • 13
  • While this is correct, I wouldn't recommend it. This is the same as just running `pytest foo.py`, which is the usual way to run pytest, and avoids hardcoding the command line in the test itself. – MrBean Bremen Jun 12 '22 at 05:10
  • I agree that it isn't usually optimal to run this way, it doesn't mean that there aren't any scenarios where it can be useful. For example, here is an answer that uses this type of execution https://stackoverflow.com/a/23765051/11423283 – Matthew Flamm May 31 '23 at 18:00
  • 1
    Sure, you are right of course - I just wanted to make sure that this is not the usual way to do this. I have seen code that does it this way just because they thought it had to be done like with `unittest` (at least that is what I probably wanted to say a year ago :) ). – MrBean Bremen May 31 '23 at 18:43