五、自动执行测试

json

json文件是一个特殊格式的文本文件

  • json是一种语法, 用来表达一些数据的
  • json文件的内容就是用json表达的一些数据
  • json的语法格式类似于python字典, 由大括号包裹, 有键,每个键对应一个值
{
    "name":"tom",
    "age":30
}

json读json文件

import json
open读的方式打开json文件
dict1 = json.load(打开文件对象) # 把json文件的内容读取到python的字典dict1中
close关闭已经打开的json文件
# 读取a.json文件, 显示键"age"对应的值
import json
file = open("a.json", "r", encoding="utf-8")
dict1 = json.load(file) # 把json文件的内容, 转化成一个python的字典
file.close()
print(dict1["age"])

a.json

{
    "name":"tom",
    "age":30
}

写json文件

import json
open用写的方式打开文件
json.dump(字典, open打开的文件对象, ensure_ascii=False) ensure_ascii=False中文不转义
关闭文件
import json
file = open("a.json", "w", encoding="utf-8")
dict1 = {"name":"刘备", "height":1.75}
json.dump(dict1, file, ensure_ascii=False) # ensure_ascii=False 中文不转义
file.close()

pytest

pytest自动执行测试用例

  • 测试用例所在的模块(py)命名一定要采用标识符的命名规则
  • 一个测试用例就是一个方法
  • 方法名习惯test开头
  • 方法所在的类习惯Test开头, 并采用大驼峰命名法
import pytest
if __name__ == "__main__":
    pytest.main(["-s", "测试用例所在的py文件名", "其他的测试用例所在的文件.py"]) 
# "-s"作用是, 如果没有-s测试用例中的print将不会输出任何内容
# m1.py
# 被测试的函数
def my_sum(a, b):
    return a + b
# m2.py 存放测试用例
# 测试m1.py中的my_sum函数是否正确
from m1 import my_sum
'''
测试用例
测试数据, 一个实参为4, 一个实参为2, 预期结果为6
'''
# 一个测试用例就是一个方法, 所以一定先要定义一个类
class TestFunc:  # 存放测试用例的类, 业内习惯Test开头, 并且采用大驼峰命名法
    # 类当中的方法就是测试用例
    def test_01(self): # 这个方法就是测试用例, 名字习惯以小写test开头
        result = my_sum(4, 2)
        if result == 6:
            print("测试通过")
        else:
            print("测试失败")

    def test_02(self):
        result = my_sum(1, 2)
        if result == 3:
            print("测试通过")
        else:
            print("测试失败")
# m3.py 存放测试用例

class TestM:
    def test_01(self):
        print("我是TestM中的测试用例test_01")
  • pytest中执行测试用例的代码
import pytest

if __name__ == "__main__":
    pytest.main(["-s", "m2.py", "m3.py"])  #"-s"的意思是执行测试用例的时候, 显示print的输出, "m2.py"测试用例所在的文件名

断言

  • 用代码判断测试用例执行是否通过
assert 条件 # 条件成立, 代表断言通过, 否则代表断言不通过
# m2.py 存放测试用例
# 测试m1.py中的my_sum函数是否正确
from m1 import my_sum
'''
测试用例
测试数据, 一个实参为4, 一个实参为2, 预期结果为6
'''
# 一个测试用例就是一个方法, 所以一定先要定义一个类
class TestFunc:  # 存放测试用例的类, 业内习惯Test开头, 并且采用大驼峰命名法
    # 类当中的方法就是测试用例
    def test_01(self): # 这个方法就是测试用例, 名字习惯以小写test开头
        result = my_sum(4, 2)
        assert result == 6  # result是实际运行结果, 6是预期结果, 实际结果与预期结果相同, 断言通过

    def test_02(self):
        result = my_sum(1, 2)
        assert result == 3

if __name__ == "__main__":
    TestFunc().test_01() # 把TestFunc这个类实例化后,直接调用test_01方法
'''
    t = TestFunc()
    t.test_01()
'''
# m3.py 存放测试用例

class TestM:
    def test_01(self):
        assert True   # 这个测试用例永远不会失败

setup和teardown

  • 测试用例所在的类可以定义两个方法, 一个是setup, 一个是teardown
  • 如果一个类中有多个测试用例, 每个测试用例执行前会自动调用setup方法, 每个测试用例执行完成后会自动调用teardown方法
