前提:需要安装pytest和pytest-html(生成html测试报告)
pip install pytest 和 pip install pytest-html
1:命名规则
Pytest单元测试中的类名和方法名必须是以test开头,执行中只能找到test开头的类和方法,比unittest更加严谨
unittest:Setup>> setupclass , teardown >> teardownclass(课堂作业)
Pytest: setup, setup_class和teardown, teardown_class函数(和unittest执行效果一样)
运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown
运行于测试方法的始末,但是不管有多少测试函数都只执行一次setup_class和 teardown_class
2:Pytest生成自带的html测试报告
前提条件:需要下载pytest-html模块(python自带的生成测试报告模块)
pip install pytest-html
案例一
pytest.main(“模块.py”)【运行指定模块下,运行所有test开头的类和测试用例】
import pytest
class TestClass:
def setup(self):
print("setup")
def test01(self):
print("test01")
def test02(self):
print("test02")
def teardown(self):
print("teardown")
if __name__ == '__main__':
pytest.main(["--html=./report.html","test_01.py"])
案例二
运行指定模块指定类指定用例,冒号分割,并生成测试报告
import pytest
class TestClass:
def setup(self):
print("setup")
def test01(self):
print("test01")
def test02(self):
print("test02")
def test03(self):
print("test03")
def teardown(self):
print("teardown")
if __name__ == '__main__':
pytest.main(["--html=./report.html", "test_02.py::TestClass::test01"])
案例三
直接执行pytest.main() 【自动查找当前目录下,以test_开头的文件或者以_test结尾的py文件】
import pytest
class TestClass:
def setup(self):
print("setup")
def test01(self):
print("test01")
def test02(self):
print("test02")
def teardown(self):
print("teardown")
if __name__ == '__main__':
pytest.main(["--html=./report.html"])
Pytest调用语句
-x出现一条测试用例失败就退出测试
-s:显示print内容
pytst.main([’-x’,’–html=./report.html’,‘t12est000.py’])
pytest.main(["-s","–html=./report.html", “test_02.py”])
使用@pytest.mark.skip()跳过该用例(函数)
@pytest.mark.skip()
def test001(self):
assert 2==2
3.Pytest的运行方式
. 点号,表示用例通过
F 表示失败 Failure
E 表示用例中存在异常 Error
4:文件读取
读取csv文件
import csv #导入csv模块
class ReadCsv():
def read_csv(self):
item =[] #定义一个空列表
c = csv.reader(open("../commonDemo/test1.csv","r")) #得到csv文件对象
for csv_i in c:
item.append(csv_i) #将获取的数据添加到列表中
return item
r = ReadCsv()
print(r.read_csv())
读取xml文件
from xml.dom import minidom
class Readxml():
def read_xml(self,filename,onename,twoname):
root =minidom.parse(filename)
firstnode =root.getElementsByTagName(onename)[0]
secondnode=firstnode.getElementsByTagName(twoname)[0].firstChild.data
return secondnode
5:allure
Allure是一款轻量级并且非常灵活的开源测试报告框架。 它支持绝大多数测试框架, 例如TestNG、Pytest、JUint等。它简单易用,易于集成。
首先配置allure的环境变量
验证allure是否配置成功(输入allure查看)
其次要安装allure
pip install allure-pytest
allure-pytest是Pytest的一个插件,通过它我们可以生成Allure所需要的用于生成测试报告的数据
Allure常用的几个特性
@allure.feature # 用于描述被测试产品需求
@allure.story # 用于描述feature的用户场景,即测试需求
with allure.step(): # 用于描述测试步骤,将会输出到报告中
allure.attach # 用于向测试报告中输入一些附加的信息,通常是一些测试数据,截图等
allure.feature
@allure.feature # 用于描述被测试产品需求
allure.story
@allure.story # 用于描述feature的用户场景,即测试需求
案例
实现用户登录功能,场景为登录成功和登录失败
import pytest, os,allure
class TestLogin(object):
@allure.feature("用户登录功能") # 用于定义被测试的功能,被测产品的需求点
@allure.story("登录成功") # 用于定义被测功能的用户场景,即子功能点
def test_success(self):
assert 1 == 1
@allure.feature("用户登录功能") # 用于定义被测试的功能,被测产品的需求点
@allure.story("登录失败") # 用于定义被测功能的用户场景,即子功能点
def test_fail(self):
assert 1 == 2
if __name__ == '__main__':
pytest.main(['--alluredir', 'report/result', 'test_04.py']) # 生成json类型的测试报告
split = 'allure ' + 'generate ' + './report/result ' + '-o ' + './report/html ' + '--clean' # 将测试报告转为html格式
os.system(split) # system函数可以将字符串转化成命令在服务器上运行
Pytest和allure效果展示
with allure.step()
用于描述测试步骤,将会输出到报告中
allure.attach
用于向测试报告中输入一些附加的信息,通常是一些测试数据,截图等
案例
实现产品信息展示,动物的各种分类
import pytest, os, allure
class TestAnimal(object):
@allure.feature("动物")
@allure.story("分类")
def testshow(self):
with allure.step("鸟类"):
allure.attach("鹰","")
allure.attach("鹭")
allure.attach("鹅")
with allure.step("昆虫"):
allure.attach("蝴蝶")
allure.attach("蜻蜓")
allure.attach("蝎子")
if __name__ == '__main__':
pytest.main(['--alluredir', 'report/result', 'test_05.py'])
split = 'allure ' + 'generate ' + './report/result ' + '-o ' + './report/html ' + '--clean'
os.system(split)
练习
单元测试:通过读取csv/xml数据并且结合使用allure展示测试报告,验证开发中的add()和reduct()操作(在@allure.story分别实现相加减)
xml文件读取数据进行单元测试并生成测试报告
1.开发的代码
class CalcClass(object):
def add(self, a, b):
c = a + b
return c
def reduct(self, a, b):
c = a - b
return c
2.创建一个xml文件
<js>
<add>
<add1>2</add1>
<add2>4</add2>
<add3>6</add3>
</add>
<reduct>
<reduct1>6</reduct1>
<reduct2>5</reduct2>
<reduct3>1</reduct3>
</reduct>
</js>
3.读取xml文件
from xml.dom import minidom
class Readxml():
def read_xml(self, filename, onename, twoname):
root = minidom.parse(filename)
firstnode = root.getElementsByTagName(onename)[0]
secondnode = firstnode.getElementsByTagName(twoname)[0].firstChild.data
return secondnode
r = Readxml()
4.传递参数进行单元测试并结合allure生成测试报告
import pytest, allure, os
from demo.calcdemo import CalcClass
from readdata.readxml import Readxml
r = Readxml()
add1 = r.read_xml('../data/test2.xml', 'add', 'add1')
add2 = r.read_xml('../data/test2.xml', 'add', 'add2')
add3 = r.read_xml('../data/test2.xml', 'add', 'add3')
re1 = r.read_xml('../data/test2.xml', 'reduct', 'reduct1')
re2 = r.read_xml('../data/test2.xml', 'reduct', 'reduct2')
re3 = r.read_xml('../data/test2.xml', 'reduct', 'reduct3')
c = CalcClass()
class TestSuccess:
@allure.feature("相加的操作")
@allure.story("相加成功")
def test_add(self):
sum = c.add(int(add1), int(add2))
assert sum == int(add3)
@allure.feature("相减的操作")
@allure.story("相减成功")
def test_rec(self):
rec = c.reduct(int(re1),int(re2))
assert rec == int(re3)
if __name__ == '__main__':
pytest.main(['--alluredir', 'report/result', 'test_xml.py']) # 生成json类型的测试报告
split = 'allure ' + 'generate ' + './report/result ' + '-o ' + './report/html ' + '--clean' # 将测试报告转为html格式
os.system(split) # system函数可以将字符串转化成命令在服务器上运行
csv文件读取数据进行单元测试并生成测试报告
1.开发的代码
class CalcClass(object):
def add(self, a, b):
c = a + b
return c
def reduct(self, a, b):
c = a - b
return c
2.创建2个csv文件
3.读取csv文件
import csv # 导入csv模块
class ReadCsv():
def add_csv(self):
item = [] # 定义一个空列表
c = csv.reader(open("../data/test1.csv", "r")) # 得到csv文件对象
for csv_i in c:
item.append(csv_i) # 将获取的数据添加到列表中
return item
def read_csv(self):
item = [] # 定义一个空列表
c = csv.reader(open("../data/test3.csv", "r")) # 得到csv文件对象
for csv_i in c:
item.append(csv_i) # 将获取的数据添加到列表中
return item
r = ReadCsv()
4.传递参数进行单元测试并结合allure生成测试报告
import pytest,allure,os
from readdata.readcsv import ReadCsv
from demo.calcdemo import CalcClass
r = ReadCsv()
rec = r.read_csv()
add = r.add_csv()
c = CalcClass()
class TestCsvClass:
@allure.feature('相加的操作')
@allure.story('相加成功')
def test_add(self):
for i in add:
add = c.add(int(i[0]), int(i[1]))
assert add == int(i[2])
@allure.feature('相减的操作')
@allure.story('相减成功')
def test_reduct(self):
for i in rec:
rec = c.reduct(int(i[0]), int(i[1]))
assert rec == int(i[2])
if __name__ == '__main__':
pytest.main(['--alluredir', 'report/result', 'test_xml.py']) # 生成json类型的测试报告
split = 'allure ' + 'generate ' + './report/result ' + '-o ' + './report/html ' + '--clean' # 将测试报告转为html格式
os.system(split) # system函数可以将字符串转化成命令在服务器上运行