unittest指南——不拼花哨,只拼實用

  • 📢專注于分享軟件測試干貨內容,歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
  • 📢交流討論:歡迎加入我們一起學習!
  • 📢資源分享:耗時200+小時精選的「軟件測試」資料包
  • 📢 最困難的時候,也就是我們離成功不遠的時候!

“ Python為開發者提供了內置的單元測試框架 unittest,它是一種強大的工具,能夠有效地編寫和執行單元測試。unittest 提供了完整的測試結構,支持自動化測試的執行,能夠對測試用例進行組織,并且提供了豐富的斷言方法。最終,unittest 會生成詳細的測試報告,這個框架非常簡單且易于使用。”

unittest核心概念

在 unittest 中,有四個核心概念:

  • TestCase(測試用例):每個測試用例實例用于封裝一個或多個測試函數。

  • TestSuite(測試套件):這是多個測試用例的集合,用于組織和執行多個測試用例。

  • TestLoader(測試加載器):這是一個用于將測試用例加載到測試套件中的工具。

  • TextTestRunner(測試運行器):這是用于執行測試用例的運行器,負責運行測試并生成結果報告。

  • Fixture(環境管理機制):這是測試用例的環境搭建和銷毀部分,包括前置條件和后置條件。

在這里插入圖片描述

unittest的工作流程

  1. 編寫繼承自 unittest.TestCase 的測試用例類,其中每個測試函數都是一個獨立的測試用例。
  2. 使用 TestLoader 加載測試用例,并將它們組織成 TestSuite 對象。
  3. 使用 TestRunner 運行 TestSuite 中的測試用例,并輸出測試結果。

使用unittest初級指南

  1. 導入 unittest 模塊以及被測試的文件或類。
  2. 創建一個測試類,并繼承 unittest.TestCase,所有自定義的單元測試類都要繼承它,作為基類。
  3. 重寫 setUp 和 tearDown 方法,用于初始化和清理測試環境(如果有必要)。
  4. 定義測試函數,函數名以 test_ 開頭,這樣才能被識別并執行。
  5. 在測試函數中使用斷言來判斷測試結果是否符合預期。
  6. 調用 unittest.main() 方法運行測試用例,按照函數名的排序執行測試。

以下是一個簡單的例子:

import unittestdef login(username, password):if username == 'kira' and password == '123':res = {"code": 200, "msg": "登錄成功"}return resreturn {"code": 400, "msg": "登錄失敗"}class TestLogin(unittest.TestCase):def test_login_success(self):"""測試登錄成功"""test_data = {"username": "kira", "password": "test"}expect_data = {"code": 200, "msg": "登錄成功"}res = login(**test_data)self.assertEqual(res, expect_data)def test_login_error_with_error_password(self):"""賬號正確,密碼錯誤,登錄失敗"""test_data = {"username": "kira", "password": "12345"}expect_data = {"code": 400, "msg": "登錄失敗"}res = login(**test_data)self.assertEqual(res, expect_data)# 更多測試函數類似...if __name__ == '__main__':unittest.main()

以上是一個簡單的測試用例,包含了兩個測試函數。運行腳本將輸出測試結果。

unittest核心概念

測試腳手架

測試腳手架 是測試用例的前置條件和后置條件,確保測試環境的初始化和清理,從而保證測試的準確性和可靠性。

import unittestclass MyTestCase(unittest.TestCase):@classmethoddef setUpClass(cls):# 類級別的前置條件設置,整個類運行最先只執行一次print("setUpClass")@classmethoddef tearDownClass(cls):# 類級別的后置條件清理,整個類運行最后結束執行一次print("tearDownClass")def setUp(self):# 測試方法級別的前置條件設置,所有測試方法運行前都執行一次print("setUp")def tearDown(self):# 測試方法級別的后置條件清理,所有測試方法運行結束都執行一次print("tearDown")def test_example(self):# 測試用例print("test_example")if __name__ == "__main__":unittest.main()
  1. setUp():每個測試方法運行前執行,用于測試前置的初始化工作。
  2. tearDown():每個測試方法結束后執行,用于測試后的清理工作。
  3. setUpClass():所有的測試方法運行前執行,用于單元測試類運行前的準備工作。使用 @classmethod 裝飾器裝飾,整個測試類運行過程中只會執行一次。
  4. tearDownClass():所有的測試方法結束后執行,用于單元測試類運行后的清理工作。使用 @classmethod 裝飾器裝飾,整個測試類運行過程中只會執行一次。

