1. 程式人生 > >【手譯】中文版unittest官方文件

【手譯】中文版unittest官方文件

近日無聊,把unittest的官方文件翻譯了下。英文水平有限,勉強翻譯如下,如果有什麼錯誤,歡迎指出!

pyunit中文版

——基於python3.6.6rc1

1. unittest框架

unittest的設計靈感最初來源於Junit以及其他語言中具有共同特徵的單元框架。它支援自動化測試,在測試中使用setup(初始化)和shutdown(關閉銷燬)操作,組織測試用例為套件(批量執行),以及把測試和報告獨立開來。

為了實現這些,unittest以一種面向物件的方式產生了一些很重要的概念:

  • test fixture

fixture表示tests執行前需要做的準備工作以及結束後的清理工作。比如,建立臨時/代理資料庫、目錄或啟動一個伺服器程序。

  • test case

test case是單元測試中的最小個體。它檢查特定輸入的響應資訊。unittest提供了一個基礎類:TestCase,用來建立test case

  • test suite

test suitetest case的合集,通常用test suitetest case彙總然後一起執行。

  • test runner

test runner是一個執行器,它可以執case並提供結果給使用者。它可以提供圖形介面、文字介面或者返回一個值表示測試結果。

1.1. 示例

unittest模組提供了豐富的工具,用於組織和執行tests。本節演示了其中一小部分功能,但足以滿足大多數使用者的需要。

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()

