支持非致命故障的 Python 测试框架
Posted
技术标签:
【中文标题】支持非致命故障的 Python 测试框架【英文标题】:Python test framework with support of non-fatal failures 【发布时间】:2009-08-20 16:28:38 【问题描述】:我正在评估自动化系统测试的“测试框架”;到目前为止,我正在寻找一个 python 框架。 在 py.test 或鼻子中,我看不到我从谷歌测试框架中知道的 EXPECT 宏之类的东西。 我想在一个测试中做出几个断言,而不是在第一次失败时中止测试。 我是否在这些框架中遗漏了什么或者这不起作用? 有人对可用于自动化系统测试的 python 测试框架有建议吗?
【问题讨论】:
看到您对我的回答的评论。我不明白你到底想做什么——我回答说“我想在一个测试中做出几个断言,而不是在第一次失败时中止测试。”我只是给出了一个框架方法,如果你想在异常处理程序中捕获所有异常信息,显然你可以捕获列表中的所有异常信息。我更新了我的答案。 你的答案去哪儿了?你删了吗?还有上面的 cmets(我没记错的话,来自多个用户)? 【参考方案1】:我想要一些类似的东西来进行我正在使用鼻子进行的功能测试。我最终想出了这个:
def raw_print(str, *args):
out_str = str % args
sys.stdout.write(out_str)
class DeferredAsserter(object):
def __init__(self):
self.broken = False
def assert_equal(self, expected, actual):
outstr = '%s == %s...' % (expected, actual)
raw_print(outstr)
try:
assert expected == actual
except AssertionError:
raw_print('FAILED\n\n')
self.broken = True
except Exception, e:
raw_print('ERROR\n')
traceback.print_exc()
self.broken = True
else:
raw_print('PASSED\n\n')
def invoke(self):
assert not self.broken
换句话说,它打印出指示测试是通过还是失败的字符串。在测试结束时,您调用实际执行real 断言的invoke 方法。这绝对不是可取的,但是我还没有看到可以处理这种测试的 Python 测试框架。我也没有弄清楚如何编写一个鼻子插件来做这种事情。 :-/
【讨论】:
好主意。既然我们决定使用鼻子,一个插件会很棒。【参考方案2】:您提出了建议,所以我建议robot framework。
【讨论】:
由于某些原因,我不能使用关键字驱动的测试框架 atm。但对于未来的项目,我会记住这一点。谢谢。【参考方案3】:奇怪的是,听起来您正在寻找类似我的claft
(命令行和过滤器测试器)的东西。类似的东西,但要成熟得多。
claft
(到目前为止)只是我为帮助学生进行编程练习而编写的一个玩具。我们的想法是为练习提供简单的配置文件,这些配置文件代表程序的要求,这些文件以人类可读的方式(并且是声明性的而不是程序性的)同时也适合自动化测试。
claft
运行所有定义的测试,为每个测试提供参数和输入,检查返回码,并根据正则表达式模式匹配输出 (stdout
) 和错误消息 (stderr
)。它收集列表中的所有故障,并在每个套件的末尾打印整个列表。
它还没有对输入/输出序列进行任意对话。到目前为止,它只是输入数据,然后读取所有数据/错误。它也没有实现超时,事实上,甚至没有捕获失败的执行尝试。 (到目前为止,我确实说过这只是一个玩具,不是吗?)。我还没有实现对 Setup、Teardown 和 External Check 脚本的支持(尽管我有计划这样做)。
Bryan 对“机器人框架”的建议可能更适合您的需求;尽管快速浏览它表明它比我想要的要复杂得多。 (我需要让事情变得足够简单,让刚接触编程的学生可以专注于他们的练习,而不是花费大量时间来设置他们的测试工具)。
欢迎您查看claft
并使用它或从中获得您自己的解决方案(它是 BSD 许可的)。显然,欢迎您回馈。 (它在 [bitbucket]:(http://www.bitbucket.org/) 上,因此您可以使用 Mercurial 进行克隆,并分叉您自己的存储库......如果您希望我查看将您的更改合并回我的存储库,请提交“拉取请求” )。
也许我又误读了你的问题。
【讨论】:
【参考方案4】:为什么不(在unittest
,但这应该适用于任何框架):
class multiTests(MyTestCase):
def testMulti(self, tests):
tests( a == b )
tests( frobnicate())
...
假设您实现了 MyTestCase 以便将函数包装到
testlist = []
x.testMulti(testlist.append)
assert all(testlist)
【讨论】:
【参考方案5】:如果您在命令行中传递 -x
选项,nose 只会在第一次失败时中止。
test.py:
def test1():
assert False
def test2():
assert False
没有 -x 选项:
C:\temp\py>C:\Python26\Scripts\nosetests.exe test.py 法郎 ==================================================== ===================== 失败:test.test1 -------------------------------------------------- -------------------- 回溯(最近一次通话最后): 文件“C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py”,行 183,在运行测试中 self.test(*self.arg) 文件“C:\temp\py\test.py”,第 2 行,在 test1 断言假 断言错误 ==================================================== ===================== 失败:test.test2 -------------------------------------------------- -------------------- 回溯(最近一次通话最后): 文件“C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py”,行 183,在运行测试中 self.test(*self.arg) 文件“C:\temp\py\test.py”,第 5 行,在 test2 断言假 断言错误 -------------------------------------------------- -------------------- 在 0.031 秒内运行 2 次测试 失败(失败=2)使用 -x 选项:
C:\temp\py>C:\Python26\Scripts\nosetests.exe test.py -x F ==================================================== ===================== 失败:test.test1 -------------------------------------------------- -------------------- 回溯(最近一次通话最后): 文件“C:\Python26\lib\site-packages\nose-0.11.1-py2.6.egg\nose\case.py”,行 183,在运行测试中 self.test(*self.arg) 文件“C:\temp\py\test.py”,第 2 行,在 test1 断言假 断言错误 -------------------------------------------------- -------------------- 在 0.047 秒内运行 1 次测试 失败(失败=1)您可能需要考虑查看the nose documentation。
【讨论】:
问题是关于 one 测试中的多个断言,一些可能失败,而不是多个测试。以上是关于支持非致命故障的 Python 测试框架的主要内容,如果未能解决你的问题,请参考以下文章