13.5. 负面测试 (Testing for failure)

使用有效输入确保函数成功通过测试还不够,你还需要测试无效输入导致函数失败的情形。但并不是任何失败都可以,必须如你预期地失败。

还记得 toRoman其他要求吧:

  1. toRoman 在输入值为 13999 之外时失败。
  2. toRoman 在输入值为非整数时失败。

Python 中,函数以引发异常的方式表示失败。unittest 模块提供了用于测试函数是否在给定无效输入时引发特定异常的方法。

例 13.3. 测试 toRoman 的无效输入


class ToRomanBadInput(unittest.TestCase):                            
    def testTooLarge(self):                                          
        """toRoman should fail with large input"""                   
        self.assertRaises(roman.OutOfRangeError, roman.toRoman, 4000) 

    def testZero(self):                                              
        """toRoman should fail with 0 input"""                       
        self.assertRaises(roman.OutOfRangeError, roman.toRoman, 0)    

    def testNegative(self):                                          
        """toRoman should fail with negative input"""                
        self.assertRaises(roman.OutOfRangeError, roman.toRoman, -1)  

    def testNonInteger(self):                                        
        """toRoman should fail with non-integer input"""             
        self.assertRaises(roman.NotIntegerError, roman.toRoman, 0.5)  
unittest 模块中的 TestCase 类提供了 assertRaises 方法,它接受这几个参数:预期的异常、测试的函数,以及传递给函数的参数。(如果被测试函数有不止一个参数,把它们按顺序全部传递给 assertRaises ,它会把这些参数传给被测的函数。) 特别注意这里的操作:不是直接调用 toRoman 再手工查看是否引发特定异常 (使用 try...except捕捉异常),assertRaises 为我们封装了这些。所有你要做的就是把异常 (roman.OutOfRangeError)、函数 (toRoman) 以及 toRoman 的参数 (4000) 传递给 assertRaises ,它会调用 toRoman 查看是否引发 roman.OutOfRangeError 异常。(还应注意到你是把 toRoman 函数本身当作一个参数,而不是调用它,传递它的时候也不是把它的名字作为一个字符串。我提到过吗?无论是函数还是异常, Python 中万物皆对象)。
与测试过大的数相伴的便是测试过小的数。记住,罗马数字不能表示 0 和负数,所以你要分别编写测试用例 ( testZerotestNegative)。在 testZero 中,你测试 toRoman 调用 0 引发的 roman.OutOfRangeError 异常,如果没能 引发 roman.OutOfRangeError (不论是返回了一个值还是引发了其他异常),则测试失败。
要求 #3toRoman 不能接受非整数输入,所以这里你测试 toRoman 在输入 0.5 时引发 roman.NotIntegerError 异常。如果 toRoman 没有引发 roman.NotIntegerError 异常,则测试失败。

接下来的两个要求与前三个类似,不同点是他们所针对的是 fromRoman 而不是 toRoman

  1. fromRoman 应该能将输入的有效罗马数字转换为相应的阿拉伯数字表示。
  2. fromRoman 在输入无效罗马数字时应该失败。

要求 #4 与要求 #1 的处理方法相同,即测试一个已知样本中的一个个数字对。要求 #5 与 #2 和 #3的处理方法相同,即通过无效输入确认 fromRoman 引发恰当的异常。

例 13.4. 测试 fromRoman 的无效输入


class FromRomanBadInput(unittest.TestCase):                                      
    def testTooManyRepeatedNumerals(self):                                       
        """fromRoman should fail with too many repeated numerals"""              
        for s in ('MMMM', 'DD', 'CCCC', 'LL', 'XXXX', 'VV', 'IIII'):             
            self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s) 

    def testRepeatedPairs(self):                                                 
        """fromRoman should fail with repeated pairs of numerals"""              
        for s in ('CMCM', 'CDCD', 'XCXC', 'XLXL', 'IXIX', 'IVIV'):               
            self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)

    def testMalformedAntecedent(self):                                           
        """fromRoman should fail with malformed antecedents"""                   
        for s in ('IIMXCC', 'VX', 'DCM', 'CMM', 'IXIV',
                  'MCMC', 'XCX', 'IVI', 'LM', 'LD', 'LC'):                       
            self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)
没什么新鲜的,时时彩计划软件公式:与测试 toRoman 无效输入时相同的模式,只是你有了一个新的异常:roman.InvalidRomanNumeralErrorroman.py 中一共要定义三个异常 (另外的两个是 roman.OutOfRangeErrorroman.NotIntegerError)。稍后你在开始编写 roman.py 时将会知道如何定义这些异常。
时时彩自动挂机lm0 时时彩那种玩法最好 重庆时时彩缩水软件 易购彩票是不是骗局 彩客网
时时彩计划王黄金版 时时彩计划网站源码 旺旺时时彩软件下载 江西时时彩201607 紫光时时彩计划软件
大智慧时时彩软件 时时彩计算器 时时彩冷热软件 时时彩软件骗局私彩 时时彩四星稳赚方法
重庆时时彩视频直播器 时时彩最稳定的打法 腾龙时时彩老版本2.2 红河州时时彩骗局 时时彩后三跨度走势图
体育彩票新疆11选5 排列三 湖北福彩快三开奖结果查询 湖南快乐十分今日开奖 兽血沸腾txt下载
急速赛车 摩托 上海快三组合走势图计划卐上海市星光计划计划卐江苏快三遗漏数据计划卐快三中奖规则及奖金 山东十一选五9码 五分彩通过微信体现转账的 北京pk10投注网平台
湖北快3开奖直播 江苏11选5八码复式 棋牌斗牛怎么玩 云南时时彩lishi 北京11选五走势图
吉林快三历史遗漏 深圳风采中奖规则开奖 河北快3开奖结果 时间 百家 乐十注公式详细 南国彩票论坛41