编辑:切换到一个更好的例子,并澄清为什么这是一个真正的问题.
我想在Python中编写单元测试,在断言失败时继续执行,这样我就可以在单个测试中看到多个失败.例如:
class Car(object):
def __init__(self, make, model):
self.make = make
self.model = make # Copy and paste error: should be model.
self.has_seats = True
self.wheel_count = 3 # Typo: should be 4.
class CarTest(unittest.TestCase):
def test_init(self):
make = "Ford"
model = "Model T"
car = Car(make=make, model=model)
self.assertEqual(car.make, make)
self.assertEqual(car.model, model) # Failure!
self.assertTrue(car.has_seats)
self.assertEqual(car.wheel_count, 4) # Failure!
Run Code Online (Sandbox Code Playgroud)
在这里,测试的目的是确保Car __init__正确设置其字段.我可以将它分解为四种方法(这通常是一个好主意),但在这种情况下,我认为将它作为测试单个概念的单个方法("对象被正确初始化")更具可读性.
如果我们假设这里最好不分解方法,那么我有一个新问题:我无法立即看到所有错误.当我修复model错误并重新运行测试时,会wheel_count出现错误.当我第一次运行测试时,它可以节省我看到两个错误的时间.
为了比较,Google的C++单元测试框架区分了非致命EXPECT_*断言和致命ASSERT_*断言:
断言成对出现,测试相同的东西但对当前函数有不同的影响.ASSERT_*版本在失败时会生成致命的故障,并中止当前的功能.EXPECT_*版本生成非致命故障,不会中止当前功能.通常EXPECT_*是首选,因为它们允许在测试中报告多个失败.但是,如果在有问题的断言失败时继续没有意义,则应使用ASSERT_*.
有没有办法EXPECT_*在Python中获得类似行为unittest?如果没有 …
当我在Python单元测试中比较两个Unicode字符串时,它会提供一个很好的失败消息,突出显示哪些行和字符不同.但是,比较两个8位字符串只显示两个没有突出显示的字符串.
如何突出显示Unicode和8位字符串?
这是一个示例单元测试,显示两个比较:
import unittest
class TestAssertEqual(unittest.TestCase):
def testString(self):
a = 'xax\nzzz'
b = 'xbx\nzzz'
self.assertEqual(a, b)
def testUnicode(self):
a = u'xax\nzzz'
b = u'xbx\nzzz'
self.assertEqual(a, b)
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
该测试的结果显示了差异:
FF
======================================================================
FAIL: testString (__main__.TestAssertEqual)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/data/don/workspace/scratch/scratch.py", line 7, in testString
self.assertEqual(a, b)
AssertionError: 'xax\nzzz' != 'xbx\nzzz'
======================================================================
FAIL: testUnicode (__main__.TestAssertEqual)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/mnt/data/don/workspace/scratch/scratch.py", line 12, in testUnicode
self.assertEqual(a, b)
AssertionError: u'xax\nzzz' != u'xbx\nzzz'
- xax …Run Code Online (Sandbox Code Playgroud) 我想向 TestCase 添加一些自定义断言方法。作为一个简单的例子,我只是在下面的测试类中放了一个。它按预期工作,但是当生成输出时,回溯在输出中包含自定义断言。
使它表现得像 assertEqual() 所必需的步骤是什么?assertEqual 的代码在 TestCase 中,但引发断言的实际行没有出现在回溯中。我需要做什么才能使 test_something2 的输出看起来更像 test_something1 的输出?
import unittest
class TestCustomAssert(unittest.TestCase):
def assertSomething(self, s):
self.assertEqual(s, 'something')
def test_something1(self):
self.assertEqual('foo', 'something')
def test_something2(self):
self.assertSomething('foo')
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
输出
python3 custom_assert.py
FF
======================================================================
FAIL: test_something1 (__main__.TestCustomAssert)
----------------------------------------------------------------------
Traceback (most recent call last):
File "custom_assert.py", line 8, in test_something1
self.assertEqual('foo', 'something')
AssertionError: 'foo' != 'something'
- foo
+ something
======================================================================
FAIL: test_something2 (__main__.TestCustomAssert)
----------------------------------------------------------------------
Traceback (most recent call last):
File "custom_assert.py", line 10, in test_something2 …Run Code Online (Sandbox Code Playgroud)