Skip to content

Pytest测试框架

Pytest测试框架

简介

PyTest 是一个常用的 Python 测试框架,它提供了简单灵活的方式来编写测试代码,并且具有丰富的扩展和插件生态系统。

  • PyTest 能够支持简单的单元测试和复杂的功能测试;
  • PyTest 可以结合 Requests 实现自动化接口测试;
  • 结合 SeleniumAppium 实现 Web 自动化测试;
  • 使用 PyTest 结合 Allure 集成到 Jenkins 中可以实现持续集成。
  • PyTest 支持 315 种以上的插件;

环境安装与配置

安装模块

前提:本地已配置完成 Python 环境

pip install pytest

环境配置

PyCharm 默认测试执行器为 Pytest,也可自行设置。

  1. 进入 Settings -> Tools -> Python Intergrated Tools - Testing
  2. 选择 Default test runnerpytest

命名规则

类型 规则
文件 test_ 开头 或者 _test 结尾
Test 开头
方法/函数 test_开头
注意:测试类中不可以添加__init__构造函数

函数级别测试用例示例

  • 格式
    def test_XXX():
        # 测试步骤1
        # 测试步骤2
        # 断言  实际结果 对比 预期结果
        assert ActualResult == ExpectedResult
    
  • 示例
    import pytest
    
    def add_one(x):
        return x + 1
    
    def test_answer():
        assert add_one(3) == 5
    
    if __name__ == "__main__":
        # 运行测试用例
        pytest.main()
    
        # 也可以在终端执行 pytest 测试用例文件  执行测试用例
        # #pytest test_case.py
    

类级别的用例示例

  • 格式
    # 定义一个测试类,方便管理测试用例
    class TestXXX:
        # 测试类中的测试方法,一个方法对象一个测试用例
        def test_XXX(self):
            # 测试步骤1
            # 测试步骤2
            # 断言  实际结果 对比 预期结果
            assert ActualResult == ExpectedResult
    
  • 示例
    # 测试添加功能的模块
    import pytest
    
    def add_one(x):
        return x + 1
    
    # 定义一个测试类
    class TestCaseManager(object):
        def test_answer(self):
            assert add_one(1) == 2
    

断言

断言 assert,是一种在程序中为了表示与验证软件开发者预期的结果。

当程序执行到断言的位置时,对应的断言应该为真。若断言不为真时,给出错误信息。

断言语法

# 方式一
assert <bool expression>;       
# 方式二
assert <bool expression> , <message>;    

第一种:assert <表达式>

示例

def test_a():
    assert True

def test_b():
    assert 'abc' in "abcd"

第二种:assert <表达式>, <描述>

示例

断言结果为真时,描述信息不展示

def test_c():
    a = 1
    b = 1
    c = 2
    assert a + b == c, f"{a}+{b}=={c}, 结果为假"

import sys
def test_platform():
    assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"

常见的断言形式

断言格式 说明
assert xx 判断 xx
assert not xx 判断 xx 不为
assert a in b 判断 b 包含 a
assert a == b 判断 a 等于 b
assert a != b 判断 a 不等于 b

示例

def test_assert_true():
    a = 1
    assert a

def test_assert_false():
    a = False
    assert not a

def test_assert_in():
    a = "霍格沃兹测试开发学社"
    b = "霍格沃兹"
    assert b in a

def test_assert_equal():
    a = "霍格沃兹测试开发学社"
    b = "霍格沃兹测试开发学社"
    assert a == b

def test_assert_unequal():
    a = "霍格沃兹测试开发学社"
    b = "霍格沃兹"
    assert a != b

测试装置

Pytest中装置用来在用例执行之前或之后,完成资源准备或回收的操作。

例如:

  • 初始/关闭数据库
  • 打开/关闭浏览器
  • 读取/清理测试数据

常用测试装置

类型 规则
setup_class / teardown_class 类级,只在类中前后运行一次
setup_method / teardown_method 在类中,运行在调用方法的前后
# 用例类中配置装置
class TestCaseManager(object):

    def setup_class(self):
        print("setup_class,类级测试装置,只执行一次")

    def setup_method(self):
        print("setup_method,方法级测试装置,每个测试用例执行时都会执行一次")

    def teardown_method(self):
        print("teardown_method,方法级测试装置,每个测试用例执行时都会执行一次")

    def teardown_class(self):
        print("teardown_class,类级测试装置,只执行一次")

    def test_case1(self):
        assert True

    def test_case2(self):
        assert True

运行结果

========== test session starts ==========
collecting ... collected 2 items

test_add.py::TestCaseManager::test_add1 
setup_class,类级测试装置,只执行一次

setup_method,方法级测试装置,每个测试用例执行时都会执行一次
PASSED                           [ 50%]
teardown_method,方法级测试装置,每个测试用例执行时都会执行一次

test_add.py::TestCaseManager::test_add2 
setup_method,方法级测试装置,每个测试用例执行时都会执行一次
PASSED                           [100%]
teardown_method,方法级测试装置,每个测试用例执行时都会执行一次

teardown_class,类级测试装置,只执行一次
========== 2 passed, 4 warnings in 0.02s ==========

数据参数化

在执行测试用例时,经常会出现同一个测试场景下,使用不同的数据来验证的情况,此时就可以使用参数形式。

Pytest 使用装饰器 @pytest.mark.parametrize("参数名",[数据列表]) 实现参数化

  • 参数名要使用字符串表示, 多个参数之间使用逗号分隔, 参数名要和测试函数参数名相同
  • 数据列表中是参数化的数据,提供的结构需要和变量定义的结构相同

数据参数化示例

简单的参数化形式

@pytest.mark.parametrize("param",["Tom","Jack", "Rose"])
def test_case01(param):
    print("Test Case 01 Run ....")
    print(param)

复杂的参数化形式

@pytest.mark.parametrize("name, age, habby",[["Tom",18,["eat","drink","play"]],["Rose",18,["eat","drink","play"]]])
def test_case02(name, age, habby):
    print("Test Case 02 Run ....")
    print(name)
    print(age)
    for v in habby:
        print(v)

使用 YAML 文件进行数据驱动测试

data.yaml

- - 1
  - 2
  - 3
- - 4
  - 5
  - 9
- - 7
  - 8
  - 9
- - 11
  - 22
  - 33

test_case.py

import yaml
import pytest

def add(a, b):
    return  a + b

with open("data.yaml", "r") as file:
    data = yaml.safe_load(file)

@pytest.mark.parametrize("a, b, expect", data)
def test_add(a, b, expect):
    assert add(a, b) == expect