自动化测试框架 - pytest

pytest是Python最流行的单元测试框架之一, 帮助更便捷的编写测试脚本, 并支持多种功能复杂的测试场景, 能用来做app测试也能用作函数测试

官方文档: https://docs.pytest.org/en/latest/

pytest具有以下优点:

  • 允许使用assert进行断言
  • 自动识别测试脚本、类、函数
  • 可用于管理小型或者参数类型的测试数据或资源
  • 兼容unittest和nose测试框架
  • 支持Python2.7/Python3.4+
  • 丰富的插件支持,超过315个插件支持

pytest安装

pip install -U pytest

如果提示下面的错误,说明是pip的版本太老了, 要更新下:

  Could not find a version that satisfies the requirement pytest (from versions: )
No matching distribution found for pytest

更新方式:

easy_install --upgrade pip

官方示例

准备一个test_sample.py, 内容如下:

def inc(x):
return x + def test_answer():
assert inc() ==

在文件所在目录执行:

pytest

这里我们做下说明:

pytest脚本都以test_xxx.py为文件名;

inc方法是我们定义的一个自增函数,该函数将传递进来的参数加1后返回;

test_answer是我们编写的一个测试函数,其中我们使用基本的断言语句assert来对结果进行验证,测试函数以test_xxx作为命名

执行结果如下:

============================================================ test session starts ============================================================
platform darwin -- Python 2.7., pytest-4.1., py-1.7., pluggy-0.8.
rootdir: /Users/jackey/Documents/iOS/code/iOS-Auto/Agent_Test, inifile:
collected item test_sample.py F [%] ================================================================= FAILURES ==================================================================
________________________________________________________________ test_answer ________________________________________________________________ def test_answer():
> assert inc() ==
E assert ==
E + where = inc() test_sample.py:: AssertionError
========================================================= failed in 0.05 seconds ==========================================================
(wda_python) bash-3.2$

当执行到assert inc(3) == 5时,报错

执行pytest会在当前目录和子目录中寻找test_xx.py的测试文件,并进入到测试文件中寻找test_xx开头的测试函数开始执行

执行pytest -q  test_xxx.py是执行执行的脚本

在看一个例子,测试指定错误: (Assert that a certain exception is raised)

import pytest

def f():
raise SystemExit() def test_mytest():
with pytest.raises(SystemExit):
f()

执行指令:

pytest -q test_sysexit.py

输出:

(wda_python) bash-3.2$ pytest -q test_sysexit.py
. [%]
passed in 0.04 seconds
(wda_python) bash-3.2$

如果要开发多个测试方法,可以把方法写进一个class中

class TestClass(object):
def test_one(self):
x = 'this'
assert 'h' in x def test_two(self):
x = 'hello'
assert hasattr(x, 'check')

pytest能够自动识别类中的测试方法, 也不用我们去创建子类或者实实例, 运行结果如下:

(wda_python) bash-3.2$ pytest -q test_sample.py
.F [%]
================================================================== FAILURES ==================================================================
_____________________________________________________________ TestClass.test_two _____________________________________________________________ self = <test_sample.TestClass object at 0x102e151d0> def test_two(self):
x = 'hello'
> assert hasattr(x, 'check')
E AssertionError: assert False
E + where False = hasattr('hello', 'check') test_sample.py:: AssertionError
failed, passed in 0.08 seconds
(wda_python) bash-3.2$

除了直接在脚本路径执行pytest外, 还可以用以下方式

python -m pytest xxx.py

出现第一个(或第N个)错误时停止

pytest -x            # stop after first failure
pytest --maxfail= # stop after two failures

运行执行测试脚本

pytest test_mod.py

运行指定目录下的所有脚本

pytest testing/

运行包含指定关键字的测试方法, 可以是文件名、类名、测试函数名

pytest -k "MyClass and not method"

执行node id运行测试脚本,每一个被收集的测试方法都会分配一个指定的id, 我们可以用一下方式运行执行的测试方法:

# To run a specific test within a module
pytest test_mod.py::test_func # To run a test within a class
pytest test_mod.py::TestClass::test_method

日志打印的不同方式

pytest --showlocals # show local variables in tracebacks
pytest -l # show local variables (shortcut) pytest --tb=auto # (default) 'long' tracebacks for the first and last
# entry, but 'short' style for the other entries
pytest --tb=long # exhaustive, informative traceback formatting
pytest --tb=short # shorter traceback format
pytest --tb=line # only one line per failure
pytest --tb=native # Python standard library formatting
pytest --tb=no # no traceback at all

测试报告

pytest默认是完整的测试报告, 我们可以加上-r标签显示简短测试报告,可再搭配一下参数

Here is the full list of available characters that can be used:

f - failed
E - error
s - skipped
x - xfailed
X - xpassed
p - passed
P - passed with output
a - all except pP

可以多个参数一起使用

Debug模式

pytest --pdb

示例:

