一、测试框架分类
1.unittest
做什么测试都可以,不局限于单元测试
- 写用例 TestCase
- 收集用例 TestLoader.discover()
- 生成报告 HtmlTestRunner
- 模板
2.pytest
做什么测试都可以,不局限于单元测试
- 能够运行unittest用例
- 灵活
3.其他
- nose
- behave --行为驱动框架
二、pytest和unittest的共同点
都是测试框架且都是通过python代码来写测试用例、收集用例、运行用例、生成报告
pytest安装:pip install pytest
三、 pytest和unittest的不同点
1.编写用例上
- unittest 继承TestCase ;
- pytest 没有固定的模板,要么以函数形式,要么以类里方法的形式;特殊的,用例名称必须以test_开头 且如果用例在类中,类名必须以Test开头;
2.前置后置
unittest:
- setup/teardown
setup中的变量怎么传递给测试用例:self.***=value - setupClass/teardownClass
setupClass当中得到的变量,传递给测试用例的方式:cls.×××=value
pytest:
方案一:沿用unittest的风格
(不推荐在pytest中使用该模式)
-
用例级别:setup、teardown 类和类外的用例都可以使用;类外的就用类外写的,类里面就用类里面写的,不是通用的。
-
类级别(类使用):setup_class teardown_class
@classmethod def setup_class(cls): print("类--前置--")
-
模块级别:.py 不管是类还是方法,只要在范围内就执行
setup_module teardown_module
方案二:fixture
在pytest中主要使用fixture,先定义再调用
-
实现方式
1)函数来实现的,但是函数名称不固定
# 定义方式如下: @pytest.fixture def fix(): pass
2)前置操作,后置操作,写在一个函数里
@pytest.fixture def fix(): 前置代码 yeild # 分割线 后置代码
3)共有4个作用域,测试函数(function)、测试类(class)、测试模块文件(module)、测试会话(session,整个用例全局只执行一次,夹的是所有的用例,默认状态是函数级别,可选参数有
scope=function/class/module/session
@pytest.fixture(scope=function) def fix(): 前置代码 yeild # 分割线 后置代码
4)不放在测试类/测试函数里面
如果说有测试类要用的话,可以调用,可以在同一文件或者不同文件
5)前置操作中得到的数据怎么传递给测试用例,以如下形式:yeild 返回值
-
在测试用例中,以fixture函数名作为用例参数,用例参数接收返回值
-
测试函数的参数:① fixture(不需要写明,直接传函数名也可以) ② 参数化ddt(装饰器)
-
如果fixture有返回值,那么将它作为测试函数的参数时,可以不使用:@pytest.mark.usefixtures(“fixture的函数名称”)
6)共享机制
-
conftest.py 不许开启共享模式,哪里需要哪里调用,前置后置共享,conftest.py内容放的是fixture;
-
文件名固定不能改,该文件可以创建多个,有一定的作用域
-
定义fixture,可以定义多个,即找个地方放fixture定义
-
不需要导入,用例/类主动去该文件中获取调用的fixture
-
fixture可以对外共享;
方式:
@pytest.mark.usefixtures(“fixture的函数名称”)
测试类/测试函数 -
共享的范围,作用域:
当前conftest.py所在目录以及其下所有子目录的所有用例,共享该文件;例如 当前文件在项目根目录下,那么整个项目下的所有用例都可以共享该文件; -
conftest.py可以创建多个,可以在不同的包下创建,即支持层级创建;
-
优先级:就近原则;用例模块自己有,就用自己的,没有就近向上层级选择,名称相同也不影响,因为是向上层级查找的
-
支持嵌套,嵌套方式:嵌套方式->伪继承 fix1在上级也可以,只要能找到
-
一个fixture,想完全使用另一个fixture,并在其基础上新增一些代码;
定义形式:@pytest.fixture def fix1() pass @pytest.fixture def fix2(fix1) #新增的代码 pass
-
嵌套后的执行顺序 :fix1的前置 fix2的前置 fix2的后置 fix1的后置; 可以任意fixture级别嵌套? fix1
-
fix2 同级 比如都是函数 fix1>=fix2的级别 类嵌套函数
-
7)参数化 在测试用例前面加上
@pytest.mark.parametrize("参数名",列表数据)
-
参数名:用来接收每一项数据,并作为测试用例的参数,参数名有几个用例中的参数就需要传递几个,参数名和列表数据需要一一对应
-
列表数据:一组测试数据,组合参数化,支持笛卡尔积的形式
#示例: @pytest.mark.parametrize("a,b,c",[(1,2,3),(10,35,45),(10.9,20.0,30.9)]) def test_add(a,b,c): res=a+b assert res==c
8)打标记:mark功能
对用例打标记,运行的时候只运行打标记的用例300个回归用例,打标记50个,作为冒烟测试
得先注册标记名
yaml pytest.ini (该文件名称固定) [pytest] #固定名称 markers= #固定名称 mark1:说明文字只能是英文 mark2 mark3,
给用例/测试类打标记
@pytest.mark.已注册的标记名
运行时设置只运行标记的用例
pytest 命令行:-m 标记名
(打多个标记不同标记名用and、or隔开)
例如:-m mark1 or mark2
在收集到的所有用例中,只运行有标记名的用例,其他的不运行
另外的方式:给测试用例/测试类/测试模块打标签- 在测试类中,使用如下方式(测试类下,所有用例都被打上该标签)
class TestClass(object): pytestmark=pytest.mark.已注册的标签名 pytestmark=[pytest.mark.标签名1,pytest.mark.标签名2] #多标签模式
- 在模块文件里,同理(py文件下,所有测试函数和测试类里的测试函数,都有该标签)
import pytest pytestmark=pytest.mark.已注册的标签名 pytestmark=[pytest.mark.标签名1,pytest.mark.标签名2]#多标签模式
9)重运行机制
用例失败的情况下,可以重运行失败的用例
插件名称:rerunfailures
安装方法:pip install pytest-rerunfailures
使用方法,命令行参数形式(main方法中也同理用该参数即可):
pytest --reruns 重试次数
pytest --reruns 重试次数 --reruns-delay 次数之间的延时设置(s)
-
3.断言
-
unittest: self.assert****()
-
pytest: assert 表达式
表达式的结果为真断言通过
4.收集用例上
用例分散在多个文件中
1)unittest:
- TestLoader.discover(目录)
- 收集到套件中
- run方法执行
2)pytest:
不需要写任何代码去收集用例,自动收集/发现用例的方式如下,执行用例的时候会自动收集:
- pytest命令行:pytest[参数]
pytest -s -v 在控制台显示详细的用例执行情况
- python文件:main.py pytest.main([命令行参数])
3)自动收集用例过程
- 目录 :rootdir:pytest命令在哪个目录下运行,就以哪个目录为rootdir开始搜索用例
例如:E:…\python_auto_test\web_auto_test>下 - 文件名/模块名:符合test_.py或者_test.py条件的文件名,就会有用例
- 函数/类下方法:函数名以test_开头,类以Test开头(且不含__init__)的类下的test_开头的方法
4)执行顺序
- 用例文件,按文件名ASCII顺序
- 文件内部,各用例是按照代码编写顺序加载执行
5.生成报告
1)unittest: HtmlTestRunner、BeautifulReport
2)pytest:
-
插件:allure、html(官方看不到,但是可以安装pip install pytest-html)、重运行
http://plugincompat.herokuapp.com/ -
allure 安装:pip install allure-pytest
官方文档:https://docs.qameta.io/allure/#_pytest
a、命令行下载:https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/
b、下载最新版zip包,解压到普通用户权限的路径,配置环境变量…/bin加入到path
c、验证:cmd中输入allure 能正常打印命令参数代表可用
d、main中配置 :pytest.main(["-s", "-v","--html=report.html","--alluredir=allure_dir"]) #生成对应的json文件
e、用法:命令行执行:
allure serve ${allure_dir}
或者集成jenkins
四、总结
pytest -写用例、收集用例、运行用例、生成报告;
- 写用例:前置后置、步骤、断言
- 收集用例:自动收集(目录、文件、用例)
- 执行用例:pytest命令(两种方式),命令行或者写在python文件中
- 生成报告:html报告-html插件,allure报告