Using a command-line option in a pytest skip-if condition

后端 未结 2 408
攒了一身酷
攒了一身酷 2021-01-12 22:16

Long story short, I want to be able to skip some tests if the session is being run against our production API. The environment that the tests are run against is set with a c

2条回答
  •  时光说笑
    2021-01-12 22:49

    The problem with putting global code in fixtures is that markers are evaluated before fixtures, so when skipif is evaluated, configInfo didn't run yet and pytest.global_env will be empty. I'd suggest to move the configuration code from the fixture to pytest_configure hook:

    # conftest.py
    import configparser
    import pytest
    
    
    def pytest_addoption(parser):
        parser.addoption('--ENV')
    
    
    def pytest_configure(config):
        environment = config.getoption('--ENV')
        pytest.global_env = environment
        ...
    

    The configuration hook is guaranteed to execute before the tests are collected and the markers are evaluated.

    Is there a better way to be trying this than the pytest_namespace?

    Some ways I know of:

    1. Simply assign a module variable in pytest_configure (pytest.foo = 'bar', like I did in the example above).
    2. Use the config object as it is shared throughout the test session:

      def pytest_configure(config):
          config.foo = 'bar'
      
      @pytest.fixture
      def somefixture(pytestconfig):
          assert pytestconfig.foo == 'bar'
      
      def test_foo(pytestconfig):
          assert pytestconfig.foo == 'bar'
      

      Outside of the fixtures/tests, you can access the config via pytest.config, for example:

      @pytest.mark.skipif(pytest.config.foo == 'bar', reason='foo is bar')
      def test_baz():
          ...
      
    3. Use caching; this has an additional feature of persisting data between the test runs:

      def pytest_configure(config):
          config.cache.set('foo', 'bar')
      
      @pytest.fixture
      def somefixture(pytestconfig):
          assert pytestconfig.cache.get('foo', None)
      
      def test_foo(pytestconfig):
          assert pytestconfig.cache.get('foo', None)
      
      @pytest.mark.skipif(pytest.config.cache.get('foo', None) == 'bar', reason='foo is bar')
      def test_baz():
          assert True
      

    When using 1. or 2., make sure you don't unintentionally overwrite pytest stuff with your own data; prefixing your own variables with a unique name is a good idea. When using caching, you don't have this problem.

提交回复
热议问题