pytest框架

一、pytest安装与入门

1、介绍

- 简单灵活,

- 容易上手,

- 文档丰富

- 支持参数化,能够支持简单的单元测试和复杂的功能测试

- 具有很多第三方插件,并且可以自定义扩展

- 可以很好的和Jenkins工具结合

2、安装pytest

(1)命令行执行以下命令

$ pip3 install -U pytest

(2) 检查版本

$ pytest --version

3、创建你的第一个测试用例

(1)创建一个简单的测试方法

#test_sample.py
def func(x):
    return x + 1
def test_a():
    print("---test_a----")
    assert func(3) == 5 #断言失败
def test_b():
    print("---test_b---")
    assert 1 #断言成功

 

(2) 执行一下

命令行下执行

$ pytest -s test_sample.py

主函数模式下增加主函数:

if __name__ == '__main__':

  pytest.main(["-s", "test_sample.py"])

#-s 表示支持控制台打印,如果不加,print 不会出现任何内容 #-q 安静模式,不打印信息

结果说明:

. 表示成功

如果需要更多信息,可以使用-v或--verbose

F 表示失败

二、Pytest 基础使用

1、函数级别方法

运行于测试方法的始末,运行一次测试函数会运行一次 setup 和 teardown

(1)示例代码

 

import pytest

class TestLogin:

  # 函数级开始

  def setup(self):

    print("------->setup_method")

  # 函数级结束

  def teardown(self):

    print("------->teardown_method")

  def test_a(self):

    print("------->test_a")

  def test_b(self):

    print("------->test_b")

 

(2)执行结果

scripts/test_login.py ------->setup_method # 第一次 setup()

------->test_a

.------->teardown_method # 第一次 teardown()

------->setup_method # 第二次 setup()

------->test_b

 

.------->teardown_method # 第二次 teardown()

2、类级别方法

运行于测试类的始末,在一个测试内只运行一次 setup_class 和 teardown_class,不关心测试类内有多少个测试函 数。

(1)示例代码

class TestLogin:
# 测试类级开始
    def setup_class(self):
        print("------->setup_class")
    # 测试类级结束
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
    def test_b(self):
        print("------->test_b")            

(2)执行结果

scripts/test_login.py

------->setup_class # 第一次 setup_class()

------->test_a

.------->test_b

.------->teardown_class # 第一次 teardown_class()

三、Pytest 常用插件

插件列表网址:https://plugincompat.herokuapp.com 包含很多插件包,大家可依据工作的需求选择使用。

1、测试报告

(1)应用场景

自动化测试脚本最终执行是通过还是不通过,需要通过测试报告进行体现。

(2)安装

$ pip3 install pytest-html

(3)使用

在配置文件中的命令行参数中增加 --html=用户路径/report.html

(4)示例

pytest.ini

addopts = -s --html=report/report.html

(5)结果

在项目目录下会对一个 report 文件夹,里面有个 report.html 即为测试报告

2、失败重试

(1)应用场景

自动化测试脚本可能会使用到网络,如果网络不好可能最终会使脚本不通过。像这种情况可能并不是脚本本身 的问题,仅仅是因为网络忽快忽慢,那么我们可以使用失败重试的插件,当失败后尝试再次运行。一般情况最 终成功可以视为成功,但最好进行进行排查时候是脚本问题。

(2)安装

pip3 install pytest-rerunfailures

  (3)使用

在配置文件中的命令行参数中增加 --reruns n

(4)示例

pytest.ini
addopts = -s --reruns 3
test_login.py
class TestLogin:
    def test_a(self): # test开头的测试函数
       print("------->test_a")
        assert 1 # 断言成功
    def test_b(self):
        print("------->test_b")
        assert 0 # 断言失败        

 

(5)结果

scripts/test_login.py

------->test_a

.------->test_b

R------->test_b

R------->test_b

R------->test_b

F

(6)说明

R 表示重试

重试时,如果脚本通过,那么后续不再重试

