|
前言
pytest是一个方便去写测试用例的测试框架.由于一开始我也不太清楚python有哪些比较好的测试框架,所以在写框架之前先调研了一些常见的测试框架.
.Unittest
.Doctest
.pytest
.nose
最终我倾向于nose和pytest,在进一步的了解这两款测试框架的api之后,最终选用了pytest,原因是使用起来真的非常简单.而且对Allure支持的非常好,这是后话了.我们先来看看pytest到底怎么使用吧.
这里我使用的IDE是:pycharm,非常好用.建议下载一个使用.尤其是对应python新手.
pytest 安装
或者设置Pycharm的工程解释器来安装
进入Preferences:
pytest 使用
sample-run
创建一个 sample.py 文件
- # content of sample.py
- def test_answer():
- assert 1 + 2 == 3
复制代码 执行
- py.test sample.py
- 或者
- pytest sample.py
复制代码
可以发现用例执行成功.
上述命令可以使pytest自动查找 sample.py 文件下所有的格式为:test_*的方法,然后执行用例.执行顺序为方法的顺序.
如果有多个py文件,可以直接使用下面命令
这个命令会找出当前目录下所有格式为test_*.py 或 *_test.py的文件然后执行用例.上面我们定义的文件名为sample.py,所以如果使用pytest是找不到用例的,我们需要把名称改成test_sample.py或者sample_test.py
注意文件内的方法名必须是test_*这种类型.如果写成def answer_test() 也是找不到的.
查找规则见文档: test-discovery
输出日志
在测试用例中输出日志,是常见的场景,如下
- # content of test_sample.py
- class TestSample:
- def test_answer(self):
- print('this is a log')
- assert 1 + 2 == 3
复制代码 然后执行py.test sample.py是不会输出日志的.需要加上-s参数.同时建议也加上-q参数.即quiet 报道模式,这样输出会好看点.
- pytest test_sample.py -s -q
复制代码
fixtures
说到测试框架自然要说到setup和teardown两个方法.
setup是用来做准备操作.一般用来初始化资源.
teardown是用来做收尾操作.一般用了关闭资源.
pytest的setup和teardown是利用@pytest.fixture这个注释来完成的.不仅可以完成初始化操作,初始化后如果有数据需要给用例使用也是非常方便!
setup
直接来看下面代码.
- # content of test_sample.py
- import pytest
- class TestSample:
- @pytest.fixture()
- def count(self):
- print('init count')
- return 10
- def test_answer(self, count):
- print('get count %s' % count)
- assert count == 10
复制代码 执行结果:
通过@pytest.fixture() 注释会在执行测试用例之前初始化操作.然后直接在测试用例的方法中就可以拿到初始化返回的参数(参数名要和初始化的方法名一样)
OK,假如我们新增一个方法会怎么样?
- # content of test_sample.py
- import pytest
- class TestSample:
- @pytest.fixture()
- def count(self):
- print('init count')
- return 10
- def test_answer(self, count):
- print('test_answer get count %s' % count)
- assert count == 10
- def test_answer_2(self, count):
- print('test_answer_2 get count %s' % count)
- assert count == 10
复制代码
可以发现 init count 这条日志输出两遍,也就是执行了两次初始化.这并没有什么问题.但是有时候我们希望的一个全局的初始化,既我们希望在这个类中只会执行一次这个初始化该怎么做?
fixture 有一个域(scope)的概念,用来指定该 fixture 的使用范围.
这里有五种域: module/class/session/invocation/function(default).
为了简单测试,这里我们修改一下工程目录结构,并且把fixture专门放到一个文件中方便使用:
通过下面命令可以列出当前目录中查找出来的所有 fixture
- pytest --fixtures
- 或者
- pytest --fixtures [目录]
复制代码
这里有个坑,就是虽然这里发现了 count 这个fixture,但在跑case的时候会报错说找不到!
原因是写 fixture 的文件的文件名不能瞎比写啊(捂脸),必须叫做 conftest.py
改完文件名后我们在运行:
这是在使用 seesion 域的情况下,可以发现init只执行一次.假如我们需要这种情况,每一个类都执行一次init,那么很简单直接把域改成 class 即可,同理 module 是基于模块的.有兴趣可以都去尝试一下.这里就不细说了.
teardown
利用python 的语法 yield 即可.
- # content of conftest.py
- import pytest
- @pytest.fixture(scope="session")
- def count():
- print('init count')
- yield 10
- print('teardown count')
复制代码 执行结果
代码中执行用例
有些时候需要在代码中调用执行case的方法.而不是通过command的方式.我们可以在python代码中加入下面代码即可:
- args = ['-s', '-q']
- pytest.main(args)
复制代码
|
|