測試用例

測試用例 是最小的測試單元,用于檢測特定的輸入集合的特定的返回值。unittest 提供了 TestCase 基類,所有的測試類都需要繼承該基類,而在該類下的函數如果以 test_ 開頭,則被標識為測試函數:

class MyTestCase(unittest.TestCase):def test_addition(self):result = 2 + 3self.assertEqual(result, 5)  # 使用斷言方法驗證結果是否相等def test_subtraction(self):result = 5 - 3self.assertTrue(result == 2)  # 使用斷言方法驗證結果是否為True# 更多測試用例函數...

斷言方法

以下是常用的斷言方法:

  • assertEqual(a, b, msg=None):驗證 a 等于 b。

  • assertNotEqual(a, b):驗證 a 不等于 b。

  • assertTrue(x):驗證 x 是否為 True。

  • assertFalse(x):驗證 x 是否為 False。

  • assertIs(a, b):驗證 a 是否是 b。

  • assertIsNot(a, b):驗證 a 是否不是 b。

  • assertIsNone(x):驗證 x 是否為 None。

  • assertIsNotNone(x):驗證 x 是否不為 None。

  • assertIn(a, b):驗證 a 是否在 b 中。

  • assertNotIn(a, b):驗證 a 是否不在 b 中。

  • assertIsInstance(a, b):驗證 a 是否是 b 類型的實例。

  • assertNotIsInstance(a, b):驗證 a 是否不是 b 類型的實例。

可以使用這些方法進行斷言,也可以直接使用原生的assert來斷言,如果斷言失敗,測試用例會被定義為執行失敗。

忽略特定測試方法

unittest 提供了一些方法來跳過特定的測試用例:

  • @unittest.skip(reason):強制跳過,reason 是跳過的原因。

  • @unittest.skipIf(condition, reason):當 condition 為 True 時跳過。

  • @unittest.skipUnless(condition, reason):當 condition 為 False 時跳過。

  • @unittest.expectedFailure:如果測試失敗,這個測試用例不會計入失敗的統計。

  • 使用實例方法:self.skipTest() 使用和上述類似。

import sys
import unittestclass Test1(unittest.TestCase):@unittest.expectedFailure  # 即使失敗也會被計為成功的用例def test_1(self):assert 1 + 1 == 3@unittest.skip('無條件跳過')  # 不管什么情況都會進行跳過def test_2(self):print("2+2...", 4)@unittest.skipIf(sys.platform == "win32", "跳過")  # 如果系統平臺為 Windows 則跳過def test_3(self):print("3+3...", 6)@unittest.skipUnless(sys.platform == "win32", "跳過")  # 除非系統平臺為 Windows,否則跳過def test_4(self):print("4+4...", 8)def test_5(self):self.skipTest("跳過")print("5+5...", 10)if __name__ == "__main__":unittest.main(verbosity=2)

測試套件

測試套件用于收集和組織多個測試用例,便于集中執行。

  1. 通過 unittest.main() 方法直接加載單元測試的測試模塊,這是一種簡單的加載方式。所有測試用例的執行順序按照方法名的字符串表示的 ASCII 碼升序排序,通過命名時使用 test_01_xxx 來指定執行順序。

  2. 將所有的單元測試用例 TestCase 加載到測試套件 Test Suite 集合中,然后一次性加載所有測試對象。

通過 TestSuite 對象收集

此方式適用于需要自定義組合特定測試用例的情況。

import unittestclass MyTestCase(unittest.TestCase):def test_addition(self):result = 2 + 3self.assertEqual(result, 5)def suite():suite = unittest.TestSuite()suite.addTest(MyTestCase('test_addition'))return suiteif __name__ == '__main__':runner = unittest.TextTestRunner()runner.run(suite())

通過 TestLoader 對象收集

TestLoader 是 unittest 框架提供的加載測試用例的類。