如果你期望加上出错重试的等待时间,请使用如下命令(reruns-delay是等待时间):

pytest --reruns 5 --reruns-delay 1

如果你只想对某几个测试用例应用重试策略,你可以使用装饰器:

@pytest.mark.flaky(reruns=5, reruns_delay=2)

例如:

@pytest.mark.flaky(reruns=5, reruns_delay=2)
def test_example():
    import random
    assert random.choice([True, False])

四、Pytest 数据参数化

1.应用场景

登录功能都是输入用户名,输入密码,点击登录。但登录的用户名和密码如果想测试多个值是没有办法用普通 的操作实现的。数据参数化可以帮我实现这样的效果。

2、方法名

pytest.mark.parametrize

# 数据参数化

# 参数:

# argnames:参数名

# argvalues:参数对应值,类型必须为可迭代类型,一般使用list

@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)

3、一个参数使用方式

  • 1. argnames 为字符串类型,根据需求决定合适的参数名
  • 2. argvalues 为列表类型,根据需求决定列表元素中的内容
  • 3. 在测试脚本中,参数,名字与 argnames 保持一致
  • 4. 在测试脚本中正常使用

(1)示例

import pytest
class TestLogin:
    @pytest.mark.parametrize("name", ["xiaoming", "xiaohong"])
    def test_a(self, name):
        print(name)
        assert 1

(2)结果

scripts/test_login.py xiaoming

.xiaohong

.

4、多个参数使用方式

(1)示例

import pytest
class TestLogin:
    @pytest.mark.parametrize(("username", "password"), [("zhangsan",
"zhangsan123"),
("xiaoming", "xiaoming123")])
    def test_a(self, username, password):
        print(username)
        print(password)
        assert 1

(2)结果

scripts/test_login.py

zhangsan zhangsan123 .

xiaoming xiaoming123 .

多个参数还可以将装饰器写成 @pytest.mark.parametrize("username,password", [("zhangsan", "zhangsan123"), ("xiaoming", "xiaoming123")]) 效果是一样的。

五、Pytest 应用接口用例

1、运行原则

  • 在不指定运行目录,运行文件,运行函数等参数的默认情况下,pytest会执行当前目录下的所有以test 为前缀(test.py)或以_test为后缀(test.py)的文件中以test为前缀的函数
  • pytest会找当前以及递归查找子文件夹下面所有的test.py或test.py的文件,把其当作测试文件
  • 在这些文件里,pytest会收集下面的一些函数或方法, 当作测试用例
  • 不在类定义中的以test开头的函数或方法 在以Test开头的类中(不能包含init方法),以test 开头的方法

2、如何执行多条测试?

  • pytest会执行当前目录及子目录下所有test_*.py及*_test.py格式的文件
  • 可以设置pytest.ini配置文件,自定义执行文件格式

    addopts = -s

    # 当前目录下的scripts文件夹 -可自定义

    testpaths = testcase

    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件 -可自定义

    python_files = test_*.py

    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类 -可自定义

    python_classes = Test_*

    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类内,以test_ 开头的方法 -可自定义

     python_functions = test_*

3、登录用例脚本

url = "http://211.103.136.242:8064/authorizations/"
data = [{"username":"python",
"password":"12345678"},
{"username":"python1",
"password":"test123"},
]
@pytest.mark.parametrize("login", data)
def test_login(login):
      res= requests.post(url,json=login)
      print(res.json())
if __name__ =="__main__":
    pytest.main(["-s"])

 

结果:

{"user_id":1,"username":"python","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiO jE1NjUzNDA5NTcsInVzZXJfaWQiOjEsImVtYWlsIjoiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0a G9uIn0.K0Kx8lKkeX0CjNTuWZ0cA67FU33nkNYBfl_s-5LxNP8"} .{"non_field_errors":["无法使用提供的认证信息登录。"]}

 

posted @ 2021-05-31 11:57  丝瓜呆呆  阅读(145)  评论(0编辑  收藏  举报