[转载]pytest学习笔记
pytest学习笔记(三)
接着上一篇的内容,这里主要讲下参数化,pytest很好的支持了测试函数中变量的参数化
一、pytest的参数化
1、通过命令行来实现参数化
文档中给了一个简单的例子,
test_compute.py 的测试函数如下:
# content of test_compute.py
def test_compute(param1):
assert param1 < 4
在conftest.py中添加两个函数,一个是添加参数,一个是根据参数生成测试

# content of conftest.py
def pytest_addoption(parser):
parser.addoption("--all", action="store_true",help="run all combinations") def pytest_generate_tests(metafunc):
if 'param1' in metafunc.fixturenames:
if metafunc.config.option.all:
end = 5
else:
end = 2
metafunc.parametrize("param1", range(end))

通过在命令行添加--all的option来实现参数化,执行py.test -q test_compute.py 会发现只有2个case,而执行 py.test -q test_compute.py --all 会执行5个case
2、不同test IDs的参数化
在pytest会为每一组参数集合建立一个ID,可以试用-k来select匹配的名字子串,所以可以为不同的测试数据建立ID来区分不同的case,这个是经常使用的变量参数化,注意pytest.mark.parametrize()的括号中的顺序,(变量名称,对应的(参数化元组)的数组,ID的数组) , 这样很好的解决了代码重复编写,减少了维护,可以很好的实现数据与代码想分离

# content of test_time.py
import pytest
from datetime import datetime, timedelta
testdata = [
(datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1)),
(datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1)),
]
@pytest.mark.parametrize("a,b,expected", testdata)
def test_timedistance_v0(a, b, expected):
diff = a - b
assert diff == expected
@pytest.mark.parametrize("a,b,expected", testdata, ids=["forward", "backward"])
def test_timedistance_v1(a, b, expected):
diff = a - b
assert diff == expected

3、重要的资源参数化,这里面给了个case,是关于db的,觉得没太多可说的,就是一个简单的工厂,上代码了

# content of conftest.py
import pytest
def pytest_generate_tests(metafunc):
if 'db' in metafunc.fixturenames:
metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
class DB1:
"one database object"
class DB2:
"alternative database object"
@pytest.fixture
def db(request):
if request.param == "d1":
return DB1()
elif request.param == "d2":
return DB2()
else:
raise ValueError("invalid internal test config")

4、通过类来实现测试函数的参数化,这个还是很有意义的,自己理解下吧,没什么难度

# content of ./test_parametrize.py
import pytest
def pytest_generate_tests(metafunc):
# called once per each test function
funcarglist = metafunc.cls.params[metafunc.function.__name__]
argnames = list(funcarglist[0])
metafunc.parametrize(argnames, [[funcargs[name] for name in argnames] for funcargs in funcarglist])
class TestClass:
# a map specifying multiple argument sets for a test method
params = {
'test_equals': [dict(a=1, b=2), dict(a=3, b=3), ],
'test_zerodivision': [dict(a=1, b=0), ],
}
def test_equals(self, a, b):
assert a == b
def test_zerodivision(self, a, b):
pytest.raises(ZeroDivisionError, "a/b")

5、通过multiple fixtures来实现间接的参数化,文档中给了使用不同版本的python编译器的代码,有需求的自己看下吧

"""
module containing a parametrized tests testing cross-python
serialization via the pickle module.
"""
import py
import pytest
import _pytest._code
pythonlist = ['python2.6', 'python2.7', 'python3.3']
@pytest.fixture(params=pythonlist)
def python1(request, tmpdir):
picklefile = tmpdir.join("data.pickle")
return Python(request.param, picklefile)
@pytest.fixture(params=pythonlist)
def python2(request, python1):
return Python(request.param, python1.picklefile)
class Python:
def __init__(self, version, picklefile):
self.pythonpath = py.path.local.sysfind(version)
if not self.pythonpath:
pytest.skip("%r not found" % (version,))
self.picklefile = picklefile
def dumps(self, obj):
dumpfile = self.picklefile.dirpath("dump.py")
dumpfile.write(_pytest._code.Source("""
import pickle
f = open(%r, 'wb')
s = pickle.dump(%r, f, protocol=2)
f.close()
""" % (str(self.picklefile), obj)))
py.process.cmdexec("%s %s" % (self.pythonpath, dumpfile))
def load_and_is_true(self, expression):
loadfile = self.picklefile.dirpath("load.py")
loadfile.write(_pytest._code.Source("""
import pickle
f = open(%r, 'rb')
obj = pickle.load(f)
f.close()
res = eval(%r)
if not res:
raise SystemExit(1)
""" % (str(self.picklefile), expression)))
print (loadfile)
py.process.cmdexec("%s %s" %(self.pythonpath, loadfile))
@pytest.mark.parametrize("obj", [42, {}, {1:3},])
def test_basic_objects(python1, python2, obj):
python1.dumps(obj)
python2.load_and_is_true("obj == %s" % obj)

二、使用自定义的markers
1、自定义一个mark,如下,然后 py.test -v -m webtest 只运行标记了webtest的函数, py.test -v -m "not webtest" 来运行未标记webtest的