(wda_python) bash-3.2$ pytest --pdb
========================================================== test session starts ===========================================================
platform darwin -- Python 2.7., pytest-4.1., py-1.7., pluggy-0.8.
rootdir: /Users/jackey/Documents/iOS/code/iOS-Auto/Agent_Test, inifile:
collected items test_sample.py .F
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> self = <test_sample.TestClass object at 0x10e928610> def test_two(self):
x = 'hello'
> assert hasattr(x, 'check')
E AssertionError: assert False
E + where False = hasattr('hello', 'check') test_sample.py:: AssertionError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /Users/jackey/Documents/iOS/code/iOS-Auto/Agent_Test/test_sample.py()test_two()
-> assert hasattr(x, 'check')
(Pdb) print x
hello
(Pdb) print hasattr(x,'check')
False
(Pdb)

还可以指定第几次失败开始进入debug:

pytest -x --pdb   # drop to PDB on first failure, then end test session
pytest --pdb --maxfail= # drop to PDB for first three failures

任何失败的异常信息都会存储在sys.last_value,sys.last_type 以及 sys_last_traceback

在debug中可以通过以下方式获取最后报错的内容

(Pdb) import sys
(Pdb) sys.last_traceback.tb_lineno (Pdb) sys.last_value
AssertionError(u"assert False\n + where False = hasattr('hello', 'check')",)
(Pdb)

在执行一开始就进入到debug模式

pytest --trace

输入next执行下一步, exit退出

脚本中设置断点

import pdb

pdb.set_trace()

例如:

import pdb

class TestClass(object):
def test_one(self):
x = 'this'
pdb.set_trace()
assert 'h' in x def test_two(self):
x = 'hello'
assert hasattr(x, 'check')

获取执行最慢的n个测试步骤

pytest --durations=
======================================================= slowest  test durations ========================================================

(0.00 durations hidden.  Use -vv to show these durations.)

但如果所有脚本的运行时间都小于0.01s, 就不显示了, 除非带上-vv参数

pytest --durations= -vv

输出结果:

======================================================= slowest  test durations ========================================================
.00s call test_sample.py::TestClass::test_two
.00s setup test_sysexit.py::test_mytest
.00s setup test_sample.py::TestClass::test_two
.00s setup test_sample.py::TestClass::test_one
.00s teardown test_sample.py::TestClass::test_two
.00s teardown test_sample.py::TestClass::test_one
.00s call test_sysexit.py::test_mytest
.00s teardown test_sysexit.py::test_mytest
.00s call test_sample.py::TestClass::test_one
=================================================== failed, passed in 0.06 seconds ===================================================
(wda_python) bash-3.2$

将日志保存到指定文件

pytest --resultlog=path

Disabling plugins

To disable loading specific plugins at invocation time, use the -p option together with the prefix no:.

Example: to disable loading the plugin doctest, which is responsible for executing doctest tests from text files, invoke pytest like this:

pytest -p no:doctest

我们也可以在pytestdemo脚本中去启动pytest:

import pytest

pytest.main()

执行python pytestdemo.py就可以执行pytest

main()不会抛出SystemExit的异常, 但会返回exitcode, 一共有6种exitcode

Exit code :    All tests were collected and passed successfully
Exit code : Tests were collected and run but some of the tests failed
Exit code : Test execution was interrupted by the user
Exit code : Internal error happened while executing tests
Exit code : pytest command line usage error
Exit code : No tests were collected

我们试着加上打印

import pytest

print pytest.main()

输出:

(wda_python) bash-3.2$ python pytestDemo.py
========================================================== test session starts ===========================================================
platform darwin -- Python 2.7., pytest-4.1., py-1.7., pluggy-0.8.
rootdir: /Users/jackey/Documents/iOS/code/iOS-Auto/Agent_Test, inifile:
collected items test_sample.py .F [ %]
test_sysexit.py . [%] ================================================================ FAILURES ================================================================
___________________________________________________________ TestClass.test_two ___________________________________________________________ self = <test_sample.TestClass object at 0x1038ba650> def test_two(self):
x = 'hello'
> assert hasattr(x, 'check')
E AssertionError: assert False
E + where False = hasattr('hello', 'check') test_sample.py:: AssertionError
=================================================== failed, passed in 0.05 seconds =================================================== (wda_python) bash-3.2$

我们还可以在main中传递参数:

pytest.main(['-q','test_sample.py'])

给pytest.main添加plugin, 如下示例在执行的开头和结尾, 添加打印信息

import pytest

class MyPlugin(object):
def pytest_sessionfinish(self):
print '*** Test run reporting finishing' def pytest_sessionstart(self):
print '*** Test run report beginning' pytest.main(['-q','test_sample.py'], plugins=[MyPlugin()])

输出:

(wda_python) bash-3.2$ python pytestDemo.py
*** Test run report beginning
.F [100%]*** Test run reporting finishing

================================================================ FAILURES ================================================================
___________________________________________________________ TestClass.test_two ___________________________________________________________

self = <test_sample.TestClass object at 0x1090843d0>

def test_two(self):
x = 'hello'
> assert hasattr(x, 'check')
E AssertionError: assert False
E + where False = hasattr('hello', 'check')

