13.4. 测试成功

单元测试最基本的部分是构建单独的测试用例。一个测试用例回答关于它正在测试的代码的单个问题。

一个测试用例应该能够……

鉴于此,让我们构建第一个测试用例。您有以下要求

  1. toRoman 应该返回所有整数 13999 的罗马数字表示。

示例 13.2. testToRomanKnownValues


class KnownValues(unittest.TestCase):                           1
    knownValues = ( (1, 'I'),
                    (2, 'II'),
                    (3, 'III'),
                    (4, 'IV'),
                    (5, 'V'),
                    (6, 'VI'),
                    (7, 'VII'),
                    (8, 'VIII'),
                    (9, 'IX'),
                    (10, 'X'),
                    (50, 'L'),
                    (100, 'C'),
                    (500, 'D'),
                    (1000, 'M'),
                    (31, 'XXXI'),
                    (148, 'CXLVIII'),
                    (294, 'CCXCIV'),
                    (312, 'CCCXII'),
                    (421, 'CDXXI'),
                    (528, 'DXXVIII'),
                    (621, 'DCXXI'),
                    (782, 'DCCLXXXII'),
                    (870, 'DCCCLXX'),
                    (941, 'CMXLI'),
                    (1043, 'MXLIII'),
                    (1110, 'MCX'),
                    (1226, 'MCCXXVI'),
                    (1301, 'MCCCI'),
                    (1485, 'MCDLXXXV'),
                    (1509, 'MDIX'),
                    (1607, 'MDCVII'),
                    (1754, 'MDCCLIV'),
                    (1832, 'MDCCCXXXII'),
                    (1993, 'MCMXCIII'),
                    (2074, 'MMLXXIV'),
                    (2152, 'MMCLII'),
                    (2212, 'MMCCXII'),
                    (2343, 'MMCCCXLIII'),
                    (2499, 'MMCDXCIX'),
                    (2574, 'MMDLXXIV'),
                    (2646, 'MMDCXLVI'),
                    (2723, 'MMDCCXXIII'),
                    (2892, 'MMDCCCXCII'),
                    (2975, 'MMCMLXXV'),
                    (3051, 'MMMLI'),
                    (3185, 'MMMCLXXXV'),
                    (3250, 'MMMCCL'),
                    (3313, 'MMMCCCXIII'),
                    (3408, 'MMMCDVIII'),
                    (3501, 'MMMDI'),
                    (3610, 'MMMDCX'),
                    (3743, 'MMMDCCXLIII'),
                    (3844, 'MMMDCCCXLIV'),
                    (3888, 'MMMDCCCLXXXVIII'),
                    (3940, 'MMMCMXL'),
                    (3999, 'MMMCMXCIX'))                        2

    def testToRomanKnownValues(self):                           3
        """toRoman should give known result with known input"""
        for integer, numeral in self.knownValues:              
            result = roman.toRoman(integer)                     4 5
            self.assertEqual(numeral, result)                   6
1 要编写测试用例,首先要继承 unittest 模块的 TestCase 类。此类提供了许多有用的方法,您可以在测试用例中使用这些方法来测试特定条件。
2 这是一个整数/数字对列表,我已经手动验证过。它包括最小的十个数字、最大的数字、每个转换为单个字符罗马数字的数字,以及其他有效数字的随机样本。单元测试的重点不是测试所有可能的输入,而是测试一个代表性的样本。
3 每个单独的测试都是它自己的方法,它必须不带任何参数并且不返回任何值。如果该方法正常退出而不引发异常,则认为测试通过;如果该方法引发异常,则认为测试失败。
4 在这里,您调用实际的 toRoman 函数。(好吧,这个函数还没有写出来,但是一旦写出来,这就是调用它的那一行。)请注意,您现在已经定义了 toRoman 函数的 API:它必须接受一个整数(要转换的数字)并返回一个字符串(罗马数字表示)。如果 API 与此不同,则认为此测试失败。
5 还要注意,在调用 toRoman 时,您没有捕获任何异常。这是故意的。toRoman 在使用有效输入调用时不应该引发异常,并且这些输入值都是有效的。如果 toRoman 引发异常,则认为此测试失败。
6 假设 toRoman 函数定义正确、调用正确、成功完成并返回一个值,最后一步是检查它是否返回了正确的值。这是一个常见问题,TestCase 类提供了一个方法 assertEqual 来检查两个值是否相等。如果从 toRoman 返回的结果 (result) 与您期望的已知值 (numeral) 不匹配,assertEqual 将引发异常,并且测试将失败。如果两个值相等,assertEqual 将不执行任何操作。如果从 toRoman 返回的每个值都与您期望的已知值匹配,assertEqual 永远不会引发异常,因此 testToRomanKnownValues 最终会正常退出,这意味着 toRoman 已经通过了此测试。