对于那些尚未开发完成的测试,最好的处理方式就是略过而不执行测试。
按正向的思路,我们只要通过标记指定要测试的就可以解决这个问题;但有时候的处境是我们能进行反向的操作才是最好的解决途径,即通过标记指定要跳过的测试。

skip

Pytest 使用特定的标记 pytest.mark.skip完美的解决了这个问题。官方Api说明:

  1. pytest.mark.skip(reason=None)
  • reason (str) – Reason why the test function is being skipped.

使用案例:

  1. import pytest
  2. @pytest.mark.skip(reason='跳过执行测试')
  3. def test_skip_01():
  4. print("test_skip_01 跳过执行")
  5. def test_skip_02():
  6. print("test_skip_02 正常执行")
  7. if __name__ == '__main__':
  8. pytest.main(['MyPytest.py', '-s'])

执行结果:

  1. collected 2 items
  2. MyPytest.py stest_skip_02 正常执行
  3. .
  4. ======================== 1 passed, 1 skipped in 0.07s =========================
  5. ***Repl Closed***

skipif

skipif则加入了condition,为测试函数指定被忽略的条件。

  1. pytest.mark.skipif(condition, *, reason=None)
  • condition (bool or str) – True/False if the condition should be skipped or a condition string.
  • reason (str) –Reason why the test function is being skipped.

举个例子,比如我希望测试代码运行在python3.0 以下的版本:

  1. import pytest
  2. import sys
  3. major_version = sys.version_info.major
  4. @pytest.mark.skipif(major_version >= 3, reason='当前python版本号大于3,跳过执行测试')
  5. def test_skipif_01():
  6. print("test_skipif_01 跳过执行")
  7. def test_skipif_02():
  8. print("test_skipif_02 正常执行")
  9. if __name__ == '__main__':
  10. pytest.main(['MyPytest.py', '-s'])

执行结果:

  1. collected 2 items
  2. MyPytest.py stest_skipif_02 正常执行
  3. .
  4. ======================== 1 passed, 1 skipped in 0.07s =========================
  5. ***Repl Closed***

pytest.skip() 和@pytest.mark.skip()区别

  1. pytest.skip(reason[, allow_module_level=False, msg=None])[source]
  • reason (str) – The message to show the user as reason for the skip.
  • allow_module_level (bool) – Allows this function to be called at module level, skipping the rest of the module. Defaults to False.
  • msg (Optional[str]) – Same as reason, but deprecated. Will be removed in a future version, use reason instead.

*官网的最新文档(https://docs.pytest.org/en/7.1.x/reference/reference.html?highlight=skip#pytest-skip)解释说用reason 后续替代msg参数。根据自己现有的版本进行参数尝试(我的pytest版本是6.2.5)

pytest.skip() 可以用在测试用例中执行跳过,而@pytest.mark.skip()是装饰器,用在整条用例上,不要混淆哦。看例子:

  1. import pytest
  2. import sys
  3. major_version = sys.version_info.major
  4. @pytest.mark.skipif(major_version >= 3, reason='当前python版本号大于3,跳过执行测试')
  5. def test_skipif_01():
  6. print("test_skipif_01 跳过执行")
  7. def test_skipif_02():
  8. print("test_skipif_02 正常执行")
  9. assert(1 == 1)
  10. #后面不再执行
  11. pytest.skip()
  12. assert(1 == 2)
  13. if __name__ == '__main__':
  14. pytest.main(['MyPytest.py', '-s'])

运行结果:

  1. collected 2 items
  2. MyPytest.py stest_skipif_02 正常执行
  3. s
  4. ============================= 2 skipped in 0.07s ==============================
  5. ***Repl Closed***

pytest.skip()也可以通过allow_module_level来控制跳过用例的作用范围。当allow_module_levelTrue的情况下,则整个模块的用例都不执行。举例子:

  1. import pytest
  2. import sys
  3. major_version = sys.version_info.major
  4. if major_version == 3:
  5. pytest.skip(msg='python 3 版本的时候,跳过本模块的用例', allow_module_level=True)
  6. def test_skipif_01():
  7. print("test_skipif_01 正常执行")
  8. assert(1 == 1)
  9. class Test_Skip():
  10. def test_skip_03(self):
  11. pass
  12. def test_skip_04(self):
  13. pass
  14. if __name__ == '__main__':
  15. pytest.main(['MyPytest.py', '-s'])

执行结果:

  1. collected 0 items / 1 skipped
  2. ============================= 1 skipped in 0.02s ==============================
  3. Process finished with exit code 0
  4. Skipped: python 3 版本的时候,跳过本模块的用例