使用unittest.TestCase的子類建立了一個case。其中有三個test開頭的測試方法,這種命名方式可以告訴執行器(test runner哪些方法可以被執行。也就是說test開頭的測試方法才會被執行。

這些測試方法中都使用了assertEqual()來判斷預期值,使用assertTrue()assertFalse()來驗證條件,或使用assertRaises()來驗證某個具體的被丟擲的異常。這些斷言方法經常被用來替代assert,這樣執行完成後,所有的測試結果都會被記錄並寫進報告。

setUp()tearDown()方法可以實現在測試執行前後做一些其他工作,具體使用情況下面提出。

最後這部分展示了一個最簡單的執行測試的方式。

unittest.main()提供了一個命令列介面,當使用命令列執行測試完成後,大致會列印如下資訊:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

使用-v引數將可以顯示更多資訊。如下:

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

上面的例子展示了unittest中最常用的功能特徵,這些足以應付平時的需要。文件的剩餘部分將從頭開始講解所有unittest的內容。

1.2. 命令列

unittest模組支援從命令列執行模組中的測試、類,甚至是單獨的測試方法。

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

可以將模組名和有效的類或方法名組合在一起執行。

模組也可以是帶路徑的方式:

python -m unittest tests/test_something.py

你也可以使用檔名代替測試模組名。指定的檔案必須是可匯入的。路徑就是去掉.py”後的檔名,檔名和模組名之間使用“.”連線。如果你要執行的測試檔案不能被作為模組匯入,也可以直接執行該檔案。

通過傳入-v選項,你可以檢視更多的執行細節:

python -m unittest -v test_module

當命令列中不傳入任何執行目標時,預設執行Test Discovery中的測試:

python -m unittest

檢視所有命令引數:

python -m unittest -h

該功是能在3.2版本中新增的。早期的版本只能執行單獨的測試方法,不能執行模組和測試類。

1.2.1. 命令列選項

unittest支援以下命令列選項:

-b--buffer

當測試在執行時,輸出的錯誤資訊被快取在記憶體中,如果測試執行通過,則釋放快取,如果測試失敗,資訊就會被打印出來。

-c--catch

在測試執行時按下Control-C將會等待當前測試完成並輸入所有測試報告。第二次按下Control-C就會觸發KeyboardInterrupt異常。

-f--failfast

測試一旦出現錯誤或失敗就停止執行。

--locals

在異常回溯中列印本地變數資訊。

命令列選項-b-c-f3.2版本中新增。

命令列選項--locals3.5版本中新增。

命令列選項也可以在Test Discovery中使用,所有專案中的測試都可以使用。

1.3. Test Discovery

3.2版本中新增。

unittest支援簡單的測試發現功能。為了相容test discovery,所有的測試檔案必須是能從專案的頂層目錄匯入的模組或包(包括名稱空間包),意思就是檔名必須是有效的識別符號。

Test DiscoveryTestLoader.discover()中實現,但是仍能用於命令列模式。基本使用方法如下:

cd project_directory
python -m unittest discover

注意:python -m unittest雖然作用和python -m unittest discovery一樣。但是如果要傳遞引數給discover的話還是要寫完整的命令。

選項:

-v--verbose

詳細的輸出

-s--start-directory 目錄

Discovery尋找的其實目錄(預設.

-p--pattern 模式

匹配的測試檔案的格式(預設test*.py

-t--top-level-directory 目錄

專案的頂級目錄(directory的預設起始目錄)

-s-p-t選項可以作為位置引數,以下兩個命令是等效的:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

可以使用傳遞一個包名路徑,比如myproject.subpackage.test作為初始目錄。這樣的話,這個包就會被匯入,包的路徑就會被當做初始目錄。

注意:Discovery通過匯入的方式來載入測試。一旦test discovery從你提供的初始目錄中發現了所有的測試檔案,它就會將路徑轉換成包名匯入,比如foo/bar/baz.py會被當做foo.bar.baz進行匯入。

如果你有一個在公共的包並且使用test discovery去載入該包的另一個不同副本,那麼就會引發異常,導致discovery退出。

如果你提供了一個起始目錄作為包名稱而不是提供一個路徑作為目錄,那麼discovery就會認為所有位置的檔案都是你需要匯入的(包括中間路徑),這樣就不會報錯。

測試模組和包通過load_tests協議以指定的方式載入測試和執行discover

3.4版本中修改:Test discovery支援名稱空間包。

1.4. 組織測試程式碼

單元測試中最基本的組成是test cases——單一的測試邏輯場景以及正確性校驗。在unittest中,test casesunittest.TestCae的例項替代。要編寫你自己的測試用例就必須寫一個TestCase的子類或者使用FunctionTestCase

一個TestCase例項的測試程式碼必須是完整且自包含的,這樣它就可以單獨執行或者和其他用例組合執行。

最簡單的TestCase子類只需實現一個測試方法(名字以test開頭)就可以實現對特定測試程式碼的執行:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

注意,為了測試我們使用了TestCase基類裡面的assert*()的方法。如果測試失敗,就會丟擲一個異常並且顯示具體資訊,unittest就認為該測試失敗。任何的異常都被視為錯誤。

當測試比較多的時候,測試的初始化就顯得重複冗餘。我們可以將這部分單獨拿出來,然後通過實現一個setUp()方法,測試框架會自動的在每個測試執行前執行該方法。

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

注意:這種方式執行時,各測試方法的執行順序是根據方法名字串形式進行排序的。

當測試進行時,如果setUp()方法引發異常,框架會認為該測試遇到了錯誤,測試方法就不會被執行。

同樣的,我們可以提供一個tearDown()方法,在測試執行完成後執行:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()

只要setUp()執行成功了,那麼不管測試方法是否成功,tearDown()方法都會執行。

對於測試程式碼來講,這樣的工作機制成為Test Fixture。一個新的TestCase例項被當做Test Fixture建立,用於執行每個測試方法。也就是說,TestCase.setUpTestCase.tearDownTestCase.__init__會在每個用例執行前執行一次。

建議使用TestCase去根據測試的特性對其進行分組。對此,unittest提供了一個機制:測試套件(test suit),由unittestTestSuit類實現。如果測試很多的話,呼叫unittest.main()方法就可以收集模組中所有的測試方法並執行。

如果你想要自定義測試套件的內容,你可以這麼做:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

你可以將測試用例或者測試套件寫在被測試的程式碼中,但是並不建議這麼做。應該將測試部分單獨寫在一個檔案,這麼做有以下好處:

  • 測試模組可以單獨在命令列執行
  • 測試程式碼部分可以更容易的單獨拿出來
  • 不會為了迎合被測試的程式碼而隨意修改測試程式碼
  • 測試程式碼會更少的修改
  • 被測試程式碼重構更容易
  • C寫的模組測試的程式碼必須是單獨的模組,那麼為什麼不保持一直呢?
  • 如果測試策略改變了,不需要去修改原始碼

1.5. 使用舊的測試程式碼

一些使用者會發現現存的一些舊的測試程式碼並不是TestCase的子類,但是仍需要執行。

基於此,unittest提供了FunctionTestCase類。TestCase的子類可以直接包含這些舊的測試類,並且同樣可以實現用例的setUp()初始化和tearDown()銷燬操作。

例如:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

此時可以建立一個等效的測試用例如下,包含set-up和tear-down方法:

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

注意:雖然FunctionTestCase可以很快的將普通測試方法轉換成單元測試,但一般不建議這麼做。儘量花時間去構造TestCase的子類作為測試將會使的以後的程式碼重構變得容易。

有時候,已有的測試是使用doctest寫的。如果這樣的話,doctest提供了一個DocTestSuites類,可以自動的將該測試轉換成unittest.TestSuite例項。

1.6. 跳過失敗的測試

版本3.1中新增。

Unittest支援跳過單個測試以及整個測試類。此外,還支援將一個測試標記為“預計失敗”,表示該測試有問題,但是這個失敗不會在TestResult中記錄。

跳過一個測試很簡單,只需使用skip()或者附帶一些條件判斷的skip()

一般的跳過是這樣的:

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

以下是執行的結果輸出:

test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 3 tests in 0.005s

OK (skipped=3)

類的跳過和方法一樣:

@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

TestCase.setUp()也可以設定跳過測試,這在將一些資源設定為不可用時非常實用。

對於預期的失敗使用exceptedFailture()裝飾器:

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

你也可以自定義一個跳過裝飾器,通過在測試上設定一個skip()的裝飾器。這個裝飾器會直接跳過該測試,除非其有某個特殊屬性。

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

以下這些裝飾器實現了跳過測試以及預期失敗的功能:

@unittest.skip(reason)

直接跳過被裝飾的測試,reason是描述跳過的原因。

@unittest.skipIf(condition, reason)

如果if的條件成立則跳過測試。

@unittest.skipUnless(condition, reason)

除非條件為真,否則跳過測試。

@unittest.expectedFailure

標記測試為失敗,如果在執行時失敗,則不會在結果中統計。

exception unittest.SkipTest(reason)

跳過測試丟擲的異常。

通常你可以使用TestCase.skipTest()或者上述裝飾器中的某一個來替代這種拋異常的做法。如果測試被跳過,則不會執行setUp()tearDown()方法;如果類被跳過,則不會執行setUpClass()tearDownClass()方法;如果模組被跳過,則不會執行setUpModule()tearDownModule()方法。

1.7. 使用subTest()

版本3.4中新增。

當部分測試只有細微的差別時,比如引數,unittest支援直接在測試方法內部使用subTest()上下文管理器來實現:

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

輸出為:

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

但是如果不使用subTest()的話,測試會在第一次失敗時就退出,並且錯誤資訊不是很明白,比如該例中的i就無法識別:

======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

1.8. 類和方法

這個章節將深度講解unittestAPI部分。

1.8.1. Test Cases

unittest.TestCase(methodName=’runTest’)

unittest系統中,TestCase的例項就是邏輯測試單元。該類作為一個基類,其特性和功能通過建立子類類得以實現。類內部實現了一些介面,可以讓test runner驅動測試,以及測試中可以使用一些方法來斷言和報告各種失敗情況。

每一個TestCase的例項執行時都是執行一個方法:該方法名就是methodName。在大多數情況下,你都不需要修改methodName,也不需要重新實現runTest()方法。

版本3.2中修改內容:TestCase可以不需要methodName就進行例項化,這使得TestCase在互動式平臺上更容易使用。

TestCase的例項的方法可以分為3種:一種是用來執行測試的;一種是用來實現條件斷言和失敗報告的;還有一部分是用來收集測試本身的一些資訊。

第一種方法大致有:

setUp()

該方法負責Test Fixture中的準備工作,一般在測試執行前呼叫;除了AssertionErrorSkipTest以外,該方法觸發的其他異常均被是做錯誤處理而不是測試失敗,該方法預設沒有操作。

tearDown()

該方法在測試方法被執行並且結果記錄後立即被呼叫。如果測試方法出現異常,子類實現的功能就需要特別的檢查。任何異常,除了AssertionErrorSkipTest,只要是該方法丟擲的異常都會被視為其他錯誤而不是測試失敗(會在報告中統計)。該方法只有在setUp()執行成功時才會呼叫,而跟測試的結果無關。預設該方法沒有操作。

setUpClass()

當類中的測試方法被執行前會被呼叫的一個類方法。該方法只會在類方法前呼叫,也就是帶有calssmethod裝飾器並且沒有其他引數的方法。

@classmethod
def setUpClass(cls):
    ...

版本3.2中新增。

tearDownClass()

當類測試方法被執行完後會被呼叫的一個類方法。該方法只會在一個類的所有方法執行完成後呼叫,該方法被呼叫時,必須有calssmethod裝飾器並且除了類以外沒有其他引數的方法。

@classmethod
def tearDownClass(cls):
    ...

版本3.2中新增。

run(result=None)

執行測試,並收集資訊作為結果傳遞給TestResult物件。如果結果為空,一個臨時的報告檔案就會被呼叫的defaultTestResult()方法建立並使用。然後將結果物件返回。

通過簡單的呼叫TestCase例項可以達到相同的效果。

版本3.3中修改:早期的run版本中不會返回測試結果,也不會呼叫例項。

SkipTest(reason)

當需要跳過一個測試方法時,可以在測試方法或setUp()中呼叫該方法。

版本3.1中新增。

subTest(msg=None,**params)

把一個封閉的程式碼塊當做subTest執行並返回上下文管理器。msgparams是可選的,主要用來顯示資訊,以方便測試執行異常時定位問題。

一個測試中可以包含任意個subTest,並且可以多層巢狀。

版本3.4中新增。

debug()

執行測試但不生成報告。這樣執行測試時會直接丟擲異常,可以在除錯模式下使用。

TestCase提供了很多斷言方法,以下是常用的:

 

nsRegex()方法被當做上下文管理器使用時才能被其使用。

assertEqual(first,second,msg=None)

測試第一個引數和第二個引數是否相等。如果比較不一致,則測試失敗。

此外,如果兩個引數都是同一種類型,且都是某種列表型別的話,addTypeEqualityFunc()會被呼叫用以顯示更多的錯誤資訊。

版本3.1修改:新增自動呼叫特定對比方法。

assertNotEqual(first,second,msg=None)
判斷兩個引數不相等。如果相等的話,則測試失敗。

assertTrue(expr,msg=None)

assertFalse(expr,msg=None)

測試expr是否為真(或假)。

注意:上述方法等同於bool(expr) is True,但不等同於expr is True(或者使用assertIs(expr,True))。當有更多具體的方法可用時應當避免使用上述方法(比如,使用assertEqual(a,b)而不是assertTrue(a==b)),因為這些具體的方法會提供更多的錯誤失敗資訊。

assertIs(first,second,msg=None)

assertIsNot(first,second,msg=None)

測試第一個引數和第二個引數是否同一個物件。

版本3.1中新增。

assertIsNone(expr,msg=None)

assertIsNotNone(expr,msg=None)

測試expr是否為None

版本3.1中新增。

assertIn(first,second,msg=None)

assertNotIn(first,second,msg=None)

測試引數一是否包含在引數二中。

版本3.1中新增。

assertIsInstance(obj,cls,msg=None)

assertNotIsInstance(obj,cls,msg=None)

測試obj是否為cls的例項(cls可以是一個類或者類組成的元組),檢查具體的物件型別使用assertIs(type(obj),cls)

版本3.2中新增。

還可以使用如下方法檢查異常、警告和日誌資訊:

 

assertRaises(exception,callable,*args,**kwds)

assertRaises(exception,msg=None)

測試callable傳入某些引數並呼叫時引發的異常。如果exception異常被丟擲,表示測試通過。如果丟擲的是另一種異常或無異常則表示測試失敗。如果需要捕捉一組異常時,exception也可以是一個異常型別組成的元組。

如果引數只傳遞了exception引數,或者也有msg,這樣就可以在with上下文管理器中測試程式碼塊而不需要在方法中:

with self.assertRaises(SomeException):
    do_something()

當使用上下文管理器時,assertRaises()接收一個額外的引數msg

上下文管理可以將捕捉到的異常儲存在exception屬性中,這樣當異常發生時,可以做進一步檢查:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

版本3.1修改:新增assertRaises()可以作為上下文管理器使用。

版本3.2修改:新增exception屬性。

版本3.3修改:當作為上下文管理器使用時新增msg引數。

assertRaisesRegex(exception,regex,callable,*args,**kwds)

aseertRaisesRegex(exception,regex,msg=None)

類似於assertRaises(),不過這裡需要匹配regex和捕捉異常的資訊是否匹配。regex可以是普通的正則表示式,或是一個包含正則表示式的字串。例如:

self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
                       int, 'XYZ')

with self.assertRaisesRegex(ValueError, 'literal'):
   int('XYZ')

版本3.1新增:asserRaisesRegexp

版本3.2修改:重新命名為assertRaiseRegex()

版本3.3修改:當作為上下文管理器使用時新增msg引數。

assertWarns(warning,callable,*args,**kwds)

assertWarns(warning,mag=None)

callable被傳入引數呼叫時,測試其觸發的警告。如果觸發異常則表示測試成功,否則失敗。如果想要測試一組警告,可以在warning出傳入包含警告類的元組。

如果有了warning引數,甚至msg引數,那麼此時可以直接在with程式碼塊下測試程式碼,而不需要在方法中使用:

with self.assertWarns(SomeWarning):
    do_something()

上下文管理器會把捕捉的警告資訊儲存在warning屬性中,觸發警告的原始碼行儲存在filenamelineno屬性中。這些資訊在觸發警告後檢查時很有用:

with self.assertWarns(SomeWarning) as cm:
    do_something()

self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)

該方法被呼叫時就會執行,無論警告過濾器是否就位。

版本3.2中新增。

版本3.3修改:當作為上下文管理器使用時新增msg引數。

assertWarnsRegex(warning,regex,callable,*args,**kwds)

assertWarnsRegex(warning,regex,msg=None)

類似於assertWarns(),不過這裡還需要測試regex是否匹配警告資訊。regex可以是正則表示式也可以是一個包含正則表示式的字串:

self.assertWarnsRegex(DeprecationWarning,
                      r'legacy_function\(\) is deprecated',
                      legacy_function, 'XYZ')

with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
    frobnicate('/etc/passwd')

版本3.2中新增。

版本3.3中修改:作為上下文管理器使用時新增msg引數。

assertLogs(logger=None,level=None)

在上下文管理器中使用,測試至少有一條資訊被記錄在logger中,且最低級別是level

如果引數logger被給定,logger將是一個logging.Logger物件,或者logger的名字。預設是root記錄器,會記錄所有資訊。

如果給定的話,level可以是數字,表示日誌記錄級別,也可以是字串格式(比如“error”和logging.ERROR)。預設是logging.INFO

with程式碼塊中,只要有一條資訊和loggerlevel匹配則表示測試成功,否則失敗。

上下文管理器返回的物件是一個記錄器,記錄了匹配的日誌資訊記錄。包含兩個屬性:

records

一個匹配日誌資訊的logging.LogRecord物件列表。

output

匹配到的資訊的格式化輸出。

例:

with self.assertLogs('foo', level='INFO') as cm:
   logging.getLogger('foo').info('first message')
   logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

版本3.4中新增。

還有其他執行具體斷言的方法:


assertAlmostEqual(first,second,places=7,msg=None,delta=None)

assertNotAlmostEqual(first,second,places=7,msg=None,delta=None)

測試引數1和引數2是否約等。小數點保留位數為places(預設7)。

如果delta被提供(替代places),表示引數1和引數2之間的差異必須小於delta

如果placesdelta同時存在時觸發TypeError

版本3.2修改:assertAlmostEqual()自動識別相似的物件進行比較。如果物件比較一致則assertAlmostEqual()自動失敗。新增delta引數。

assertGreater(first,second,msg=None)

assertGreaterEqual(first,second,msg=None)

assertLess(first,second,msg=None)

assertLessEqual(first,second,msg=None)

正如方法名含義,比較引數1和引數2之間是否存在>>=<或者<=關係。

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

版本3.1新增。

assertRegex(text,regex,msg=None)

assertNotRegex(text,regex,msg=None)

測試regex是否匹配text。如果匹配失敗,錯誤資訊會包含匹配模式和text(或者部分匹配不成功的text)。regex為一般的正則表示式或者可以被re.search()識別的其他字串格式。

版本3.1新增:命名為assertRegexpMatches

版本3.2修改:重新命名為assertRegex()

版本3.2新增:assertNotRegex()

版本3.5新增:assertNotRegexpMatches被棄用。

assertCountEqual(first,second,msg=None)

測試序列first中的元素是否和second中的一致,不考慮排序。如果不同,會生成詳細的錯誤清單。

在比較時,重複的元素不會被忽略。等效於:assertEqual(Counter(list(first)),Counter(list(second))),只適用於序列。

版本3.2新增。

assertEqual()方法為同類型物件的比較提供了多種具體的比較方法。這些方法大多數都已經在內建方法實現,但是你仍可以使用addTypeEqualityFunction()方法新註冊一個方法:

addTypeEqualityFunc(typeobj,function)

註冊一個被assertEqual()呼叫的特定型別的方法,用以判斷兩個相同型別的物件(不是子類)是否相等。function必須有2個形參,還有一個msg=None引數,和assertEqual()中使用方法一樣。當2個引數比較第一次出現不相等時就引發self.failureException(msg)異常,這可能會提供一些有用的資訊,並在錯誤資訊中解釋哪裡不同。

版本3.1新增。

assertEqual()方法會自動的呼叫下面列表中的方法。但是通常沒有必要直接呼叫這些方法:


assertMultiLineEqual(first,second,msg=None)

測試多行字串first是否等同於字串second。當不相同時,不一致的地方會在錯誤資訊中高亮顯示。使用assertEqual()方法比較字串時,這個方法會被預設呼叫。

版本3.1新增。

assertSequenceEqual(first,second,msg=None,seq_type=None)

測試兩個序列是否相等。如果seq_type被提供,引數1和引數2都必須是seq_type的例項,否則引發異常。如果兩個序列不等,會在錯誤資訊中顯示不同。

版本3.1新增。

assertListEqual(first,second,msg=None)

assertTupleEqual(first,second,msg=None)

測試列表或者元組是否相等。如果不同,會列印錯誤資訊並顯示不同之處。當引數型別錯誤時仍會報錯。這些方法通常是在比較列表和元組時被assertEqual()預設呼叫。

assertSetEqual(first,second,msg=None)

測試集合是否相等。如果不同,會列印錯誤資訊並顯示不同之處。該方法通常是在比較集合和frozensets時被assertEqual()預設呼叫。

版本3.1新增。

assertDictEqual(first,second,msg=None)

測試字典是否相等。如果不同,會列印錯誤資訊並顯示不同之處。該方法通常是在比較字典時被assertEqual()預設呼叫。

版本3.1新增。

最後,TestCase提供了一下方法和屬性:

fail(msg=None)

當某個測試失敗時,可以將msg提供給錯誤資訊。

failureException

該類屬性提供了測試方法丟擲的異常。如果測試框架需要一個特定的異常,比如攜帶更多的資訊,就必須在子類中實現該異常。該屬性的初始值為AssertionError

longMessage

這個類屬性決定了當一個自定義失敗資訊被當做msg引數傳遞給assertXYY等方法時該做什麼。預設值是True。這種情況下,自定義的資訊被新增到標準失敗資訊後面。當值為False時,自定義資訊會覆蓋標準資訊。

在每個測試方法中,可以重寫該屬性:呼叫assert方法之前,分配例項屬性self.longMessage的值為TrueFalse

每次測試執行前該設定都會被重置。

版本3.1新增。

maxDiff

該屬性決定了assert方法結果中差異資訊的顯示長度。預設有80*8個字元。受此影響的方法有assertSequenceEqual()(包括所有序列的比較方法),assertDictEqual()assertmultiLineEqual()

如果maxDiff設定為None時,表示沒有最大長度。

版本3.2

相關推薦

中文版unittest官方

近日無聊,把unittest的官方文件翻譯了下。英文水平有限,勉強翻譯如下,如果有什麼錯誤,歡迎指出!pyunit中文版——基於python3.6.6rc11. unittest框架unittest的設計靈感最初來源於Junit以及其他語言中具有共同特徵的單元框架。它支援自動

Android官方翻譯Android官方-Activities(一)

Activity是可以給使用者提供互動操作的程式元件,例如打電話,拍照,傳送郵件,抑或者是顯示地圖。通常視窗會填滿螢幕,但是也可以做到比螢幕小或者是懸浮在視窗頂部。 App通常由多個Activities組成,它們之間支援相互跳轉。一般情況下,每個Activit

日常錯誤spring-boot配置讀取不到

無法 pan factory sdn 一個 pre nco span xxx 最近在用spring-boot做項目時,遇到自定義的配置文件無法讀取到的問題,通過在appcation.java類上定義@PropertySource(value = {"classpath:XX

Spark篇---Spark中Shuffle的尋址

sta lock exe 數據 小文件 默認 節點 刪除 提高 一、前述 Spark中Shuffle文件的尋址是一個文件底層的管理機制,所以還是有必要了解一下的。 二、架構圖 三、基本概念: 1) MapOutputTracker MapOutputTracker是Spa

Python庫ReportLab生成PDF

Python庫 >> ReportLab 一、安裝   可以嘗試pip install或者yum install來安裝reportlab庫,這裡介紹手動安裝的過程 【2】使用

小白javascript中的“已完成載入後執行 document.write,整個 HTML 頁面將被覆蓋”

document.write已經遇到過好幾次了,還是得弄弄清楚。 W3cschool上面有一道練習題,如下(圖片1) 結果輸入的時候h1跟p段落全部被覆蓋,只有語句“糟糕!文件消失了” 圖片中出現

小松教你遊開發unity實用技能unity所有特殊夾的用途(轉自雨松momo)

unity實用技能這裏列舉出手遊開發中用到了所有特殊文件夾。 Unity3D研究院之手遊開發中所有特殊的文件夾 - 雨松MOMO程序研究院 1.Editor Editor文件夾可以在根目錄下,也可以在子目錄裏,只要名子叫Editor就可以。比如目錄:/xxx/xxx/Editor 和 /Editor 是一

AutoMapper官方(二)升級指南

初始化 您現在必須使用Mapper.Initialize或new MapperConfiguration()來初始化AutoMapper。如果您希望保持靜態使用,請使用Mapper.Initialize。 如果你有很多的Mapper.CreateMap呼叫,把它們移動到一個Profile,或者Mapper

pySerial3.4官方6、示例

示例 Miniterm  Miniterm現在可用作模組而不是示例。有關詳細資訊,請參閱serial.tools.miniterm。 miniterm.py miniterm計劃。 setup-miniterm-py2exe.py 這是Windows的py2exe安

pySerial3.4官方4、工具

工具 serial.tools.list_ports  可以執行此模組以獲取埠列表()。它還包含以下功能。python -m serial.tools.list_ports serial.tools.list_ports.comports(include_l

pySerial3.4官方3、pySerial API

pySerial API  類 本地埠 類serial.Serial __init__(port = None,baudrate = 9600,bytesize = EIGHTBITS,parity = PARITY_NONE,stopbits = STOPBITS_ONE

pySerial3.4官方2、簡介

簡介 開啟串列埠 開啟“9600,8,N,1”的埠,沒有超時: >>> import serial >>> ser = serial.Serial('/dev/ttyUSB0') # open serial port >>> pri

Gradle官方翻譯起步2:建立構建掃描

構建掃描是對構建的可分享的專門記錄,可以看到“構建中發生了那些行為以及為什麼會發生這種行為”。通過在專案中使用構建掃描外掛,開發者可以免費地在https://scans.gradle.com/上釋出構建掃描。 將要建立的 本文會展示如何在不對任何構建指令碼進行

Redis Cluster官方教程

摘要這篇文章主要介紹redis cluster可用性和一致性相關的特性,值得一提的是,redis cluster需要高於等於redis3.0版本。 概要 這篇文章主要介紹redis cluster可用性和一致性相關的特性,值得一提的是,redis cluster需要高於等於r

cocos2d-js官方十七、事件分發機制

簡介 遊戲開發中一個很重要的功能就是互動,如果沒有與使用者的互動,那麼遊戲將變成動畫,而處理使用者互動就需要使用事件監聽器了。 總概: 事件監聽器(cc.EventListener) 封裝使用者的事件處理邏輯事件管理器(cc.eventManager) 管理使用者註

Vue.jsVue官方學習-Vue例項

一、建立一個Vue例項 var vm = new Vue({ // 選項 }) 每個Vue應用程式都是通過Vue函式創建出一個新的Vue物件開始的。 通常我們使用變數 vm (ViewModel 的簡稱) 來表示 Vue 例項。 在建立一個 Vu

ABP官方(一)入門介紹

1.1 ABP總體介紹 - 入門介紹 ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 ASP.NET Boilerplate是一個用最佳實踐和流行技術開發現代WEB應用程式的新起點,它旨在成為一個通用的

微信小程式--官方補充操作反饋--modal元件

modal彈出框常用在提示一些資訊比如:退出應用,清楚快取,修改資料提交時一些提示等等。 常用屬性: wxml <!--監聽button點選事件--><buttonbindtap="listenerButton"type="primary">彈出modal</but

cocos2d-js官方一、搭建 Cocos2d-JS 開發環境

在本文中,我將展示如何在 Mac os 10.9(Maverics) 上搭建 Cocos2d-JS 開發環境。 下載必備的軟體包 下載並安裝WebStorm7。WebStorm7目前的穩定版本是7.0.3。為什麼我們選擇WebStorm?因為它提供了許多功能,如Jav

cocos2d-js官方十九、Cocos2d-JS單檔案引擎使用指引

這篇指引主要介紹如何使用從線上下載工具下載下來的Cocos2d-JS的單檔案引擎。 你有可能下載了下面三個版本中的一個: Cocos2d-JS Full Version: 完整版引擎包含Cocos2d-JS引擎的所有功能特性以及所有擴充套件,使用這個版本可以幫助你發掘