文章目录

  • 学习说明
  • Pytest介绍
  • 编写规则
  • Console参数介绍
  • 执行测试
  • 执行指定的函数
  • 参数化处理
  • 使用fixture实现用例之间的调用

学习说明

这里主要是了解pytest的使用。

Pytest介绍

Pytest是一个非常成熟的全功能的Python测试框架,主要由一下几点:

  • 简单容易上手,文档很丰富
  • 支持参数化,可以细粒度地控制要测试的测试用例
  • 能够支持简单的单元测试和复杂的功能测试,还可以用来做selemium、appmium等自动化测试、接口自动化测试(pytest+request)
  • 有很多丰富的第三方插件,并且可以自定义扩展,比如pytest-selemium、pytest-html、pytest-rerunfailures、pytest-xdist(多CPU分发)
  • 可以初始化和清除,setupmodule和teardowmmodule。

编写规则

  • 测试文件以test开头(以test结尾也可以)
  • 测试函数以test开头
  • 测试类以Test开头,不能有init方法
  • 断言使用assert即可

Console参数介绍

  • -v:用于显示每个测试函数的执行结果
  • -q:只显示整体测试结果
  • -s:用于显示测试函数中print()函数输出
  • -x:–exitfirst,在第一个错误或测试失败时立即退出
  • -h:帮助

执行测试

• 配置PyCharm执行 
  
• Tools->Python integrated tools->Default test runner
• main方法 
  
• pytest.main([“-s”, “-v”, “test_01.py”])
• 命令行 
  
• pytest -s -v test_01.py

执行指定的函数

有三种方法

  • 显式指定函数名,通过::标记
pytest.main(["-s", "-v", "test_03.py::test1"])
  • 使用模糊匹配,通过-k选择标识
pytest.main(["-s", "-v", "-k", "add","test_03.py"])
或者直接命令行 pytest -k func1 test.py
  • 使用pytest.mark,在函数上进行标记(必须要写配置文件)
pytest.main(["-s", "-v", "-m", "undo","test_03.py"])
或者直接命令行 pytest -m undo test_03.py
import pytest

@pytest.mark.undo
def test_add1():
    print("test1")

@pytest.mark.do
def test_sub2():
    print("test2")

if __name__ == '__main__':
    # pytest.main(["-s", "-v", "test_03.py::test1"])
    # pytest.main(["-s", "-v", "-k", "add","test_03.py"])
    pytest.main(["-s", "-v", "-m", "undo","test_03.py"])

下面是pytest.ini的配置文件

[pytest]
markers=
        do: do
        undo: undo

参数化处理

在pytest中,也可以使用参数化测试,即每组参数都独立执行一次测试。使用的工具就是pytest.mark.parametrize(argnames, argvalues)。包括列表元组字典来进行传参。

import pytest

# 列表
data = ['123', '456']

@pytest.mark.parametrize("pwd", data)
def test1(pwd):
    print("pwd")

# 元组
data2 = [(1,2,3), (4,5,6)]
@pytest.mark.parametrize("a, b, c", data2)
def test2(a, b, c):
    print(a, b, c)

# 字典
dicts = [
    {
      "user": 123,
      "pwd": 456
    },{
        "user": 789,
        "pwd": 101112
    }
]

data4 = [
    pytest.param(1,2,3, id="(a+b):pass"), # id的值可以自定义,只要方便理解每个用例是干什么的即可
    pytest.param(4,5,9, id="(a+b):pass")

]
@pytest.mark.parametrize("dic", dicts)
def test3(dic):
    print(dic)

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

class TestParametrize(object):

    @pytest.mark.parametrize("a, b, expect", data4)
    def test_patam(self, a, b, expect):
        assert add(a, b) == expect
if __name__ == '__main__':
    pytest.main(["-s", "-v", "test_04.py"])

使用fixture实现用例之间的调用

**目的:**是前后置的方法,可以实现部分以及全部用例的前后置。

如果要实现后置,则需要加上yield-(yield是生成器,可以生成一个可以迭代的数组,然后循环,所以是可以返回的)yield和return都可以返回,return后面没有代码,而yield后面可以有代码。

@pytest.fixture(),包含五个参数

  • scope:表示的是被这个装饰器它的作用域是什么,可以作用域函数、类、模块和包
  • params:可选的参数化,列表、元组、字典列表、字典元组。
  • autouse:自动执行,默认是False
  • ids:当使用params参数化时,给每一个值设置一个变量名
  • name: 表示被装饰器所标记的方法取别名-取了别名原来的名就不能用了
    fixture与fixture间可相互调用
    fixture可以有返回值,如果没有return,默认会是None
import pytest

@pytest.fixture()
def init():
    print("init")
    return 1

def test1(init):
    print("test1")

def test2(init):
    print("test2")

if __name__ == '__main__':
    pytest.main(['-s','-v',"test_05.py"])