import unittestif __name__ == '__main__':loader = unittest.defaultTestLoader# 自動加載當前模塊中所有以 'test_' 開頭的測試用例函數suite = loader.loadTestsFromModule(__name__)runner = unittest.TextTestRunner()runner.run(suite)
import unittestclass MyTestCase(unittest.TestCase):def test_addition(self):result = 2 + 3self.assertEqual(result, 5)if __name__ == '__main__':loader = unittest.defaultTestLoader# 自動加載 MyTestCase 類中的所有測試用例suite = loader.loadTestsFromTestCase(MyTestCase)runner = unittest.TextTestRunner()runner.run(suite)
import unittestif __name__ == '__main__':loader = unittest.defaultTestLoader# 自動加載指定名稱的測試用例suite = loader.loadTestsFromName('module.MyTestCase.test_addition')runner = unittest.TextTestRunner()runner.run(suite)
import unittestif __name__ == '__main__':loader = unittest.defaultTestLoader# 自動發現并加載指定目錄中的測試用例模塊suite = loader.discover(start_dir='test_directory', pattern='test_*.py', top_level_dir=None)runner = unittest.TextTestRunner()runner.run(suite)

測試運行器

測試運行器是用于執行和輸出測試結果的組件。常用的運行器有:

  • unittest.TextTestRunner:這是 unittest 框架中默認的測試運行器,會在命令行輸出測試結果。通過調用 run() 方法運行測試套件,并將測試結果打印到控制臺。
import unittestif __name__ == '__main__':loader = unittest.defaultTestLoadersuite = loader.discover(start_dir='tests', pattern='test_*.py')runner = unittest.TextTestRunner()result = runner.run(suite)
  • HTMLTestRunner:這是一個第三方庫,能夠生成漂亮的 HTML 測試報告,需要進行安裝。你可以通過搜索獲取相關文件進行安裝。
import unittest
from HTMLTestRunner import HTMLTestRunnerif __name__ == '__main__':loader = unittest.defaultTestLoadersuite = loader.discover(start_dir='tests', pattern='test_*.py')with open('test_report.html', 'wb') as report_file:runner = HTMLTestRunner(stream=report_file, title='Test Report', description='Test Results')result = runner.run(suite)
  • XMLTestRunner:這是另一個第三方庫,用于生成 XML 格式的測試報告。
import unittest
from xmlrunner import XMLTestRunnerif __name__ == '__main__':loader = unittest.defaultTestLoadersuite = loader.discover(start_dir='tests', pattern='test_*.py')with open('test_report.xml', 'wb') as report_file:runner = XMLTestRunner(output=report_file)result = runner.run(suite)

你也可以自定義測試運行器。繼承 unittest.TestRunner 類并實現 run() 方法,以創建自己的測試運行器。

import unittestclass MyTestRunner(unittest.TextTestRunner):def run(self, test):print("Running tests with MyTestRunner")result = super().run(test)return resultif __name__ == '__main__':loader = unittest.defaultTestLoadersuite = loader.discover(start_dir='tests', pattern='test_*.py')runner = MyTestRunner()result = runner.run(suite)

通常使用 HTMLTestRunner 即可滿足需求,它非常易用。

實戰一個測試案例

假設有一個測試函數 login:

# login.py
def login(username, password):"""模擬登錄校驗"""if username == 'kira' and password == '123456':return {"code": 0, "msg": "登錄成功"}else:return {"code": 1, "msg": "賬號或密碼不正確"}

設計用例

根據函數的參數和邏輯,設計如下用例:

編寫測試用例并運行

import unittest
from login import loginclass TestLogin(unittest.TestCase):def test_login_correct(self):"""測試賬號密碼正確"""test_data = {"username": "kira", "password": "123456"}expect_data = {"code": 0, "msg": "登錄成功"}res = login(**test_data)self.assertEqual(res, expect_data)def test_login_wrong_password(self):"""測試賬號正確密碼不正確"""test_data = {"username": "kira", "password": "123"}expect_data = {"code": 1, "msg": "賬號或密碼不正確"}res = login(**test_data)self.assertEqual(res, expect_data)def test_login_wrong_username(self):"""測試賬號錯誤密碼正確"""test_data = {"username": "kir", "password": "123456"}expect_data = {"code": 1, "msg": "賬號或密碼不正確"}res = login(**test_data)self.assertEqual(res, expect_data)if __name__ == '__main__':unittest.main()