test_sample.py:11: AssertionError
1 failed, 1 passed in 0.05 seconds

iOS自动化探索(四)自动化测试框架pytest - 安装和使用的更多相关文章

  1. iOS自动化探索(一)WebDriverAgent安装

    WebDriverAgent FaceBook推出的一款iOS移动测试框架, 支持真机和模拟器, 同时支持USB, 官方是这样介绍的: https://github.com/facebook/WebD ...

  2. python3: 自动化测试框架pytest

    最近在学习web自动化,所以在这里总结一下pytest框架. 其实pytest 和 unittest 都是自动化测试框架,但是pytest更好用一些,有以下几个优点:1)可以根据标签执行用例:2)?? ...

  3. iOS自动化探索(七)自动化测试框架pytest - 测试报告

    这里我们单独来看下关于如何生存测试报告 准备测试代码如下: #coding: utf- import pytest @pytest.fixture() def login(): print '输入账号 ...

  4. iOS自动化探索(六)自动化测试框架pytest - fixtures

    Fixture介绍 fixture是pytest特有的功能,它用pytest.fixture标识,定义在函数前面.在编写测试函数的时候,可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将 ...

  5. iOS自动化探索(五)自动化测试框架pytest - Assert断言的使用

    使用assert语句进行断言 pytest允许使用标准的python assert语法,用来校验expectation and value是否一致 代码演示: def func(): def test ...

  6. iOS自动化探索(八)Mac上的Jenkins安装

    安装Jenkins 首先检查是否有Jenkins依赖的java环境 java -version 出现java version "1.8.xx"说明已经安装了java Jackeys ...

  7. Python接口自动化测试框架: pytest+allure+jsonpath+requests+excel实现的接口自动化测试框架(学习成果)

    废话 最近在自己学习接口自动化测试,这里也算是完成一个小的成果,欢迎大家交流指出不合适的地方,源码在文末 问题 整体代码结构优化未实现,导致最终测试时间变长,其他工具单接口测试只需要39ms,该框架中 ...

  8. 【Mac + Python3.6 + ATX基于facebook-wda】之IOS自动化(一):WebDriverAgent安装

    此篇介绍如何安装WebDriverAgent,下一篇介绍facebook-wda库的安装使用以及自动化脚本的开发. 前言: 对于iOS的应用的测试,如果不需要用到图像识别,推荐使用这个项目facebo ...

  9. iOS自动化探索(十)代码覆盖率统计

    iOS APP代码覆盖率统计 今年Q3季度领导给加了个任务要做前后端代码覆盖率统计, 鉴于对iOS代码代码比较熟就选择先从iOS端入手,折腾一整天后终于初步把流程跑通了记录如下 覆盖率监测的原理 Xc ...

随机推荐

  1. xxxservlet继承HttpServlet类

    "HttpServlet类被定义为抽象类,但是源码里面没有抽象方法.所以没有一定要求实现的方法.之所以定义为抽象类,是因为他继承了GenericServlet这个抽象类.并没有全部实现里面的 ...

  2. Python3+Selenium3自动化测试-(一)

    完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱动浏览器做一些基本操作: 窗口尺寸设置.网页截图.刷新.前进和后退 窗口尺寸设置 在测试过程中,我们可能会要求打开浏览 ...

  3. centos7 vmware克隆解决网络问题

    centos7克隆后,发现两台机子之间的MAC相同,无法获取IP.超找资料,解决办法如下: 只要删除网卡的配置文件中的HWADDR和UUID两行就行.使用ifup启动网卡即可.

  4. django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统

    Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...

  5. PAT 天梯赛 L1-045. 宇宙无敌大招呼 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-045 AC代码 #include <iostream> #include <cstdio&g ...

  6. iOS 在cell中使用倒计时的处理方法(新)

    一.前言 之前的文章iOS 在cell中使用倒计时的处理方法得到大量的支持, 在这先感谢大家的支持. 但是也收到不少人的回复表示不会用, 需要一一解答, 由于之前写的时候没有使用Markdown编辑, ...

  7. 20162305李昱兴 2016-2017-2 《Java程序设计》第2周学习总结

    20162305 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 教材的第二章以数据和表达式为主.在第二章的学习中,我了解了print以及println的用法 ...

  8. Linux下MySQL 5.6.24的编译安装与部署

    MySQL 5.6正式版发布了,相对于5.5版本作出了不少改进,其源码安装配置方式也有所变化,本文根据实际操作,不断尝试,精确还原了安装的具体步骤. 在Linux下安装MySQL前,先确认卸载系统自带 ...

  9. 查询当天数据(mysql)

    SELECT count(*) as nums FROM go_member_share WHERE DATEDIFF(FROM_UNIXTIME(time, '%Y-%m-%d') , now()) ...

  10. DFS - 深度搜索 - 基于邻接列表表示法

    2017-07-25 15:38:00 writer:pprp 在前一篇图基于邻接列表表示法的代码加了一小部分,加了一个DFS函数,visited[N]数组 参考书目:张新华的<算法竞赛宝典&g ...