python之測試你的代碼

單元測試
  1. unittest包括Python標準庫中的測試模型。創建測試用例通過繼承unittest.Testcase來實現。
#簡單測試字符串的方法
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()
  1. 一個類繼承了unittest.TestCase就是創建了一個測試樣例。每一個測試的關鍵是調用assertEqual()來檢查預期的輸出,調用assertTrue()或者assertFalse()來驗證一個條件。調用assertRaises()來驗證拋出一個特定的異常。使用這些方法而不使用assert語句是爲了讓測試運行者能聚合所有測試結果併產生結果報告。
  2. 測試用例結構。在運行每一個測試用例的時候,setUp(),tearDown(),init()會被調用一次。如果同時存在多個前置操作相同的測試,我們可以把測試的前置操作從測試代碼中拆解出來,並實現測試前置方法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')

類似的,tearDown()方法在測試方法啊運行後進行清理工作。無論測試方法是否成功都會運行tearDown()。

import unittest

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

    def tearDown(self):
        self.widget.dispose()
  1. unittest.main()提供了一個測試腳本的命令行接口。unittest 模塊可以通過命令行運行模塊、類和獨立測試方法的測試
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
  1. unittest提供FunctionTestCase類,可用於打包已有的測試函數,並支持設置前置函數和後置函數。
#假設有一個測試函數
def testSomething():
    something = makeSomething()
    assert something.name is not None

#可以創建等價的測試用例,並且前置函數和後置函數
testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)
  1. 3.1版本支持跳過測試和預計測試用例失敗
    • @unittest.skip(reason) 跳過被這個裝飾器修飾的測試用例,reason表示原因(字符串)
    • @unittest.skipIf(condition, reason) 當condition爲True的時候,跳過被這個裝飾器修飾的測試用例
    • @unittest.skipUnless(condition, reason) 當condition爲False的時候,跳過被這個裝飾器修飾的測試用例,也就是condition成立的時候執行這個測試用例
    • @unittest.expectedFailure 把測試用例標記爲預計失敗,如果測試不通過,表示測試用例成功,測試通過,表示測試用例失敗
   #跳過的舉例
    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
        
        def test_maybe_skipped(self):
        	if not external_resource_available():
            	self.skipTest("external resource not available")
           # test code that depends on the external resource
        	pass
      
    #預計失敗的舉例
    class ExpectedFailureTestCase(unittest.TestCase):
    	@unittest.expectedFailure
    	def test_fail(self):
        	self.assertEqual(1, 0, "broken")
  1. 3.4版本的新功能,通過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

可以通過i的展示來尋找問題。

  1. testCase提供一些斷言的方法來檢查並報告故障
方法 檢查 版本
assertEqual(a,b,Msg=None) 檢查a,b是否相等
assertNotEqual(a,b,Msg=None) 檢查a.b.是否不相等
asserTrue(x) 檢查x是否爲真
asserFlase(x) 檢查是否爲假
assertIs(a,b) 檢查a.b是否是同類型 3.1
assertIsNot(a,b) 檢查a.b是否不是同類型的 3.1
asserIsNone(x) 檢查x是否爲None 3.1
assertIsNotNone(x) 檢查x是否不是None 3.1
assertIn(a,b) 檢查a是否在b中 3.1
assertNotIn(a,b) 檢查a是否不在b中的值 3.1
assertIsInstance(object,classinfo) 檢查如果object是classinfo的實例或者是其子類,則返回True 3.2
assertNotIsInstance(object,classinfo) 檢查如果object不是classinfo的實例或者是其子類,則返回True 3.2

unittest文檔參考鏈接

文檔測試
  1. python中有doctest模塊查找零碎文本,就像在Python中docstrings內的交互式會話,執行那些會話以證實工作正常。
#簡單的函數文檔測試
def square(x):
    """返回 x 的平方。

    >>> square(2)
    4
    >>> square(-2)
    4
    """

    return x + x

if __name__ == '__main__':
    import doctest
    doctest.testmod()

然後運行之後的命令行展示

**********************************************************************
File "test_doctest.py", line 7, in __main__.square
Failed example:
    square(-2)
Expected:
    4
Got:
    -4
**********************************************************************

doctets參考文檔

工具 py.test
#舉例有一個測試文件
# content of test_sample.py
def func(x):
    return x + 1

def test_answer():
    assert func(3) == 5

在這個文件目錄下運行

C:\Users\Administrator\Desktop\test>py.test
================================================= test session starts =================================================
platform win32 -- Python 3.7.6, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Administrator\Desktop\test
collected 1 item

test_doctest.py F                                                                                                [100%]

====================================================== FAILURES =======================================================
_____________________________________________________ test_answer _____________________________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_doctest.py:6: AssertionError
================================================== 1 failed in 0.03s ==================================================

py.test 參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章