Pytest 设置跳过、预期失败用例
同学们大家好,这个章节我们来学习 pytest 运行时,如何设置跳过用例或者预期失败的用例。
简介
在使用 pytest 进行测试开发时,有时候可能需要跳过某些测试用例或者标记某些测试用例为预期失败。pytest 提供了一些装饰器和命令行选项来实现这些功能。
我们在做测试的时候,可能有些用例我们已经知道它是无法通过的,或者有一部分用例暂时不想执行,这时候我们就想要跳过这些用例,或者标记它们为预期失败。Pytest 给我们提供了跳过和预期失败的功能,这样我们就能灵活控制测试执行的行为了。
使用场景
- 当某些用例无法顺利通过或者尚未完成实现时,可以将其标记为跳过或预期失败,这样在整个测试运行过程中,这些用例将不会执行。
- 预期失败的测试用例会被执行,但不会导致整个测试运行失败。
一般在哪些场景下我们会想要这么做呢?比如有些用例因为开发还没完成或者暂时不可用,我们就可以选择跳过这些测试,或者把它们标记为预期失败。这样的话,这些测试就不会影响到整个测试运行,pytest 会根据我们的设置跳过这些用例,或者记录它们是预期失败的,而不会算作真正的失败。
跳过用例
- skip:用于标记测试用例,以指示该测试用例应该被跳过而不执行
- skipif:遇到特定情况跳过该测试用例。
先来看如何跳过用例。如果我们不想执行某个测试用例,可以直接使用 skip 装饰器把它跳过。如果是某些特定条件下跳过,可以使用 skipif,比如某个测试功能在某些平台下不可用,或者在某些版本下还没有实现。也就是说,这个功能很适合用来处理暂时不需要执行的用例,或者是在特定情况下,某些用例不能执行时,我们也能保证不出错。
装饰器设置跳过某个用例不执行
@pytest.mark.skip
@pytest.mark.skip(reason="跳过的原因描述")
import pytest
@pytest.mark.skip
def test_a():
assert True
@pytest.mark.skip(reason="代码没有实现")
def test_b():
assert False
比如我们在做一些基础功能测试时,有一个用例暂时没实现,或者我们不希望它执行,可以直接在用例前加上 @pytest点mark点skip 装饰器,pytest 就会跳过这个用例的执行。我们也可以传入原因说明为什么要跳过,比如 @pytest点mark点skip 括号中使用 reason 等于一个字符串来设置具体跳过原因,这样测试报告里会有详细说明。
运行结果:
我们来看看执行结果,设置跳过之后,在执行到这一行时,测试会立刻跳过,整个测试方法都不会被执行了。
方法中设置跳过用例
pytest.skip("reason")
def test_skip_example():
print("方法中设置跳过用例")
pytest.skip("跳过这个用例")
# 这个断言不会被执行,因为测试会被跳过
assert 1 == 1
除了直接用装饰器设置跳过之外,pytest 也支持在方法中进行设置。有时候我们想在某个测试方法执行到一半时跳过执行,这时可以在方法中直接调用 pytest点skip,括号中直接通过字符串设置跳过文本就可以。这样在执行到这一行时,测试会立刻跳过,后面的断言就不会执行了。这对于动态跳过某些不符合条件的测试很有用。
执行结果:
我们来看下执行结果,可以看到这个方法中上面的步骤执行了,但是设置跳过之后的步骤就都没有被执行了。
遇到特定情况跳过该测试用例
@pytest.mark.skipif(条件表达式, reason="跳过原因")
import pytest
# 如果是mac系统则跳过执行
@pytest.mark.skipif(sys.platform == 'darwin', reason="does not run on mac")
def test_case1():
assert True
# 如果是windows系统则跳过执行
@pytest.mark.skipif(sys.platform == 'win', reason="does not run on windows")
def test_case2():
assert True
如果我们想在某些特定条件下才跳过用例,比如说我们只想在 Windows 系统上执行某个测试,Mac 系统上跳过,就可以用 @pytest点mark点skipif,在 skipif 中传入判断条件,当条件满足时,测试用例就会被跳过。
标记用例预期失败
- 与 skip 类似,当用例预期结果为 fail 时,可以直接标记用例预期失败。
- 用法:添加装饰器
@pytest.mark.xfail
注意: 而 xfail 用于标记测试用例,以指示该测试用例是预期失败的。这意味着测试用例可以运行,但失败时不会被视为实际失败,而是被记录为已预期的失败。
在测试的过程中,有些测试用例是我们知道它会失败的,比如说某个功能还没做完,或者是知道它在某些版本中有问题。这时我们就可以标记它为预期失败,使用 @pytest点mark点xfail,让 pytest 执行这个用例,但如果它失败了,pytest 就会把它当做预期失败来记录,而不是当作真正的失败。当然了,如果标记为 xfail 的测试用例意外地通过了(即没有抛出预期的异常或没有失败),pytest 会在输出中显示该用例为 XPASS(unexpectedly passed),表示这个测试本来应该失败,但它意外地通过了。
代码示例:
import pytest
@pytest.mark.xfail
def test_a():
assert 1 == 2
@pytest.mark.xfail
def test_b():
assert 2 == 2
比如这个例子,在标记预期失败的测试用例时,我们只需要在用例前加上 @pytest点mark点xfail 装饰器,表示这个用例预期会失败。比如第一个例子中断言 1 == 2 是肯定会失败的,但是这里 pytest 会执行这个用例,但它知道这个断言会失败,所以会把它当作预期失败记录,而不会影响整个测试结果。
运行结果:
执行之后可以看到,pytest 在报告中把第一个用例标记为预期失败。第二个用例标记为 xpass。这样就能帮助我们区分哪些是开发中已经知道的问题,而不把它们误当成测试的失败。
接下来给大家演示一下具体操作。项目当中已经准备好了测试文件和一些测试用例。首先给第一个用例设置为跳过,使用 pytest点mark点skip 装饰器。然后第二个用例的话我们也给它设置一下跳过,并且加上跳过的原因。直接在括号里面用 reason 等于,字符串中传入跳过的原因,比如是因为代码没有实现。那然后第三个用例的话,我们给它在方法当中去设置一下跳过。方法当中去设置的话,就不需要装饰器了,在方法内部用 pytest点skip 就可以,然后在这个括号里面也可以设置跳过的原因,这里我们写一下原因。比如就写一下后面的不执行了,直接写成跳过以下的步骤。
./assets/Pytest设置跳过、预期失败用例.mp4
下面这两个用例我们可以设置一下针对不同的系统执行。比如这个如果是 mac 系统就跳过,那我们在这边就可以用 pytest点mark点skipif,然后在这个里面我们可以用 sys点platform 来获取当前执行的系统,如果是 mac 系统,它的值是 darwin,然后我们也可以用这个 reason 来设置跳过的原因,还是使用 reason 等于,然后传入一个字符串,字符串中写上原因就可以,比如这里就写用例不可以在 mac 系统运行。那这样的话就设置好了。下面的这个用例也是同样的思路。同样的我们给它设置一下,如果是 windows 系统的话就给它设置跳过,比如说这个用例不可以在 Windows 系统运行。接下来我们再试试设置预期失败的场景。比如这个测试用例要测试的场景我们知道它有 bug,不会成功,那就使用 pytest点mark点xfail 装饰器来设置。再下面的这个用例也是同样的,我们也给它设置一下 xfail,直接复制过来吧。好,那现在的话就全部都已经设置好了。
./assets/Pytest设置跳过、预期失败用例.mp4
设置好了之后的话,我们来执行一下整个文件。来看一下执行结果。可以看到第一个用例被跳过了对吧?然后第二个用例也跳过了,而且显示了跳过的原因。再来看第三个用例也跳过了,不过设置跳过之前的步骤是执行了的,设置完跳过之后的逻辑就没有执行了。然后第四个的话,设置的是 mac 系统就跳过对吧?大家看这个确实跳过没有执行,因为我现在用的是 mac 系统。然后后面这个用例它没有跳过,因为不是 windows 系统。再下面的这个第标记的是 xfail,它确实显示 xfail 了。第二个标记的虽然是 xfail,但是这里它执行成功了,所以标记的是 xpass,代表偶尔的成功了。
./assets/Pytest设置跳过、预期失败用例.mp4
总结
- Pytest 设置跳过。
- Pytest 设置预期失败用例。
最后来总结一下。这个章节我们介绍了如何在 Pytest 中跳过不需要执行的测试用例,或者标记某些测试用例为预期失败,这两个功能帮助我们更灵活地管理测试执行,避免因为未完成的功能或者不可执行的环境影响整个测试过程。好了,关于如何设置跳过和预期失败用例就先介绍到这里。