Python test fixture to run a single test?

Viewed 3727

I'm looking for something like ruby rspec's focus metadata or elixir's mix tags to run a single python test.

Ruby RSpec Example:

# $ rspec spec
it 'runs a single test', :focus do 
  expect(2).to eq(2)
end

Elixir ExUnit & Mix Example:

# $ mix test --only focus
@tag :focus
test "only run this test" do
  assert true
end

Is this possible / available with any python test runner and fixture combo? Running single tests by specifying nested module.class.test_name via command line args can become very verbose in larger projects.

So Something like:

Desired Python Code:

# $ nosetests --only focus

from tests.fixtures import focus

class TestSomething(unittest.TestCase):
    @focus
    def test_all_the_things(self):
        self.assertEqual(1, 1)
2 Answers

Had a similar problem and wanted to imitate the same behaviour that rspec provides for ruby, where the entire test suite is ran when there are no focused tests, but when there are it only runs the focused tests.

The setup is fairly similar to what Piotr suggested, but adds one extra step to filter out the selected tests.

  1. Configure the marker as suggested by Piotr in your pytest.ini or pyproject.toml:

    [pytest]
    markers = 
        focus: what is being developed right now
    
  2. Add the following code to your root conftest.py

    def pytest_collection_modifyitems(session: pytest.Session, config: Any, items: list[pytest.Item]):
        focused = [i for i in items if i.get_closest_marker("focus")]
    
        if focused:
            items[:] = focused
    

This will filter the collected tests when there are one or more tests that have a focus marker. Combining this with pytest-testmon gives you the same behaviour as guard provides when coming from a ruby background.

Related