2016-05-26 51 views
9

問題:多個異常和代碼覆蓋時單元測試蟒

下面是代碼的被測人爲例如:

from datetime import datetime 

def f(s): 
    try: 
     date = s.split(":")[1] 
     return datetime.strptime(date, "%Y%m%d") 
    except (ValueError, IndexError) as e: 
     # some code here 
     raise 

下面是一組測試我現在有:

from datetime import datetime 
import unittest 

from test_module import f 

class MyTestCase(unittest.TestCase): 
    def test_valid_date(self): 
     self.assertEqual(f("1:20130101"), datetime(2013, 1, 1)) 

    def test_invalid_date(self): 
     self.assertRaises(ValueError, f, "1:invalid") 

測試通過,如果我運行--branch標誌的覆蓋範圍,我會得到100%行和分支覆蓋

$ coverage run --branch -m unittest test 
.. 
---------------------------------------------------------------------- 
Ran 2 tests in 0.003s 

OK 
$ coverage report 
Name   Stmts Miss Branch BrPart Cover 
-------------------------------------------- 
test_module.py  7  0  0  0 100% 
-------------------------------------------- 
TOTAL    7  0  0  0 100% 

但是,請注意,測試檢驗當前只有兩種情況 - 當沒有拋出異常,且有ValueError異常升高。

問題:

是否有coverage辦法報表時IndexError升起,我沒有測試的情況下?

+0

您可以爲IndexError創建一個不同的塊。我認爲覆蓋範圍只是計算哪些行已被執行。 –

回答

8

Coverage.py只能測量運行哪條執行路徑(語句或分支)。它無法跟蹤使用的值,包括引發的異常類型。

在我看來,你的選擇是:

  1. 獨立的例外條款。在你所展示的代碼中,這兩個例外可以通過單獨的行來提出,但也許在你真實的代碼中,它們是不可分離的。

  2. 不要擔心兩個例外。您對此代碼的測試可能會考慮許多不同的輸入,旨在鍛鍊不同的邊緣情況。 Coverage.py無法幫助您區分所有這些問題,或者確保您已經編寫了足夠的案例。使用其他標準來決定你寫了足夠多的測試用例。

+0

好的,非常感謝。祝你在PyCon上談論你的好運! – alecxe

1

我想你可以嘗試除兩個例外以外的兩個單獨的。在這種情況下,行覆蓋顯示您沒有測試過一種情況。

from datetime import datetime 

def f(s): 
    try: 
     date = s.split(":")[1] 
     return datetime.strptime(date, "%Y%m%d") 
    except ValueError as e: 
     # some code here 
     raise 
    except IndexError as e: 
     # some code 
     raise 

如果您不想重複您的某些代碼,您可能可以使用該功能。

+0

這絕對是一種選擇,但如果coverage(或其他包)能夠在不改變被測代碼的情況下確定未經測試的執行路徑,那麼我的好奇心仍然存在這個問題。謝謝! – alecxe

相關問題