# content of test_server.py
import pytest
@pytest.mark.webtest
def test_send_http():
pass # perform some webtest test for your app
def test_something_quick():
pass
def test_another():
pass
class TestClass:
def test_method(self):
pass

2、还可以通过-v 指定的函数ID, py.test -v test_server.py::TestClass::test_method 来运行指定的函数
3、使用-k 来匹配名字子串, py.test -v -k http , py.test -k "not send_http" -v
4、在pytest.ini中注册markers
# content of pytest.ini
[pytest]
markers =
webtest: mark a test as a webtest.
addopts = --pyargs
好了,就这么多吧,下面的一些关于mocking的,有时间再来写
[转载]pytest学习笔记的更多相关文章
- [转载]Log4net学习笔记
Log4net 学习笔记: 主要是根据apache站点整理的: 原文链接:http://logging.apache.org/log4net/release/sdk/ http://logging.a ...
- 转载-python学习笔记之输入输出功能读取和写入数据
读取.写入和 Python 在 “探索 Python” 系列以前的文章中,学习了基本的 Python 数据类型和一些容器数据类型,例如tuple.string 和 list.其他文章讨论了 Pytho ...
- 转载-Python学习笔记之文件读写
Python 文件读写 Python内置了读写文件的函数,用法和C是兼容的.本节介绍内容大致有:文件的打开/关闭.文件对象.文件的读写等. 本章节仅示例介绍 TXT 类型文档的读写,也就是最基础的文件 ...
- 转载——JavaScript学习笔记:取数组中最大值和最小值
转载自:http://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html. 取数组中最大值 可以先把思路 ...
- pytest学习笔记
From: https://blog.csdn.net/gaowg11/article/details/54910974 由于对测试框架了解比较少,所以最近看了下pytest测试框架,对学习心得做个记 ...
- pytest 学习笔记一 入门篇
前言 之前做自动化测试的时候,用的测试框架为Python自带的unittest框架,随着工作的深入,发现了另外一个框架就是pytest (官方地址文档http://www.pytest.org/en/ ...
- pytest学习笔记(一)
这两天在学习pytest,之前有小用到pytest,觉得这个测试框架很灵巧,用在实现接口自动化(pytest+requests)非常的轻便,然后很有兴致的决定学习下,然后又发现了pytest-sele ...
- Pytest学习笔记3-fixture
前言 个人认为,fixture是pytest最精髓的地方,也是学习pytest必会的知识点. fixture用途 用于执行测试前后的初始化操作,比如打开浏览器.准备测试数据.清除之前的测试数据等等 用 ...
- Pytest学习笔记5-conftest.py的用法
前言 在之前介绍fixture的文章中,我们使用到了conftest.py文件,那么conftest.py文件到底该如何使用呢,下面我们就来详细了解一下conftest.py文件的特点和使用方法吧 什 ...
随机推荐
- 【miscellaneous】软件加密方法
原文:http://www.jiamisoft.com/blog/3471-ruanjianjiamifangfa.html 软件行业的加密是软件厂商为了保护软件开发的利润而采取的一种软件保护方式.当 ...
- 前端JS之HTML利用XMLHttpRequest()和FormData()进行大文件分段上传
用于网页向后端上传大文件 ### 前端代码<body> <input type="file" name="video" id="fi ...
- postgres csv日志和查看用户权限
最近在使用postgres 时遇到的2个问题,顺便记录一下查到的比较好的资料. 怀疑postgres在执行SQL时报错,程序日志中有无明确异常信息.通过查看csv日志来确定是否SQL真的是执行时报错. ...
- DOS命令学习
DOS命令学习 一.DOS使用常识 DOS的概况 DOS(Disk Operating System)是一个使用得十分广泛的磁盘操作系统,就连眼下流行的Windows9x/ME系统都是以它为基础. 常 ...
- 数据结构 -- 队列Queue
一.队列简介 定义 队列(queue)在计算机科学中,是一种先进先出的线性表. 它只允许在表的前端进行删除操作,而在表的后端进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有 ...
- 2019牛客多校第七场E Find the median 权值线段树+离散化
Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...
- PHP内存管理-zendMM
ZendMM 是zend memory manager zendMM可以分为三层: 1.存储层 维护者不同体量内存的hash表,已提供堆层使用,负责向os申请和释放内存 2.堆层 PHP内存管理的核心 ...
- python — 池
1. 池 池分为:进程池.线程池 池:预先的开启固定个数的进程数/线程数,当任务来临的时候,直接提交给已经开好的进程 / 线程,让这个进程 / 线程去执行就可以了. 池节省了进程.线程的开启.关闭.切 ...
- Django2.0 应用 Xadmin 报错解决(转载)
原文地址:https://blog.csdn.net/GoAheadNeverTurnBack/article/details/8143362 1.TypeError at /xadmin/ l ...
- C调用C++(C++封装以及C对其调用)
C调用C++(C++封装以及C对其调用) 来源 https://blog.csdn.net/wonengguwozai/article/details/89854781 相关知识提点:很经典的exte ...