這是一個簡單的測試用例,包含了三個測試函數。運行測試用例后,會輸出測試結果,看完是否覺得unittest非常簡單易用。ner.run(suite)

最后的分享

如果你想學習自動化測試,那么下面這套視頻應該會幫到你很多

如何逼自己1個月學完自動化測試,學完即就業,小白也能信手拈來,拿走不謝,允許白嫖....

最后我這里給你們分享一下我所積累和整理的一些文檔和學習資料,有需要直接領取就可以了!


以上內容,對于軟件測試的朋友來說應該是最全面最完整的備戰倉庫了,為了更好地整理每個模塊,我也參考了很多網上的優質博文和項目,力求不漏掉每一個知識點,很多朋友靠著這些內容進行復習,拿到了BATJ等大廠的offer,這個倉庫也已經幫助了很多的軟件測試的學習者,希望也能幫助到你。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167811.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167811.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167811.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

centos7 docker開啟認證的遠程端口2376配置

docker開啟2375會存在安全漏洞 暴露了2375端口的Docker主機。因為沒有任何加密和認證過程,知道了主機IP以后,,任何人都可以管理這臺主機上的容器和鏡像,以前貪圖方便,只開啟了沒有認證的docker2375端口,后…

代碼隨想錄算法訓練營第五十三天|1143.最長公共子序列 1035.不相交的線 53. 最大子序和

