一、pytest的简介及简单使用
1. pytest与unittest一样,也是python的单元测试框架,但比unittest更灵活。
2. pytest简单使用:
1⃣️ 编写pytest测试用例注意事项:首先.py文件名必须以test_开头或_test结尾;其次测试类名必须以Test开头、测试用例方法名必须以est_开头或_test结尾;测试用例可以直接定义也可以写在测试类中。
在示例项目中新建test_sample_1.py文件,在文件中定义一个test_sample()函数和TestSample类及两个方法test_sample_2()和hello_pytest(),打开终端,输入命令“pytest -v”,便开始类了用例的收集执行。
从图中可见:执行命令后,输出了命令运行的根目录,以及在根目录下收集到的测试用例条数、测试用例执行的结果
===> 可以得出以下结论:
1⃣️ pytest命令运行的目录,即为收集用例的根目录,pytest会自己下该目录及其子目录下搜寻符合命名规范的测试用例,不符合的不会被收集到
2⃣️ 测试用例的执行顺序为:先搜索到的先执行,即先搜索到的.py文件先执行,同一文件内部,按照代码书写顺序执行。
在示例项目中新建test_sample_2.py文件,在文件中定义两个测试用例函数,打开终端,输入命令“pytest -v”,查看执行顺序
二、pytest与unittest的异同
1⃣️ 在用例收集加载上:unittest必须通过testsuite以及loader来主动收集测试用例;pytest会在执行时自动收集测试用例
2⃣️ 在测试用例编写上:unittest必须import unittest,定义继承unittest.TestCase的测试类,然后在测试类里定义测试用例方法;pytest无需引入pytest,也不需要继承任何,测试用例可以是符合命名规范的.py文件里符合用例命名规范的函数也可以是符合命名规范的测试类中的方法。
3⃣️ 在测试用例的运行上:unittest可以通过命令行运行,也可以通过py文件来运行;pytest只能命令行运行即在根路径下通过“pytest -v”命令来运行,如果非要以py文件运行,则需要新建一个py文件,引入pytest,然后调用pytest的main()函数
4⃣️ 在筛选用例执行上:unittest本身不具备筛选功能,但可以通过测试用例命名,加载测试用例上来间接实现筛选;pytest具备筛选用例功能即通过给用例打标记的方式来实现用例筛选
5⃣️ 在用例断言上:unittest有多种断言方法assertXXX();pytest使用assert + 断言表达式来断言
6⃣️ 在数据驱动的支持上:unittest -> ddt ,pytest -> 参数化(pytest有自己的实现数据驱动的方式即参数化,故不支持ddt,是不能兼容使用的)@pytest.mark.parametrize(“参数名”, 参数列表)
7⃣️ 在测试用例执行报告上:unittest只有HTMLTestRunner,没有三方库;pytest有丰富的三方库(900+)
8⃣️ 在用例执行失败重试机制上:unittest没有此机制;pytest自带用例失败重试机制
====> 说完这些差异后,这或许/大概/可能/也许/就是pytest越来越火爆的原因吧!!!!
三、pytest的前置后置:fixture这个小机灵鬼~
1. 众所周知unittest的前置后置是固定的setUp() tearDown() setUpClass() TearDownClass(),那么pytest是怎么实现测试用例的前置后置的呢?是的没错,就是fixture这个小机灵鬼啦~
2. 前置后置函数的定义:
====> 通过装饰器的方式即@pytest.fixture()来识别该函数是前置后置函数;
====> 一个函数既包含前置也包含后置,那么是怎么区分开前置与后置的呢?答案就是 yield 这个楚河汉界
====> 函数有返回值该怎么返回呢?答案就是 跟在yield后面就好啦~ 返回值类型可以自定义,元祖/字典...
3. fixture的级别:
====> 1⃣️ session级别:即测试会话级别, 执行顺序为 前置-->所有测试用例-->后置,全局只执行一次,可以将参数autoUse的值置为True,一般用在接口自动化中数据库的连接(全局只连接一次,所有测试用例运行完毕后,关闭连接)。
====> 2⃣️ .py级别:即module模块级别,执行顺序为 前置-->该模块中测试类、测试用例-->后置,在哪一行调用,则该行之后的测试类/测试用例均适用。调用位置影响fixture的执行
====> 3⃣️ class级别:即测试类级别,执行顺序为 前置-->该类中的所有测试用例-->后置,作用类似unittest的setUpClass()和tearDownClass()
====> 4⃣️ function级别:即测试用例级别,执行顺序为 前置-->某一测试用例-->后置,作用类似unittest的setUp()和tearDown()
4. fixture的参数:
====> 1⃣️ scope:指定fixture的级别,默认是function级别,可以指定为session、module、class
====> 2⃣️ antouse:指定fixture是否自动使用,默认是False
5. 前置后置函数与测试用例的关联:
通过主动调用来实现前置后置函数与测试用例的关联,即在测试用例函数上使用@pytest.mark.usefixtures("前置后置函数名")即可实现调用。注意⚠️:调用时,级别应一一对应。
6. 前置后置函数有返回值时,测试用例怎么接收返回值?
====> 在测试函数中用同名形参来接收,如下:
定义一个前置后置函数:
@pytest.fixture def init_func(): driver = webdriver.Chrome() driver.get(url) yield driver driver.quit()
调用前置后置函数:
@pytest.mark.userfixtures("init_func") def test_case_1(init_func): pass
7. conftest.py --> 实现前置后置函数的共享
注意⚠️ 前置后置函数可以和测试用例写在同一个.py文件里,也可以提取出来放在单独的文件里,用于共享;前置后置函数是可以定义多个的,根据测试用例的需要来调用。
1⃣️ 为什么要实现前置后置函数的共享?====> 节省代码量,将共同的前置后置函数放在固定的conftest.py文件,需要使用则直接调用,无需引入,方便简介又高效
2⃣️ conftest.py文件放在哪个目录下?====> 一般在testcase目录下,新建一个conftest.py文件,名字是固定的!!!
3⃣️ conftest.py文件的作用:
====> conftest.py文件是专门用来定义共享的前置后置函数的
====> conftest.py文件作用域:所在目录及其子目录,即conftest.py文件所在目录中的测试类/测试用例和其子目录中的测试类/测试用例均可直接调用conftest.py文件中定义的前置后置函数
4⃣️ 子目录中conftest.py文件中定义的fixture与父目录中conftest.py文件中定义的fixture重名时怎么办?====> 就近原则,即先找到先执行。(优先使用子目录中的fixture)
4⃣️ fixture的内部继承:即一个fixture继承另一个fixture
在conftest.py中定义一个fixture,如下:
@pytest.fixnture def init(): driver = webdriver.Chrom() driver.get(url) yield driver driver.quit()
在conftest.py中定义另一个fixture来继承上面定义的fixture,如下:
@pytest.fixture def login(init): LoginPage(init).login(xxx) yield init # 用同名变量来返回继承的fixture的返回值
继承之后的执行顺序为:
==== 父fixture的前置 ====
==== 子fixture的前置 ====
***** 测试用例执行 ******
==== 子fixture的后置 ====
==== 父fixture的后置 ====
四、pytest的参数化
在unittest中有ddt实现数据驱动,那么对应的 pytest的参数化。====> @pytest.mark.parametrize(“参数名”, 参数列表)
示例:
@pytest.mark.parametrize("data", test_data_list) def test_case_1(data, fixture名): # 测试用例方法中的形参名必须与装饰器中的参数名一致 pass
总结:以上就是pytest的简单使用 以及 fixture的简单使用 以及 pytest的参数化使用