Pytest(一)安装与快速开始

pytest是一个可以轻松构建简单且可扩展测试用例的框架。本文通过一些小的单元测试和功能测试,来快速了解pytest的使用。

安装pytest

  1. 运行下面的命令安装pytest模块:
    1
    >pip install -U pytest # install -U 意思是更新xx模块
    
  2. 检查pytest是否安装成功:
    1
    >pytest --version
    

创建第一个testCase

创建一个文件,包含一个被测试函数和一个测试函数:

1
2
3
4
5
6
7
8
9
10
11
# test_first_pytest.py file


# 被测试的函数func(x)
def func(x):
    return x + 1

# 执行测试的函数test_func()
def test_func():
    assert func(1) == 3 

然后,在test_first_pytest.py文件路径下,执行pytest命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>pytest

======================================================================= test session starts =======================================================================
platform win32 -- Python 3.7.0, pytest-5.1.2, py-1.8.0, pluggy-0.13.0
rootdir: E:\pytestLearning\pytest-Learning
collected 1 item                                                                                                                                                   

test_first_pytest.py F                                                                                                                                       [100%]

============================================================================ FAILURES =============================================================================
____________________________________________________________________________ test_func ____________________________________________________________________________

    def test_func():
>       assert 3 == func(1)
E       assert 3 == 2
E        +  where 2 = func(1)

test_first_pytest.py:6: AssertionError
======================================================================== 1 failed in 0.36s ========================================================================

可以看到,测试返回一个失败的报告,因为func(1)不等于3.

提示:可以使用assert语句来判断测试实际结果是否等于测试期望结果。 python语言的assert语法为assert expression1 ["," expression2]。expression1为要判断的表达式;experssion2为抛出异常时,要执行的表达式,可以显示报错具体信息。

运行多个testCase

pytest会在当前目录下和所有子目录下查找并执行所有名字为test_*.py*_test.py的文件。

断言被测试函数抛出的异常

可以使用pytest.raises()判断被测试函数抛出的异常是否是我们期望的异常类型:

1
2
3
4
5
6
7
8
9
10
11
# test_pytest_raises.py
import pytest

def f():
    raise SystemExit(1)


def test_f():
    with pytest.raises(SystemExit):
        f()

使用pytest执行test_pytest_raises.py

1
2
3
4
5
6
7
8
9
10
>pytest test_pytest_raises.py

======================================================================= test session starts =======================================================================
platform win32 -- Python 3.7.0, pytest-5.1.2, py-1.8.0, pluggy-0.13.0
rootdir: E:\pytestLearning\pytest-Learning
collected 1 item                                                                                                                                                   

test_pytest_raises.py .                                                                                                                                      [100%]

======================================================================== 1 passed in 0.06s ========================================================================

关于with的用法: 参考https://www.cnblogs.com/xiaxiaoxu/p/9747551.html 参考https://blog.csdn.net/qq_33961117/article/details/88948245

通过Class组织多个testCase

pytest可以很容易的使用一个Class来组织多个测试函数:

1
2
3
4
5
6
7
8
class TestClass:
    def test_func1(self):
        x = "this"
        assert x == "h"

    def test_func2(self):
        x = "hello"
        assert hasattr(x, "h")

pytest会根据规则,自动寻找文件中所有test_前缀的函数。所以无需子类继承。我们可以通过命令,指定运行一个py文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>pytest -q test_class.py

.F                                                                                                                                                           [100%]
============================================================================ FAILURES =============================================================================
______________________________________________________________________ TestClass.test_func2 _______________________________________________________________________

self = <test_class.TestClass object at 0x000001E8D22016D8>

    def test_func2(self):
        x = "hello"
>       assert hasattr(x, "helloqq")
E       AssertionError: assert False
E        +  where False = hasattr('hello', 'helloqq')

test_class.py:9: AssertionError
1 failed, 1 passed in 0.04s

使用内置的fixture(如tmpdir)

pytest提供很多内建的fixture,fixture可以用来请求任意资源。通过pytest --fixtures 命令可以列出pytest所有内建的资源。

我们以tmpdir这个内置的fixtures来演示。tmpdir可以返回一个唯一的临时目录给测试函数调用:

1
2
3
4
5
# test_tmpdir.py file
def test_needfiles(tmpdir):
    print(tmpdir)
    assert 0

在测试函数中,我们使用了tmpdir这个fixture(通过在测试函数中声明了tmpdir这个fixture)。pytest将在测试函数执行之前查找并调用fixture工厂来创建资源。运行代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>pytest -q test_tmpdir.py
F                                                                                                                                                            [100%]
============================================================================ FAILURES =============================================================================
_________________________________________________________________________ test_needfiles __________________________________________________________________________

tmpdir = local('C:\Users\wuwenda\AppData\Local\Temp\pytest-of-wuwenda\pytest-2\test_needfiles0')

    def test_needfiles(tmpdir):
        print(tmpdir)
>       assert 0
E       assert 0

test_tmpdir.py:3: AssertionError
---------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------
C:\Users\wuwenda\AppData\Local\Temp\pytest-of-wuwenda\pytest-2\test_needfiles0
1 failed in 0.07s

可以通过print函数看到,tmpdir创建了一个唯一的临时目录。我们测试的时候,可以将一些信息保存在这个目录。