文檔講解:代碼隨想錄 視頻講解:代碼隨想錄B站賬號 狀態:看了視頻題解和文章解析后做出來了 1143.最長公共子序列 class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:dp [[0] * (len(text2) 1) for _ i…

機器學習入門

簡介 https://huggingface.co/是一個AI社區,類似于github的地位。它開源了許多機器學習需要的基礎組件如:Transformers, Tokenizers等。 許多公司也在不斷地往上面提交新的模型和數據集,利用它你可以獲取以下內容: Datasets : 數…

hikariCP 數據庫連接池配置

springBoot 項目默認自動使用 HikariCP ,HikariCP 的性能比 alibaba/druid快。 一、背景 系統中多少個線程在進行與數據庫有關的工作?其中,而多少個線程正在執行 SQL 語句?這可以讓我們評估數據庫是不是系統瓶頸。 多少個線程在…

基于法醫調查算法優化概率神經網絡PNN的分類預測 - 附代碼

基于法醫調查算法優化概率神經網絡PNN的分類預測 - 附代碼 文章目錄 基于法醫調查算法優化概率神經網絡PNN的分類預測 - 附代碼1.PNN網絡概述2.變壓器故障診街系統相關背景2.1 模型建立 3.基于法醫調查優化的PNN網絡5.測試結果6.參考文獻7.Matlab代碼 摘要:針對PNN神…

【學生成績管理】數據庫示例數據(MySQL代碼)

【學生成績管理】數據庫示例數據(MySQL代碼) 目錄 【學生成績管理】數據庫示例數據(MySQL代碼)一、創建數據庫二、創建dept(學院)表1、創建表結構2、添加示例數據3、查看表中數據 三、創建stu(學…

35.邏輯運算符

目錄 一.什么是邏輯運算符 二.C語言中的邏輯運算符 三.邏輯表達式 三.視頻教程 一.什么是邏輯運算符 同時對倆個或者倆個以上的表達式進行判斷的運算符叫做邏輯運算符。 舉例:比如去網吧上網,只有年滿十八周歲并且帶身份證才可以上網。在C語言中如果…

為什么 Flink 拋棄了 Scala

曾經紅遍一時的Scala 想當初Spark橫空出世之后,Scala簡直就是語言界的一顆璀璨新星,惹得大家紛紛側目,連Kafka這類技術框架也選擇用Scala語言進行開發重構。 可如今,Flink竟然公開宣布棄用Scala 在Flink1.18的官方文檔里&#x…

國家開放大學的學子們 練習題 走起!

試卷代號:1356 高級英語聽說(2) 參考 試題 Section One (20 points, 2 points each) Directions: Listen to the conversation and fill in the blanks with the words you hear. Write the words on the Answer Sheet The conversation will be read TWICE. M…

windows11上安裝WSL

Windows電腦上要配置linux(這里指ubuntu)開發環境,主要有三種方式: 1)在windows上裝個虛擬機(比如vmware)。缺點是vmware加載ubuntu后系統會變慢很多,而且需要通過samba來實現window…

使用Java連接Hbase

我在網上試 了很多代碼,但是大部分都不能實現,Java連接Hbase,一直報一個錯 java.util.concurrent.ExecutionException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode NoNode for /hbase/hbaseid一直也不清楚為什…

計算機組成原理。3-408

1.動態存儲和靜態存儲 2.雙端口RAM 注意:cpu通過地址線和數據線讀寫數據時,不能同時寫,但可以同時讀,也不能一邊讀一邊寫。 3.多體并行存儲器 分為高位存儲和低位存儲 小結 4.磁盤存儲器的組成 5.磁盤的性能指標 磁盤讀寫尋道…

如何對網站進行滲透測試

信息搜集 信息搜集拿到域名后獲取真實IP,如果存在CDN想辦法繞過端口掃描,針對開放的端口在獲取客戶同意的前提下進行爆破查找網站子域名,后臺目錄判斷網站的CMS 可以使用 Wappalyzer插件 whatcms 是一個可以用來確定特定網站正在使用的什么…

Vue中Slot的使用指南

目錄 前言 什么是slot? 單個slot的使用 具名slot的使用 作用域插槽 總結 前言 在Vue中,slot是一種非常強大和靈活的功能,它允許你在組件模板中預留出一個或多個"插槽",然后在使用這個組件的時候動態地填充內容。這…

TSINGSEE青犀智能分析網關道路積水識別AI算法方案

在各處的街道、路口等區域,及時發現道路積水問題,可以大大減少城市管理部門壓力,及時處理,減少交通事故與人員摔倒事故。通過道路積水AI算法,能有效提高城市管理部門效率,優化城市管理方式。 那么&#xff…

【Web】PhpBypassTrick相關例題wp

目錄 ①[NSSCTF 2022 Spring Recruit]babyphp ②[鶴城杯 2021]Middle magic ③[WUSTCTF 2020]樸實無華 ④[SWPUCTF 2022 新生賽]funny_php 明天中期考,先整理些小知識點冷靜一下 ①[NSSCTF 2022 Spring Recruit]babyphp payload: a[]1&b1[]1&b2[]2&…

NLP的使用

參考: Apache openNLP 簡介 - 鏈滴 (ld246.com) opennlp 模型下載地址:Index of /apache/opennlp/models/ud-models-1.0/ (tencent.com) OpenNLP是一個流行的開源自然語言處理工具包,它提供了一系列的NLP模型和算法。然而,Open…

【模擬開關CH440R】2022-1-20

資料模擬開關CH440芯片手冊 - 百度文庫 ch440R回來了,導通usb設備沒問題,降壓不影響。但是我發現個嚴重的問題,我的電路是直接通過4067控制ch440r接地,低電平,使能三個線路連一起的,郵箱的圖您看看&#xf…

N-134基于java實現捕魚達人游戲

開發工具eclipse,jdk1.8 文檔截圖&#xff1a; package com.qd.fish;import java.awt.Graphics; import java.io.File; import java.util.ArrayList; import java.util.List;import javax.imageio.ImageIO;public class Fishes {//定義一個集合來管理魚List<Fish> fish…

五種多目標優化算法(NSDBO、NSGA3、MOGWO、NSWOA、MOPSO)求解微電網多目標優化調度(MATLAB代碼)

一、多目標優化算法簡介 &#xff08;1&#xff09;非支配排序的蜣螂優化算法NSDBO 多目標應用&#xff1a;基于非支配排序的蜣螂優化算法NSDBO求解微電網多目標優化調度&#xff08;MATLAB&#xff09;-CSDN博客 &#xff08;2&#xff09;NSGA3 NSGA-III求解微電網多目標…