python-unittest(8)

來源:互聯網
上載者:User

將晦澀難懂的測試分解成簡單的測試

本篇的目的是解說晦澀的測試不易一目瞭然,然後用一個例子將晦澀的測試案例化為簡單的測試案例,使得測試結果一目瞭然。

Breaking down obscure tests into simple ones.

Unittest provides the means to test the code through a series of assertions. I have often felt
the temptation to exercise many aspects of a particular piece of code within a single test
method. If any part fails, it becomes obscured as to which part failed. It is preferable to split
things up into several smaller test methods, so that when some part of the code under test
fails, it is obvious.

1. Create a new file named recipe8.py in which to put our application code for this
recipe.

2. Pick a class to test. In this case, we will use an alternative version of the Roman
numeral converter, which converts both ways.

3. Create a new file called recipe8_obscure.py in which to put some longer
test methods.

4. Create some test methods that combine several test assertions.

5. Run the obscure tests. Why did it fail? Where is the bug? It reports that II is not
equal to I, so something appears to be off. If this the only bug?

6. Create another file called recipe8_clear.py to create a more fine-grained set of
test methods.

7. Split up the assertions into separate test methods to give a higher fidelity of output.

8. Run the clearer test suite. Is it a bit clearer where the bug is? What did we trade in to
get this higher degree of test failure? Was it worth the effort?

測試代碼1:

Code# !usr/bin/env python 2.7# coding: utf-8# filename: recipe8.pyclass RomanNumeralConverter(object):    def __init__(self):        self.digit_map = {"M":1000, "D":500, "C":100, "L":50, "X":10, "V":5, "I":1}    def convert_to_decimal(self, roman_numeral):        val = 0        for char in roman_numeral:            val += self.digit_map[char]        return val    def convert_to_roman(self, decimal):        val = ""        while decimal > 1000:            val += "M"            decimal -= 1000        while decimal > 500:            val += "D"            decimal -= 500        while decimal > 100:            val += "C"            decimal -= 100        while decimal > 50:            val += "L"            decimal -= 50        while decimal > 10:            val += "X"            decimal -= 10        while decimal > 5:            val += "V"            decimal -= 5        while decimal > 1:            val += "I"            decimal -= 1        return val

 

Code# !usr/bin/env python 2.7# coding: utf-8# filename: recipe8_obscure.pyimport unittestfrom recipe8 import *class RomanNumeralTest(unittest.TestCase):    def setUp(self):        self.cvt = RomanNumeralConverter()    def test_convert_to_decimal(self):        self.assertEquals(0, self.cvt.convert_to_decimal(""))        self.assertEquals(1, self.cvt.convert_to_decimal("I"))        self.assertEquals(2010, \                          self.cvt.convert_to_decimal("MMX"))        self.assertEquals(4000, \                          self.cvt.convert_to_decimal("MMMM"))    def test_convert_to_roman(self):        self.assertEquals("", self.cvt.convert_to_roman(0))        self.assertEquals("II", self.cvt.convert_to_roman(2))        self.assertEquals("V", self.cvt.convert_to_roman(5))        self.assertEquals("XII", \                          self.cvt.convert_to_roman(12))        self.assertEquals("MMX", \                          self.cvt.convert_to_roman(2010))        self.assertEquals("MMMM", \                          self.cvt.convert_to_roman(4000))if __name__ == "__main__":    unittest.main()

 

結果輸出:(這樣的結果讓人弄不明白倒底哪些用例發生了錯誤,不如下面用例那樣的一目瞭然)

.F
======================================================================
FAIL: test_convert_to_roman (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_obscure.py", line 22, in test_convert_to_roman
    self.assertEquals("II", self.cvt.convert_to_roman(2))
AssertionError: 'II' != 'I'

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)
Process terminated with an exit code of 1

 

測試代碼2:

Code# !usr/bin/env python 2.7# coding: utf-8# filename: recipe8_clear.pyimport unittestfrom recipe8 import *class RomanNumeralTest(unittest.TestCase):    def setUp(self):        self.cvt = RomanNumeralConverter()    def test_to_decimal1(self):        self.assertEquals(0, self.cvt.convert_to_decimal(""))    def test_to_decimal2(self):        self.assertEquals(1, self.cvt.convert_to_decimal("I"))    def test_to_decimal3(self):        self.assertEquals(2010, \                          self.cvt.convert_to_decimal("MMX"))    def test_to_decimal4(self):        self.assertEquals(4000, \                          self.cvt.convert_to_decimal("MMMM"))    def test_convert_to_roman1(self):        self.assertEquals("", self.cvt.convert_to_roman(0))    def test_convert_to_roman2(self):        self.assertEquals("II", self.cvt.convert_to_roman(2))    def test_convert_to_roman3(self):        self.assertEquals("V", self.cvt.convert_to_roman(5))    def test_convert_to_roman4(self):        self.assertEquals("XII", \                          self.cvt.convert_to_roman(12))    def test_convert_to_roman5(self):        self.assertEquals("MMX", \                          self.cvt.convert_to_roman(2010))    def test_convert_to_roman6(self):        self.assertEquals("MMMM", \                          self.cvt.convert_to_roman(4000))if __name__ == "__main__":    unittest.main()

結果輸出:

.FFFFF....
======================================================================
FAIL: test_convert_to_roman2 (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_clear.py", line 30, in test_convert_to_roman2
    self.assertEquals("II", self.cvt.convert_to_roman(2))
AssertionError: 'II' != 'I'

======================================================================
FAIL: test_convert_to_roman3 (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_clear.py", line 33, in test_convert_to_roman3
    self.assertEquals("V", self.cvt.convert_to_roman(5))
AssertionError: 'V' != 'IIII'

======================================================================
FAIL: test_convert_to_roman4 (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_clear.py", line 37, in test_convert_to_roman4
    self.cvt.convert_to_roman(12))
AssertionError: 'XII' != 'XI'

======================================================================
FAIL: test_convert_to_roman5 (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_clear.py", line 41, in test_convert_to_roman5
    self.cvt.convert_to_roman(2010))
AssertionError: 'MMX' != 'MMVIIII'

======================================================================
FAIL: test_convert_to_roman6 (__main__.RomanNumeralTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "e:\study\python\4668_Code\Chapter 1\01\recipe8_clear.py", line 45, in test_convert_to_roman6
    self.cvt.convert_to_roman(4000))
AssertionError: 'MMMM' != 'MMMDCCCCLXXXXVIIII'

----------------------------------------------------------------------
Ran 10 tests in 0.001s

FAILED (failures=5)
Process terminated with an exit code of 1

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.