Pytest插件,用于根据有趣的模式断言数据。
pytest-voluptuous的Python项目详细描述
pytest volupturous
常见的用例是验证http api响应(在功能测试中):
importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()
如果验证失败,则比较返回 false 并断言失败,打印错误详细信息:
E AssertionError: assert failed to validation error(s): E - info.platform: not a valid value for dictionary value @ data[u'info'][u'platform'] E - info.description: length of value must be at most 10 for dictionary value @ data[u'info'][u'description'] E - info.downloads: expected list for dictionary value @ data[u'info'][u'downloads'] E - info.classifiers: expected dict for dictionary value @ data[u'info'][u'classifiers'] E - urls: expected int for dictionary value @ data[u'urls']
安装
适用于Python2.7和3.4+:
pip install pytest-voluptuous
更改日志
请参见更改日志。
功能
- 提供 实用程序模式 ( s , 精确 和 部分 )以减少样板文件。
- 实现一个pytest钩子来提供关于 断言 失败的错误详细信息。
- 打印描述性验证 失败消息
- 等于 和 无序的 验证器(有助于丰富的项目,在0.10+中可用)。
因为写作:
< Buff行情>>>> r = {'info': {'package_url': 'http://pypi.python.org/pypi/pytest'}} >>> assert 'info' in r >>> assert 'package_url' in r['info'] >>> assert r['info']['package_url'] == 'http://pypi.python.org/pypi/pytest'
…太烦人了。
为什么不将json模式 json模式 ?太冗长,太不方便。json模式永远不会 与能够利用平台优点的验证库的便利性相匹配。
为什么不去别的图书馆?没有特别的原因-但是它很容易使用和理解。此外, 语法非常简洁。
用法
简介
从指定模式开始:
< Buff行情>>>> from pytest_voluptuous import S, Partial, Exact >>> from voluptuous.validators import All, Length >>> schema = S({ ... 'info': Partial({ ... 'package_url': 'http://pypi.python.org/pypi/pytest', ... 'platform': 'unix', ... 'description': Length(min=100), ... 'downloads': dict, ... 'classifiers': list, ... }), ... 'urls': list ... })
然后加载数据以验证:
< Buff行情>>>> import requests >>> data = requests.get('https://pypi.python.org/pypi/pytest/json').json()
现在,如果断言这一点,数据将根据架构进行验证,但是比较并没有引起错误 将只计算为 false 这将使断言失败:
< Buff行情>>>> assert data == schema Traceback (most recent call last): ... AssertionError
现在,如果数据与模式不匹配,那么获取断言错误(assertionerror)就不是很好了,但是不用担心 在这里没有pytest魔法,但是一旦你运行pytest,你会得到:
E AssertionError: assert failed to validation error(s): E - info.platform: not a valid value for dictionary value @ data[u'info'][u'platform'] E - info.description: length of value must be at most 10 for dictionary value @ data[u'info'][u'description'] E - info.downloads: expected list for dictionary value @ data[u'info'][u'downloads'] E - info.classifiers: expected dict for dictionary value @ data[u'info'][u'classifiers'] E - urls: expected int for dictionary value @ data[u'urls']
详细信息
使用 = 运算符进行精确验证:
< Buff行情>>>> data = {'foo': 1, 'bar': True} >>> S({'foo': 1, 'bar': True}) == data True
在这些示例中,我们省略了assert(以便更容易地进行诊断)。
使用 <;= 执行 部分验证(允许额外的键,即):
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()0
您选择的运算符将被继承,因此测试数据为:
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()1
使用 = 还必须在嵌套上下文中提供精确值 :
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()2
<;= 表示部分匹配:
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()3
当需要混合和匹配运算符时,可以使用 partial :
松开匹配 < Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()4
并严格地使用 精确的 :
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()5
记住,匹配模式是继承的,因此您可能会做如下事情:
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()6
不存在 >;= 。如果要声明可能丢失的架构键,请使用可选的 :
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()7
或者,如果您想使所有键都是可选的,则覆盖 必需的 :
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()8
在这些情况下,如果要 需要一个键:
< Buff行情>importrequestsfrompytest_voluptuousimportS,Partial,Exactfromvoluptuous.validatorsimportAll,Lengthdeftest_pypi():resp=requests.get('https://pypi.python.org/pypi/pytest/json')assertS({'info':Partial({'package_url':'http://pypi.python.org/pypi/pytest','platform':'INVALID VALUE','description':Length(max=10),'downloads':list,'classifiers':dict,}),'urls':int})==resp.json()9
就这样。对于可用的验证程序,请查看 有趣的文档
有问题
性感的0.9.3及更早版本:
在volupturous pre-0.10.2 [] 中,匹配任何列表,而不是空列表。若要声明空列表,请使用等于([])
类似地,在volupturouspre-0.10.2中,
性感的0.10.0+:
在volupturous 0.10.0+
始终使用 dict 和 list 来验证任何大小的dict或list。它的工作原理与性感版不同。
任何版本:
[str,int] 匹配同时包含字符串和int的任何列表(以任何顺序和1-n次)。验证 包含这些类型的固定长度列表,使用 ExactSequence([str, int]) 和 无序([str, int]) 当命令没有意义的时候。您还可以使用这些函数中的值,如exactsequence([2,3])
许可证
Apache2.0许可。有关详细信息,请参见许可证。
更改日志
1.1.0(2018-10-31)
新的 :
修复 :
-
<HREF="https://github.com/f-secure/pytest-voluptuous/pull/4/commits/404407fdd554cdbe17323f1cc935225bb429b29d" rel="nofollow">提交:
如果路径为空(当错误位于"主级别"时),则跳过错误输出中的路径前缀。
感谢
@turbo87
!
1.0.1(2017-01-10)
第一个公共版本。
1.0.0(2016-12-07)
第一版。