XUnit測試框架-Python unittest


選擇

語言選擇

本次個人作業我選擇的語言是Python,了解學習Python有一段時間了但是一直沒有練習,所以這次玩蛇,使用的版本是Python3.6。

開發工具選擇

我選擇的IDE是Pycharm,個人認為Pycharm是一款不錯的Py開發工具,用起來得心應手,unittset是py自帶的包不需要安裝直接引用即可,方便快捷。開發工具截圖如下。

Python單元測試框架unittest

unittest簡介

TestCase(測試用例)

一個testcase就是一個測試用例,包括測試前環境的搭建setUp,執行測試代碼run,測試后環境的還原tearDown,是一個完整的測試單元。

TestSuite(測試套件)

多個testcase的集合

TestLoder

用來加載TestCase到TestSuite中

TextTestRunner

是來執行測試用例的

TextTestResult

保存測試結果的類

TestFixture

測試准備前和執行后要做到的工作

核心工作原理

工作原理

unittest實例

准備待測方法

mathfunc.py

def  add(a,b):
    return a+b

def minus(a,b):
    return a-b

def multi(a,b):
    return a*b

def divide(a,b):
    return a/b

編寫測試方法

test_mathfunc.py

import unittest
from mathfunc import *

class TestMathFunc(unittest.TestCase):
    #每個測試方法以test開頭
    def test_add(self):
        self.assertEqual(3,add(1,2))
        self.assertNotEqual(3,add(2,2))

    def test_minus(self):
        self.assertEqual(1,minus(3,2))

    def test_multi(self):
        self.assertEqual(6,multi(2,3))

    def test_divide(self):
        self.assertEqual(2,divide(6,3))
        self.assertEqual(2.5,divide(5,2))

if __name__ == '__main__':
    #verbosity  輸出詳細程度 0 1 2
    unittest.main(verbosity=2)

運行結果

測試通過

測試通過

測試不通過

把除法/改為//(整除)報錯如下圖
測試報錯

TestSuite

上面的代碼運行無序,如果我們寫的用例有順序的話,就需要用TestSuite,被添加到TestSuite中的case會被按照順序執行。
編寫test_suite.py代碼如下

 import unittest
from test_mathfunc import TestMathFunc
from HTMLTestRunner import HTMLTestRunner

if __name__ == '__main__':
    suite = unittest.TestSuite()

    tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")]
    #addTests添加多個TestCase
    #addTest添加單個TestCase
    #suite.addTests(tests)
    suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
    #suite.addTests(unittest.TestLoader().loadTestsFromNames(['test_mathfunc.TestMathFunc')]) 傳入列表

    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

addTests方法

傳入一個TestCase對象的列表。

unittest.TestLoader().loadTestsFromName/Names

傳入一個TestCase對象,這個對象里可以包含多個test_開頭的方法,每個test_開頭的方法處理的時候都可以理解為一個TestCase實例。

TestFixture

在實際測試中,我們可能會遇到這種情況,需要測試的方法中有的需要連接數據庫,測試完畢需要還原數據,所以我們就需要一個准備環境的方法(setUp)還有清理環境的方法(TearDown),這就是TestFixture所包含的內容。
修改test_mathfunc.py如下

import unittest
from mathfunc import *


class TestMathFunc(unittest.TestCase):
    #重寫了TestCase的方法
    def setUp(self):
        print("開始測試之前的環境搭建")

    def tearDown(self):
        print("環境清理")

    def test_add(self):
        self.assertEqual(3,add(1,2))
        self.assertNotEqual(3,add(2,2))

    def test_minus(self):
        self.assertEqual(1,minus(3,2))

    def test_multi(self):
        self.assertEqual(6,multi(2,3))
    #skip裝飾器
    @unittest.skip("我不想執行除法")
    #@unittest.skipIf(condition=,reason=)   當condition為true時跳過
    #@unittest.skipUnless(condition=,reason=)   為false時跳過
    def test_divide(self):
        self.assertEqual(2,divide(6,3))
        self.assertEqual(2.5,divide(5,2))

if __name__ == '__main__':
    unittest.main(verbosity=2)

在實際測試中我們也可能會遇到這樣的情況,開始測試前需要連接數據庫,測試結束后關閉連接,不需要還原數據,只在開始和結束各自執行一次即可,setUpClass和tearDownClass的作用就是實現以上功能。

    @classmethod
    def setUpClass(cls):
        print("開始測試之前的環境搭建統一")

    @classmethod
    def tearDownClass(cls):
        print("最后清理環境")

輸出結果如下圖
輸出結果混亂
沒有得到想要的結果,多次輸出發現setUp和tearDown輸出位置不定,猜想是因為不是單線程執行造成的,所以進行調試結果正確,暫存疑問。
輸出正確

跳過測試

有時候當某些條件的時候我們可能需要跳過測試,unittest也為我們提供了相應的方法

    #@unittest.skipIf(condition=,reason=)   當condition為true時跳過
    #@unittest.skipUnless(condition=,reason=)   為false時跳過
    def test_divide(self):
        self.assertEqual(2,divide(6,3))
        self.assertEqual(2.5,divide(5,2))

執行結果如下
跳過測試

把結果保存到文件中

保存到文本文件中

 with open('Unittest.txt','a') as f:
        runner = unittest.TextTestRunner(stream=f, verbosity=2)
        runner.run(suite)

會在項目目錄下生成Unittext.txt文本文件,內容如下

test_add (test_mathfunc.TestMathFunc) ... ok
test_divide (test_mathfunc.TestMathFunc) ... ok
test_minus (test_mathfunc.TestMathFunc) ... ok
test_multi (test_mathfunc.TestMathFunc) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

生成HTML

需要HTMLTsetRunner文件

    with open('HTMLReport.html', 'wb') as f:
        runner = HTMLTestRunner(stream=f, title="123", description="test", verbosity=2)
        runner.run(suite)

參考自


免責聲明!

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



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