Unittest - 如何编写大量简单测试代码 [英] Unittest - How do I code lots of simple tests
问题描述
我真的不喜欢关于Unittest的事情之一(比较一下,我过去曾经使用过的一些特殊测试技巧,以及Perl''s / br / >
标准测试框架)是测试用作为一个类的模型
往往意味着测试中的粒度相对较高。
一个很好的例子来自Dive Into Python
( http ://diveintopython.org )第7.3节。在这里,作者写了一个模块,它将数字转换成罗马数字。测试案例是
然后
类KnownValues(unittest.TestCase):
knownValues =((1,''I ''),...#50多个具体案例
def testToRomanKnownValues(个体经营):
""" toRoman应该给出已知结果已知输入"
表示整数,数字表示self.knownValues:
result = roman.toRoman(整数)
self .assertEqual(数字,结果)
现在,在我看来,这里最大的问题是这个*不是*一个测试,
但是相当于50(或更多)。好吧,如果所有内容都成功完成相同的检查,但是
1.如果测试失败,则跳过其余部分!如果
失败的模式(代码处理错误地以4和9结尾的数字,对于
示例),它更容易找到所有支票都是报b / b
2.心理上,52次测试成功是一个更大的嘘声比
1测试成功 (尽管这项测试涉及52例)。它不仅仅是心理学 - 我们确实*确实*测试了52种不同的条件。
我能看到生成b的唯一方法真QUOT;测试次数是通过
某种形式的丑陋黑客攻击
test_values =((1,''我'),...)
类KnownValues(unittest.TestCase):
通过
for arabic,roman in test_values:
def test(self):
result = roman.toRoman(arabic)
self.assertEqual(roman,result)
setattr(KnownValues,''test_%s_%s''%(阿拉伯语,罗马),测试)
但我不能真正看到这是正确的方法 。
任何人都可以通过unittest建议更合理的方式运行这种
表驱动测试吗?
也许我应该使用doctest,但说实话,我更喜欢单元测试的整体基础设施(用于实际测试)。这只是这个
特别的问题真的让我感到烦恼......
保罗。
-
此签名故意留空
One of the things I really dislike about Unittest (compared, say, to a
number of adhoc testing tricks I''ve used in the past, and to Perl''s
"standard" testing framework) is that the testcase-as-a-class model
tends to imply a relatively high granularity in testing.
A good example of this comes from "Dive Into Python"
(http://diveintopython.org) section 7.3. Here, the author has written
a module which converts numbers to Roman numerals. The test case is
then
class KnownValues(unittest.TestCase):
knownValues = ( (1, ''I''), ... # 50-plus specific cases
def testToRomanKnownValues(self):
"""toRoman should give known result with known input"""
for integer, numeral in self.knownValues:
result = roman.toRoman(integer)
self.assertEqual(numeral, result)
Now, to my mind, the big problem here is that this *isn''t* one test,
but rather 50 (or more). OK, the same checks are done if everything
succeeds, but
1. If a test fails, the rest are skipped! If there''s a pattern to the
failures (the code handles numbers ending in 4 and 9 wrongly, for
example) it''s much easier to find if all of the checks are
reported.
2. Psychologically, "52 tests succeeded" is a much bigger boost than
"1 test succeeded" (albeit this test covered 52 cases). And it''s
not just psychology - we really *did* test 52 distinct conditions.
The only way I can see of producing the "true" number of tests is via
some form of ugly hack like
test_values = ((1, ''I''), ...)
class KnownValues(unittest.TestCase):
pass
for arabic, roman in test_values:
def test(self):
result = roman.toRoman(arabic)
self.assertEqual(roman, result)
setattr(KnownValues, ''test_%s_%s'' % (arabic, roman), test)
But I can''t really see that as the "right approach".
Can anyone suggest a more reasonable way of running this sort of
table-driven test via unittest?
Maybe I should use doctest instead, but to be honest, I prefer the
overall infrastructure of unittest (for real tests). It''s just this
particular issue that really bugs me...
Paul.
--
This signature intentionally left blank
推荐答案
Paul Moore写道:
Paul Moore wrote:
任何人都可以建议通过unittest运行这种表驱动测试更合理的方式?
Can anyone suggest a more reasonable way of running this sort of
table-driven test via unittest?
为什么不只是扩展self.assertEqual()并使用自己的检查,
增加计数器或添加项目所需的额外逻辑
到通过测试列表。然后最后检查一下通过测试的数字
或者类似的结果,以确保
总体上有效。
For例如:
类KnownValues(unittest.TestCase):
def setUp(self):
self.passCount = 0
def checkValue(自我,预期,结果):
如果预期==结果:
self.passCount + = 1
else:
#留给读者练习,但通行证会有效...
def testToRomanKnownValues(self):
表示整数,数字表示self.knownValues:
result = roman.toRoman(整数)
self.checkValue(数字,结果)
self.assertEqual(len(self.knownValues),self.passCount)
不,你没有得到心理上的肯定52测试通过!>
没有更改TestRunner,但我认为非化妆品部分
现在更关注你...
-Peter
Why not just extend self.assertEqual() and use your own check, with
additional logic as required to increment counters or add items
to the list of passing tests. Then put a final check of the number
of passing tests or something like that at the end to make sure
things worked overall.
For example:
class KnownValues(unittest.TestCase):
def setUp(self):
self.passCount = 0
def checkValue(self, expected, result):
if expected == result:
self.passCount += 1
else:
# left as exercise to the reader, but pass would work...
def testToRomanKnownValues(self):
for integer, numeral in self.knownValues:
result = roman.toRoman(integer)
self.checkValue(numeral, result)
self.assertEqual(len(self.knownValues), self.passCount)
No, you don''t get the psychologically affirming "52 tests passed!"
without changes to the TestRunner, but I assume the non-cosmetic part
of this is more your concern right now...
-Peter
Paul Moore写道:
Paul Moore wrote:
任何人都可以建议通过unittest运行这种表驱动测试的更合理的方法?
Can anyone suggest a more reasonable way of running this sort of
table-driven test via unittest?
看一下Docutils的'test / DocutilsTestSupport.py的想法。
CustomTestSuite和CustomTestCase类为命名的
数据驱动测试提供支持。大多数Docutils的测试都是数据驱动的。
Ian Bicking写道:unittest不是用子类编写的,除了记录的有限子类。 (并且它使用了双下划线变量,就像它只是*试图*让我失望!
双下划线变量是如此傲慢和光顾。
Take a look at Docutils'' test/DocutilsTestSupport.py for ideas. The
CustomTestSuite and CustomTestCase classes provide support for named
data-driven tests. Most of Docutils'' tests are data-driven.
Ian Bicking wrote: unittest is not written with subclassing in mind, except for the
limited subclassing that is documented. (And it uses
double-underscore variables, like it''s just *trying* to piss me off!
Double-underscore variables are so arrogant and patronizing.
一切都非常真实。双重下划线应该从
标准库中禁止。它们不可避免地会受到影响,因为无论如何
如何写了一个类,有人想要以原作者从未考虑过的方式将它子类化为
。
-
David Goodger http://starship.python.net/~goodger
出租: http://starship.python.net / ~goodger / cv
Docutils: http:// docutils.sourceforge.net/
(包括reStructuredText: http://docutils.sf.net/rst.html )
All very true. Double-underscores ought to be banned from the
standard library. They inevitably get in the way because no matter
how well a class is written, somebody is going to want to subclass it
in a way the original author never considered.
--
David Goodger http://starship.python.net/~goodger
For hire: http://starship.python.net/~goodger/cv
Docutils: http://docutils.sourceforge.net/
(includes reStructuredText: http://docutils.sf.net/rst.html)
Paul Moore< pf ** ****@yahoo.co.uk>在消息新闻中写道:< br ********** @ yahoo.co.uk> ...
Paul Moore <pf******@yahoo.co.uk> wrote in message news:<br**********@yahoo.co.uk>...
1.如果测试失败,则跳过其余部分!如果
失败的模式(代码处理错误地以4和9结尾的数字,对于
示例),如果所有检查都是
则更容易找到报告。
1. If a test fails, the rest are skipped! If there''s a pattern to the
failures (the code handles numbers ending in 4 and 9 wrongly, for
example) it''s much easier to find if all of the checks are
reported.
这是真的,但大部分时间我测试时,我更喜欢这种行为。
我的很多断言取决于
之前的断言是否成功,所以我希望测试在其中一个断言已经失败后失败。
不过有两种可能性会很好。
Jeremy
That''s true, but most of the time when I test, I prefer that behavior.
Many of my asserts depend on the success of the assert prior to
them, so I want the test to fail as soon as one of the asserts has
failed.
It''d be nice to have both possibilities, though.
Jeremy
这篇关于Unittest - 如何编写大量简单测试代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!