# m2.py 存放测试用例
# 测试m1.py中的my_sum函数是否正确
from m1 import my_sum
'''
测试用例
测试数据, 一个实参为4, 一个实参为2, 预期结果为6
'''
# 一个测试用例就是一个方法, 所以一定先要定义一个类
class TestFunc:  # 存放测试用例的类, 业内习惯Test开头, 并且采用大驼峰命名法
    # 类当中的方法就是测试用例
    def test_01(self): # 这个方法就是测试用例, 名字习惯以小写test开头
        result = my_sum(4, 2)
        assert result == 6  # result是实际运行结果, 6是预期结果, 实际结果与预期结果相同, 断言通过

    def test_02(self):
        result = my_sum(1, 2)
        assert result == 3

    def setup(self):
        print("setup方法给调用了")

    def teardown(self):
        print("teardown方法给调动了")

if __name__ == "__main__":
    TestFunc().test_01() # 把TestFunc这个类实例化后,直接调用test_01方法
'''
    t = TestFunc()
    t.test_01()
'''

setup_class和teardown_class

  • 一个类中不管有多少测试用例, 所有测试用例执行前, 自动调用一次setup_class, 所以测试用例执行完成后自动调用一次teardown_class
# m2.py 存放测试用例
# 测试m1.py中的my_sum函数是否正确
from m1 import my_sum
'''
测试用例
测试数据, 一个实参为4, 一个实参为2, 预期结果为6
'''
# 一个测试用例就是一个方法, 所以一定先要定义一个类
class TestFunc:  # 存放测试用例的类, 业内习惯Test开头, 并且采用大驼峰命名法
    # 类当中的方法就是测试用例
    def test_01(self): # 这个方法就是测试用例, 名字习惯以小写test开头
        result = my_sum(4, 2)
        assert result == 6  # result是实际运行结果, 6是预期结果, 实际结果与预期结果相同, 断言通过

    def test_02(self):
        result = my_sum(1, 2)
        assert result == 3

    def setup(self):
        print("setup方法给调用了")

    def teardown(self):
        print("teardown方法给调动了")

    def setup_class(self):
        print("setup_class方法给调用了")

    def teardown_class(self):
        print("teardown_class方法给调动了")

if __name__ == "__main__":
    TestFunc().test_01() # 把TestFunc这个类实例化后,直接调用test_01方法
'''
    t = TestFunc()
    t.test_01()
'''

参数化

  • 多个测试用例, 代码完全相同, 只有测试数据与预期结果不同, 使用参数化后可以去掉冗余代码
import pytest

# 在要使用参数化的方法前
@pytest.mark.parametrize("形参的说明", [(形参对应的实参), (形参对应的实参), (....)])
def 测试用例(self, 和形参的说明里一样的具体形参):
    pass
[里有几个元组, 被参数化的方法就会自动执行几次]
# m4.py 存放测试用例
# 测试m1.py中的my_sum函数是否正确
import pytest
from m1 import my_sum
'''
测试用例1
测试数据, 一个实参为4, 一个实参为2, 预期结果为6
测试用例2
测试数据, 一个实参为1, 一个实参为2, 预期结果为3
测试用例3
测试数据, 一个实参为10, 一个实参为1, 预期结果为11
'''
class TestFunc:
    @pytest.mark.parametrize("a, b, expect", [(4, 2, 6), (1, 2, 3), (10, 1, 11)])
    def test_01(self, a, b, expect): # a和b代表调动my_sum提供的实参, expect代表预期结果
        result = my_sum(a, b)
        assert result == expect

生成html版本测试报告

import pytest

if __name__ == "__main__":
    pytest.main(["-s", "--html=a.html", "m4.py"])  #"-s"的意思是执行测试用例的时候, 显示print的输出, "m2.py"测试用例所在的文件名

pytest.ini配置文件

  • pytest.ini配置文件一定要在项目目录里, 不能在任何一个包里
[pytest]
addopts = -s --html=a.html
testpaths = ./
python_files = m*.py
python_classes = Test*
python_functions = test*
  • 第一行必须为[pytest]
  • 第二行, -s代表执行测试用例的时候, 可以显示print的输出结果, --html=a.html 生成测试报告的文件名
  • 第三行: 在哪个包里查找测试用例所在的py文件
  • 第四行: 测试用例所在的py文件名, 支持通配符 m*.py查找所有以m开头, .py结尾的文件
  • 第五行: 测试用例所在的类名必须以Test开头
  • 第六行: 测试用例的方法名必须以test开头
import pytest

if __name__ == "__main__":
    pytest.main() # 启用pytest.ini配置文件, 来执行测试用例

总结

image

posted @ 2022-05-24 22:51  鬼谷仙生  阅读(42)  评论(0编辑  收藏  举报