Unittest框架的從零到壹(一)


前言

Python中有非常多的單元測試框架,如unittest、pytest、nose、doctest等,Python2.1及其以后的版本已經將unittest作為一個標准模塊放入Python開發包中。並且在pytest框架中,是可以兼容運行unittest的代碼的,簡單來說,就是學一頂倆。並且unittest也是比較簡單上手的,等unittest篇完結后,我們再開一個pytest篇。成為自動化測試大神指日可待🙊

認識斷言

單元測試本質上就是通過一段代碼去驗證另外一段代碼,那么這段驗證的代碼里,有一個起到關鍵作用的關鍵字,就是assert-斷言。assert(斷言)用於判斷一個表達式,在表達式條件為 false 的時候觸發異常。下面舉例說明一下用法

  • 來看看語法格式,一般assert后面跟一個條件和一個斷言失敗信息

    比如assert 1 == -1,'報錯就打印我出來'

    斷言失敗就會拋出AssertionError異常,並且把自定義的斷言失敗信息打印出來

    上面這條語句就等價於

    if not 1 == -1:
    		print("報錯就打印我出來")
        raise AssertionError
    

    看到這里的話應該很清晰了,所謂斷言就是判斷一個條件,條件不成立就會拋出異常,稱之為斷言失敗,反之就是斷言成功。

代碼初體驗

了解基本情況后,開始動手敲敲代碼吧,始終貫徹代碼驅動學習理念,只看是永遠學不會的!當然了天才除外👏🏻

先來創個項目,項目名就叫Study_unittest,直白易懂

image-20190928104758064

先創第一個py文件,名就叫calculator.py,在這里面創建計算器類。

#計算器類
class Calculator:
    "”用於完成兩個數的加、減、乘、除"""

    def __init__(self,a,b):
        self.a=int(a)
        self.b=int(b)

    # 加法
    def add(self):
        return self.a + self.b

    #減法
    def sub(self):
        return self.a - self.b

    #乘法
    def mul(self):
        return self.a * self.b

    #除法
    def div(self):
        return self.a / self.b

在定義好上面的 alculator.py程序之后,該程序就相當於一個模塊,接下來為該模塊編寫單元測試代碼。

創建test_calculator.py文件,下面就是測試用例的代碼:

import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):

    def test_add(self):
        c = Calculator(1, 2)
        result = c.add()
        self.assertEqual(result, 3)

    def test_sub(self):
        c = Calculator(5, 1)
        result = c.sub()
        self.assertEqual(result, 4)

    def test_mul(self):
        c = Calculator(5, 1)
        result = c.sub()
        self.assertEqual(result, 6)
    
    def test_div(self):
        c = Calculator(6, 2)
        result = c.sub()
        self.assertEqual(result, 3)
        
if __name__ == '__main__':
    unittest.main()

由上得知,unittest 要求單元測試類必須繼承 unittest.TestCase,該類中的測試方法需要滿足如下要求:

  • 測試方法不應該有返回值。
  • 測試方法不應該有任何參數。
  • 測試方法應以test 開頭。

運行結果如下:

image-20190928144251167

本次統計運行了4條測試用例,運行時間為0.139s,失敗(failures)了1條測試用例,成功(successes)了3條測試用例。失敗的測試用例也有清晰說明用例名稱以及錯誤的位置。

斷言方法

  • unittest.TestCase 內置了大量 assertXXX 方法來執行斷言,其中最常用的斷言方法如表 1 所示。

    斷言方法 檢查條件
    assertEqual(a, b) a == b
    assertNotEqual(a, b) a != b
    assertTrue(x) bool(x) is True
    assertFalse(x) bool(x) is False
    assertIs(a, b) a is b
    assertIsNot(a, b) a is not b
    assertIsNone(x) x is None
    assertIsNotNone(x) x is not None
    assertIn(a, b) a in b
    assertNotIn(a, b) a not in b
    assertlsInstance(a, b) isinstance(a, b)
    assertNotIsInstance(a, b) not isinstance(a, b)

    ​ 表 1 TestCase 中最常用的斷言方法

  • 除了上面這些斷言方法,如果程序要對異常、錯誤、警告和日志進行斷言判斷,TestCase 提供了如表 2 所示的斷言方法。

    斷言方法 檢查條件
    assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds) 引發 exc 異常
    assertRaisesRegex(exc, r, fun, *args, **kwds) fun(*args, **kwds) 引發 exc 異常,且異常信息匹配 r 正則表達式
    assertWarns(warn, fun, *args, **kwds) fun(*args, **kwds) 引發 warn 警告
    assertWamsRegex(warn, r, fun, *args, **kwds) fun(*args, **kwds) 引發 warn 警告,且警告信息匹配 r 正則表達式
    assertLogs(logger, level) With 語句塊使用日志器生成 level 級別的日志

    ​ 表 2 TestCase 包含的與異常、錯誤、警告和日志相關的斷言方法

  • TestCase 還包含了如表 3 所示的斷言方法用於完成某種特定檢查。

    斷言方法 檢查條件
    assertAlmostEqual(a, b) round(a-b, 7) == 0
    assertNotAlmostEqual(a, b) round(a-b, 7) != 0
    assertGreater(a, b) a > b
    assertGreaterEqual(a, b) a >= b
    assertLess(a, b) a < b
    assertLessEqual(a, b) a <= b
    assertRegex(s, r) r.search(s)
    assertNotRegex(s, r) not r.search(s)
    assertCountEqual(a, b) a、b 兩個序列包含的元素相同,不管元素出現的順序如何

    ​ 表 3 TestCase 包含的用於完成某種特定檢查的斷言方法

  • 當測試用例使用 assertEqual() 判斷兩個對象是否相等時,如果被判斷的類型是字符串、序列、列表、元組、集合、字典,則程序會自動改為使用如表 4 所示的斷言方法進行判斷。換而言之,如表 4 所示的斷言方法其實沒有必要使用,unittest 模塊會自動應用它們。

斷言方法 用於比較的類型
assertMultiLineEqual(a, b) 字符串(string)
assertSequenceEqual(a, b) 序列(sequence)
assertListEqual(a, b) 列表(list)
assertTupleEqual(a, b) 元組(tuple)
assertSetEqual(a, b) 集合(set 或 frozenset)
assertDictEqual(a, b) 字典(dict)

​ 表 4 TestCase 包含的針對特定類型的斷言方法

運行測試

在編寫完測試用例之后,可以使用如下兩種方式來運行它們:

  1. 通過代碼調用測試用例。程序可以通過調用 unittest.main() 來運行當前源文件中的所有測試用例。例如,在上面的測試用例中增加如下代碼:

    if __name__ == '__main__':
        unittest.main()
    
  2. 使用 unittest 模塊運行測試用例。使用該模塊的語法格式如下:

    python -m unittest 測試文件
    

    在使用 python -m unittest 命令運行測試用例時,如果沒有指定測試用例,該命令將自動查找並運行當前目錄下的所有測試用例。因此,程序也可直接使用如下命令來運行所有測試用例:

    py -m unittest
    

相信通過本篇文章,你對unittest有了基本的認識,該系列的文章也會做到簡潔通俗明了,讓大家更容易上手。

這一期就到這里了,下一期內容來介紹unittest的四大重點。喜歡的朋友可以收藏下來方便以后查看~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM