目录
@pytest.mark.usefixtures('fixture1','fixture2')
以下是Pytest的学习记录,持续学习中。。。
一、未分类-记录点
API与数据库控制层交互,数据库控制层与文档数据库(MongoDB或TinyDB)交互。
并非所有的测试代码都要放到测试函数中
二、测试方法
单元测试 | 检查一小块代码(如一个函数,或一个类)的测试 |
集成测试 | 检查大段的代码(如多个类,或一个子系统)的测试。集成测试的规模介于单元测试与系统测试之间 |
系统测试 | 检查整个系统的测试,通常要求测试环境尽可能接近最终用户的使用环境 |
功能测试 | 检查单个系统功能的测试。 |
皮下测试 | subcutaneous test,不针对最终用户界面,而是针对用户界面以下的接口测试。 |
三、pytest测试搜索的命名规则
- 测试文件应当命名为test_<something>.py或者<something>_test.py
- 测试函数、测试类方法应当命名为test_<something>
- 测试类应当命名为Test<Something>
四、测试结果解读
PASSED(.) | 测试通过 |
FAILED(F) | 测试失败 |
SKIPPED(s) | 测试未被执行。指定测试跳过执行 可以将测试标记为@pytest.mark.skip() 或使用@pytest.mark.skipif()指定跳过测试的条件 |
xfail(x) | 预期测试失败,并且确实失败 使用@pytest.mark.xfail()指定你认为会失败的测试用例 |
XPASS(X) | 预期测试失败,但实际上运行通过,不符合预期 |
ERROR(E) | 测试用例之外的代码触发了异常 |
五、命令行选项解读
--collect-only | 展示有哪些用例将会被运行, 用于检查选中的测试用例是否符合预期 |
-k EXPRESSION | 使用表达式指定希望运行的测试用例, 筛选出用例名中含有表达式的用例 如:pytest -k “asdict or defaults” 筛选出用例名中含有asdict或者defaults的用例 |
-m MARKEXPR | 用于标记分组 @pytest.mark.crud 将用例标记为crud
|
-x,--exitfirst | 失败后停止执行后面所有的用例 |
--maxfail=num | 指定出现几次失败后停止执行后面所有的用例 |
-s | 等价于--capture=on 允许终端在测试运行时输出某些结果 |
--capture=method | method有三种:no、sys、fd
|
--lf | --last-failed 定位到最后一个失败的测试用例重新执行 |
--ff | --failed-first 与--lf作用基本相同,不同之处在于-ff会运行完剩余的测试用例。即,调整了用例的测试顺序,上一轮失败的先运行,再运行上一轮成功的用例 |
-v | --verbose 输出的信息会更详细 |
-q | --quite 与-v刚好相反,简化输出信息 我喜欢-q和--tb=line(仅打印异常的代码位置)搭配使用 |
-l | --showlocals 失败用例由于被堆栈追踪,所以局部变量及其值都会显示出来 |
--tb=style | 决定捕捉到失败时输出信息的显示方式,即进行信息回溯 我推荐的style类型有:short、line、no
其他的类型还有:long、auto、native
|
--duration=N | 统计测试过程中哪几个阶段是最慢的(包括每个测试用例的call、setup、teardown过程) 显示最慢的N个阶段,耗时越长越靠前。 如使用--duration=0,则会将所有阶段按耗时从长到短排序后显示。 |
-rs | 查看跳过的原因,可以指令中加上-rs |
--setup-show | 看到测试过程中执行的是什么fixture,以及执行的先后顺序 |
--fixtures | 查询fixture信息,包括重命名的fixture |
--cache-show | 显示cache的内容 |
--cache-clear | 清除cache内容 |
六、关键文件解读
conftest.py | 可选的 它是pytest的”本地插件库“,其中可以包含hook函数和fixture。
同一个项目中可以有多个conftest.py文件,如tests目录下有一个,tests目录的子目录中各有一个 |
pytest.ini | 可选的 它保存了pytest在该项目下的特定配置。项目中最多包含一个配置文件,其中的指令可以调节pytest的工作行为 |
__init__.py | |
setup.py | 对于创建可分发的包很重要 |
七、fixture作用范围解读
scope=”function“ | scope参数的默认值 函数级别的fixture每个测试函数只需要运行一次。 |
scope=”class“ | 类级别的fixture每个测试类只需要执行一次 测试类里的所以方法都共享这个fixture |
scope=”module“ | 模块级别的fixture每个模块只需要执行一次 模块内的测试函数、类方法或其他fixture都共享这个fixture |
scope="session" | 会话级别的fixture每次会话只需要执行一次 一次pytest会话中的所有测试函数、方法都共享这个fixture |
八、pytest的内置fixture
8.1 tmpdir和tmpdir_factory
负责在测试开始运行前创建临时文件目录,并在测试结束后删除。以下是两者的对比:
tmpdir | tmpdir_factory | |
作用范围 | 函数级别 | 会话级别 |
tmpdir默认已经存在一个dir | tmpdir_factory需要先创建一个dir | |
创建文件夹 | a_sub_dir=tmpdir.mkdir('subdir') | a_dir=tmpdir_factory.mktemp('mydir') a_sub_dir=a_dir.mkdir('subdir') |
创建文件 | a_file=tmpdir.join('file.txt') | a_file=a_dir.join('file.txt') |
写文件 | a_file.write('Content xxxxx') | a_file.write('Content xxxxx') |
读文件 | a_file.read() | a_file.read() |
# 通过以下方法可以获取到根目录
base_temp=tmpdir_factory.getbasetemp()
# 也可以指定根目录
base_temp=mydir
8.2 pytestconfig
pytestconfig是request.config的快捷方式
通过命令行参数、选项、配置文件、插件、运行目录等方式来控制pytest。
pytestconfig.args |
pytestconfig.inifile |
pytestconfig.invocation_dir |
pytestconfig.rootdir |
pytestconfig.getoption('keyword') pytestconfig.getoption('verbose') pytestconfig.getoption('quiet') pytestconfig.getoption('showlocals') pytestconfig.getoption('tbstyle') |
8.3 cache
cache的作用是存储一段测试会话的信息,在下一段测试会话中使用。如提供--lf和--ff标识。
支持--cache-show、--cache-clear指令。
cache.get(key,default) |
cache.set(key,value) |
8.4 capsys
capsys有两个功能:允许使用代码读取stdout和stderr;可以临时禁止抓取日志信息。
capsys.readouterr() |
capsys.disabled() |
8.5 monkeypatch
monkeypatch可以在运行期间对类或模块进行动态修改,测试结束所有修改都会复原。
monkeypatch.setattr(target,name,value=<notset>,raising=True) # 设置一个属性 |
monkeypatch.delattr(target,name=<notset>,raising=True) # 删除一个属性 |
monkeypatch.setitem(dic,name,value) # 设置字典中的一条记录 |
monkeypatch.delitem(dic,name,raising=True) # 删除字典中的一条记录 |
monkeypatch.setenv(name,value,prepend=None) # 设置一个环境变量 |
monkeypatch.delenv(name,raising=True) # 删除一个环境变量 |
monkeypatch.syspath_prepend(path) # 将路径path加入sys.path并放在最前面 |
monkeypatch.chdir(path) # 改变当前工作目录 |
8.6 doctest_namespace
8.7 recwarn
九、装饰器
@pytest.mark.parametrize()
# 某个参数定义多个取值
@pytest.mark.parametrize('testname',['param1','param2','param3'])
def test_fun(testname):
pass
# 定义多个参数
@pytest.ark.parameterize('testA,testB',[('A1','B1'),('A2','B2'),('A3','B3'),])
def test_fun(testA,testB):
pass
#如果函数上分别定义两个参数,则运行时为两个参数的笛卡尔积,按照('A1','B1'),('A1','B2'),('A1','B3'),('A2','B1'),('A2','B2'),('A2','B3'),('A3','B1'),('A3','B2'),('A3','B3'),传参
@pytest.ark.parameterize('testA',[('A1','A2','A3',]) # 定义多个参数
@pytest.ark.parameterize('testB',[('B1','B2','B3',]) # 定义多个参数
def test_fun(testA,testB):
pass
@pytest.mark.usefixtures('fixture1','fixture2')
使用usefixtures和在测试方法中添加fixture参数,二者大体上是差不多的,区别之一在于只有后者才能使用fixture的返回值。
@pytest.fixture()
# 一次会话执行一次
@pytest.fixture(scope='session')
# 所在的每个测试都会执行,autouse特性更像是一个特例,而非规则。
# 设置成autouse=True的fixture不需要被测试用例引用
@pytest.fixture(autouse=True)
# 给fixture重命名
@pytest.fixture(name='alias')
# fixture参数化,并进行参数标识
@pytest.fixture(params=参数,ids=参数标识)
# 对于fixture的参数化,可以在函数中加入request,参数调用使用request.param
@pytest.fixture(params='mongo','tiny'])
def fun(tmpdir_factory,request):
print(request.param)
十、常用插件
改变测试流程的插件 | pytest-repeat | 重复运行测试 |
pytest-xdist | 并行运行测试 | |
pytest-timeout | 为测试设置时间限制 | |
改善输出效果的插件 | pytest-instafail | 查看错误的详细信息 |
pytest-sugar | 显示色彩和进度条 | |
pytest-emoji | 为测试增添一些乐趣 | |
pytest-html | 为测试生成HTML报告 | |
静态分析用的插件 | pytest-pycodestype pytest-pep8 | Python代码风格检查 |
pytest-flake8 | 更多的风格检查 | |
Web开发用的插件 | pytest-selenium | 借助浏览器完成自动化测试 |
pytest-django | 测试Django应用 | |
pytest-flask | 测试Flask应用 | |
其他 | pytest-assume | 断言报错后依然执行 |
pytest-cov | 测试覆盖率 | |
pytest-freezegun | 冰冻时间 | |
pytest-httpserver | 模拟HTTP服务 | |
pytest-mock | 模拟未实现的部分 | |
pytest-ordering | 调整执行顺序 | |
pytest-picked | 运行未提交git的用例 | |
pytest-rerunfailures | 失败重试 | |
pytest-random-order | 随机顺序执行 |
待学习内容
- 重新运行失败测试
- 遇到失败即停止所有测试
- 控制堆栈跟踪
- 控制日志输出
- 测试函数
- 使用断言语句
- marker标记功能的用法:测试归类/分组、测试标记为skip(跳过不执行)、告知某些测试一定失败
- 测试目录、测试模块、测试类、
- 将测试数据、启动逻辑、销毁逻辑放入fixture
- fixture实现对数据库进行初始化,写入数据以备测试之用
- fixture支持参数,利用参数,只需编写一份代码,可以针对TinyDB和MongoDB开展测试
- 内置fixture可满足的常见需求:生成和销毁临时目录、截取输出流(通过日志判定结果)、使用monkey patch、检查是否发出警告
- 在pytest中添加命令行选项
- 改进打印输出
- 打包分发自己编写的插件
- 共享定制化的pytest(包括fixture)
- 学习测试自己的测试插件(元插件)
- 一些热门的社区插件
- 修改默认配置,pytest.ini文件,或者tox.ini、setup.cfg文件
- 借助tox使项目可以在多个Python版本上运行
- 测试CLI部分,而不必mock系统的其余部分
- 借助coverage.py检查项目代码块的测试覆盖情况
- 通过Jenkins发起测试并实时显示结果
- 让pytest运行基于unittest的测试用例
- 把pytest的fixture共享给unittest的测试用例使用