Testing Python动态测试计划生成
我使用Sphinx进行文档编制,使用pytest进行测试。 我需要生成一个测试计划,但我真的不想手动生成 我突然想到,一个简洁的解决方案是将测试元数据实际嵌入到测试本身中,嵌入到它们各自的docstring中。此元数据将包括完成百分比、剩余时间等内容。然后,我可以运行所有测试(此时主要包括占位符),并从中生成测试计划。这将保证测试计划和测试本身是同步的 我想做一个pytest插件或者sphinx插件来处理这个问题 使用pytest,我能看到的最近的钩子看起来像Testing Python动态测试计划生成,testing,pytest,python-sphinx,Testing,Pytest,Python Sphinx,我使用Sphinx进行文档编制,使用pytest进行测试。 我需要生成一个测试计划,但我真的不想手动生成 我突然想到,一个简洁的解决方案是将测试元数据实际嵌入到测试本身中,嵌入到它们各自的docstring中。此元数据将包括完成百分比、剩余时间等内容。然后,我可以运行所有测试(此时主要包括占位符),并从中生成测试计划。这将保证测试计划和测试本身是同步的 我想做一个pytest插件或者sphinx插件来处理这个问题 使用pytest,我能看到的最近的钩子看起来像pytest\u collectio
pytest\u collection\u modifyitems
,它在收集所有测试之后被调用
或者,我正在考虑使用Sphinx,或者复制/修改todolist插件,因为它似乎最符合这个想法。这个插件的输出会更有用,因为输出会很好地插入到我现有的基于Sphinx的文档中,尽管这个插件中有很多内容,我没有时间去理解它
docstrings中可能包含以下内容:
:plan_complete: 50 #% indicator of how complete this test is
:plan_remaining: 2 #the number of hours estimated to complete this test
:plan_focus: something #what is the test focused on testing
其思想是基于函数名、docstring和嵌入的计划信息生成一个简单的markdown/rst或类似的表,并将其用作测试计划
这样的事情已经存在了吗 最后,我使用了一个基于
pytest
的插件,因为它的编码非常简单
如果其他人感兴趣,以下是插件:
根据从测试中提取的元数据生成测试计划表的模块
文档字符串。测试描述从第一句话中提取,最多可提取到
第一个空行。从docstring中提取的数据是
格式:
:测试剩余时间:完成此测试剩余的10小时数。如果
不存在,假定为0
:test_complete:#已完成测试的百分比。如果未完成
现在,假设是100
:test\u focus:测试关注的项目,例如DLL调用。
"""
导入pytest
进口稀土
从functools导入部分
从运算符导入itemgetter
从pathlib导入路径
空格\u re=re.compile(r'\s+')
cut_whitespace=partial(whitespace_re.sub.))
计划\u re=re.compile(r):计划(\w+?):')
计划处理程序={
“剩余”:lambda x:int(x.split(“#”)[0]),
“完成”:lambda x:int(x.strip().split(“#”)[0]),
“焦点”:lambda x:x.strip().split(“#”)[0]
}
csv_template=“”。csv表格::测试计划
:标题:“名称”、“焦点”、“完成”、“剩余小时数”、“说明”、“路径”
:宽度:20、20、10、10、60、100
{tests}
总剩余小时数:{剩余小时数:.2f}
总完成百分比:{complete:.2f}
"""
类生成计划:
def uu init uu(self,output_file=Path('test_plan.rst')):
self.output\u file=输出文件
def pytest_集合_修改项(自身、会话、配置、项):
#断点()
items_to_parse={i.nodeid.split('[')[0]:self.item_过滤器(items)中的i代表i}
#parsed=map(解析_项,项到_parse.items())
parsed=[self.parse_items(n,i)for items_to_parse.items()中的(n,i)]
完成,剩余小时数=自身。获取摘要数据(已解析)
self.output_file.write_text(csv_template.format(
tests='\n'.join(self.generate_rst_table(已解析)),
完成,
剩余小时数=剩余小时数)
def项目过滤器(自身,项目):
退货项目#覆盖我
def get_summary_数据(自解析):
completes=[p['complete']表示解析后的p]
总体完成=总和(完成)/len(完成)
总时数剩余=总和(p[‘剩余’]表示解析后的p)
返回总完成时间、总剩余时间
def生成表格(自身,项目):
“为了简单起见,请使用CSV类型”
已排序的\u项=已排序(项,项=lambda x:x['name'])
quoter=lambda x:“{}”。格式(x)
getter=itemgetter(*“名称焦点完成剩余描述路径”.split())
对于已排序项目中的项目:
产生3*''+'','.join(映射(引用、获取(项)))
def parse_项(自身、路径、项):
“处理pytest提供的项目”
数据={
“名称”:item.name.split(“[”)[0],
“路径”:path.split(“:”)[0],
“描述”:“,
“剩余”:0,
“完成”:100,
“焦点”:“
}
单据=项目功能。\u单据__
如果文件:
desc=自我提取描述(doc)
数据['description']=desc
计划信息=自身提取信息(单据)
数据更新(计划信息)
返回数据
def提取描述(自我、文档):
第一句话=doc.split('\n\n')[0]。替换('\n','')
返回剪切空白(第一句)
def提取信息(自我、文档):
计划信息={}
对于文档拆分('\n\n')中的子字符串:
已清理=剪切空白(子结构替换('\n','')
拆分=计划重新拆分(已清理)
如果len(拆分)>1:
i=iter(拆分[1:])#拆分器从索引1开始
尽管如此:
尝试:
键=下一个(i)
val=下一个(i)
除停止迭代外:
打破
断言键
如果输入plan_处理程序:
计划信息[键]=计划处理程序[键](val)
退货计划信息
从我的conftest.py
文件中,我在pytest\u addoption函数中配置了一个命令行参数:parser.addoption('--generate\u test\u plan',action='store\u true',default=False,help=“generate test p
Autogenerated test_plan
=======================
The below test_data is extracted from the individual tests in the suite.
.. include:: test_plan.rst
def my_test():
"""
.. test:: My test case
:id: TEST_001
:status: in progress
:author: me
This test case checks for **awesome** stuff.
"""
a = 2
b = 5
# ToDo: chek if a+b = 7
My tests
========
.. automodule:: test.my_tests:
:members:
.. test-report: My Test report
:id: REPORT_1
:file: ../pytest_junit_results.xml
:links: [[tr_link('case_name', 'signature')]]