<p>Python的<code>unittest</code>包允许您像您所注意到的那样,在不同的方法中构造单元测试。这在需要测试非常密切相关且不需要单独的单元测试的情况下非常有用。在</p>
<p><code>unittest</code>测试首先将<code>unittest.Test</code>子类化,然后向其添加方法。因此,您可以在不同的单元测试之间添加多个层分离,这些单元测试之间的关联性较小。在</p>
<p><a href="https://docs.python.org/3/library/unittest.html" rel="nofollow noreferrer">Python Docs</a>中的一个示例演示了Python单元测试的最佳实践:</p>
<pre><code>import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
</code></pre>
<p>在这里你可以观察到很多事情:</p>
<ol>
<li><code>TestStringMethods</code>的三种方法是独立的单元测试。在</li>
<li><code>test_isupper</code>和{<cd6>}都包含两个断言,因为它们非常密切相关。为<code>test_isupper</code>中存在的两个断言添加单独的测试将给代码添加大量膨胀,并且可能导致非常奇怪的问题。在</li>
</ol>
<p>例如,如果<code>str.isupper()</code>以一种奇怪的方式中断,那么覆盖这个单一函数的单个unittest就会中断。但是,如果<code>"FOO"</code>和<code>"Foo"</code>的两个测试是分开的,那么一个测试可能通过,另一个测试失败。因此,测试单个函数的功能最好保存在具有多个断言的单个单元测试中。在</p>
<p>这同样适用于<code>test_split</code>方法;检查<code>str.split()</code>是否工作以及检查它是否引发了<code>TypeError</code>是密切相关的,因此最好在代码中保持紧密联系。在</p>
<p>所以,回到你的问题上来:每个方法可以(有时应该)有多个assert,因为它会导致更简单、更清晰的代码和更少的混乱。引用“Python的Zen”(在pythonshell中运行<code>import this</code>可以发现):“简单比复杂好”。因此,通过在一个方法中对相似的断言进行分组,使您的单元测试保持简单和结构化。在</p>