1. 程式人生 > 實用技巧 >unittest_核心概念(進階)

unittest_核心概念(進階)

unittest 核心概念
1、測試腳手架 TestCase提供的一系列的方法,他會在測試前,測試後執行
1.1、setUP在每個單元測試函式開始前執行
1.2、tearDown在每個測試函式結束後執行
1.3、setUPClass 在整個測試用例類執行之前執行 (是類方法,需要裝飾器)
1.4、tearDownClass 在整個測試用例類執行完畢前執行 (是類方法,需要裝飾器)
2、測試用例 一個獨立的測試單元,unittest提供的一個基類,TestCase
3、測試套件 一個測試用例的列表 testsuite,歸檔需要一起執行的測試
3.1、直接使用unittest.TestSuite例項化,一個一個的新增
新增的時候 測試用例類(測試方法名)
3.2、使用unittest.TestLoader例項化,傳入測試用例類名/模組/包,需要匯入測試用例類
3.3、使用unittest.TestLoader().discover()方法來收集用例
測試用例模組名要以test開頭
4、測試執行器 執行測試用例,並輸出結果
4.1、uninttest.TestTestRunner 例項化呼叫run的方法,傳入測試套件
runner(ts)
4.2、HTMLTestRunnerNew
4.3、BeautifulReport
4.4、執行順序就是收集順序,收集順序是按照ascii碼(.py/函式/方法)


第一建立login.py

  def login_check(username,password):
    """
    :param username:賬號
    :param password:密碼
    :return:
    """
    if 6 <= len(password) <= 18:
        if username == 'python34' and password == 'lemonban':
            return {"code": 0,"msg":"登陸成功"}
        else:
            return {"code": 1,"msg":"賬號或密碼不正確"}
    else:
        return {"code":1,"msg":"密碼長度在6-18位之間"}
# __name__ 是模組的特殊變數
# 當直接之前當前模組的時候__name__='__main__'
# 當被其他模組匯入的時候__name__ = 模組名
# pass佔位符,什麼都不是,表示跳過
if __name__ == '__main__':
    pass

第二建立test_case.py (測試用例類1)

# 匯入unittese,匯入被檢測函式或者類
# 一般系統模組放在最上面
# 第三方模組放在系統模組的下面
# 自己寫的模組放在最下面
import unittest
from day17.login import login_check


# 建立測試類,繼承unittest.TeseCase類,測試用例
class Testlog(unittest.TestCase):
    """
    測試登入功能
    """

    # 3、如果有初始(前置)條件和結束(後置)條件,重寫腳手架(fixture)方法
    # 4、定義單元測試函式,函式名要以test開頭

    def setUp(self) -> None:
        """
        測試函式前置
        :return:
        """
        print('在每個測試函式開始前執行')

    def tearDown(self) -> None:
        """
        測試函式後置
        :return:
        """
        print('在每個測試函式結束後執行')
    @classmethod
    def setUpClass(cls) -> None:
        """
        測試類前置
        :return:
        """
        print('在整個類開始前執行')

    @classmethod
    def tearDownClass(cls) -> None:
        """
        測試類後置
        :return:
        """
        print('在整個類結束後執行')

    def test_log_ok(self):

        """
        賬號密碼正確
        :return:
        """

        # 1、測試資料
        test_data = {"username": "python34", "password": "lemonban"}
        # 期望資料
        expect_data = {"code": 0, "msg": "登陸成功"}
        # 測試步驟
        # 執行函式-,**解包,鍵相同,相當於把test_data中的兩個值傳給了login_check
        res = login_check(**test_data)
        # 3、斷言(判斷)assert
        self.assertEqual(expect_data, res)
        # 如果不相等會丟擲assertError,斷言錯誤
        print('第一條用例')

    def test_log_password_error(self):
        """
        賬號正確,密碼錯誤
        :return:
        """
        # 1、測試資料
        test_data = {"username": "python342", "password": "lemonban"}
        # 期望結果
        expected = {"code": 1, "msg": "賬號或密碼不正確"}
        # 2、測試步驟
        res = login_check(**test_data)
        # 3、斷言
        self.assertEqual(expected, res)
        print("第二條用例")

    def test_password_ok_pass_error(self):
        test_date = {"username": "python34", "password": "lemonban1"}
        expected = {"code": 1, "msg": "賬號或密碼不正確"}
        res = login_check(**test_date)
        self.assertEqual(res,expected)
        print('第三條用例')

    def test_password_lenth_little(self):
        test_data = {"username": "python34", "password": "lem"}
        expected = {"code": 1, "msg": "密碼長度在6-18位之間"}
        res = login_check(**test_data)
        self.assertEqual(expected,res)
        print('第四條用例')

    def test_password_lenth_blg(self):
        test_data = {"username": "python34", "password": "lemonbanaaaaaaaaaaaaaaa1"}
        expected = {"code":1,"msg":"密碼長度在6-18位之間"}
        res = login_check(**test_data)
        self.assertEqual(expected,res)
        print('第五條用例')
# 5、呼叫unittese.main()來執行測試用例
if __name__ == '__main__':
    a = 1
    # 會自動收集TestCase類裡的單元測試函式
    unittest.main()

第三建立test_dome.py (測試用例類2)

import unittest
class TeststrUpper(unittest.TestCase):


    def test_str_upper(self):
        """
        測試字串的方法upper
        :return:
        """
        self.assertEqual('ABC','abc'.upper())

第四建立main.py (收集用例/執行/輸出)

import unittest
from day17.test_dome import TeststrUpper
from day17.test_case import Testlog
# #第一種收集用例方法unittest.TestSuite
# # 1、例項化一個測試套件
# ts = unittest.TestSuite()
# # 2、收集測試
# # 一個一個的新增
# # 單元測試的語法:測試用例類名("單元測試方法名")
# ts.addTest(TeststrUpper('test_str_upper'))
# # 一次新增多個
# ts.addTests([Testlog('test_log_ok'), Testlog('test_log_password_error')])
#
# # 第二種收集用例方法unittest.TestLoader
# # TestLoader物件,收集器
# tloader = unittest.TestLoader()
# # 通過測試用例類名,不要加括號,需要匯入
# tloader.loadTestsFromTestCase(Testlog)
# # 以上兩種方法比較笨拙

# 第三種收集用例的方法,也是常用的方法是
tloader = unittest.TestLoader()
# discover方法接收三個引數
# - start_dir 開始查詢的目錄 (一般只傳開始目錄即可),'.' 表示根目錄
# - pattern 查詢模組名的規則 test*.py 以test開頭的模組(py檔案),收集裡面的測試用例,繼承了unittest.TestCase
# - top_level_dir 專案的頂層目錄
# 開始查詢的目錄要有__init__.py檔案,才算是一個模組(包)
ts = tloader.discover(r'D:\PYthon\untitled_test\Ningmengban\day17')

# # 執行測試
# # 第一種,文字測試執行器,例項化執行器
# runner = unittest.TextTestRunner()
# # 傳入測試套件
# res = runner.run(ts)
# print(res)
#
# # 1、編寫測試用例類
# # 2、收集測試用例
# # 3、執行測試,輸出結果

# # 第二種,HTML測試執行器,別人的包
# # HTMLTestRunnerNew
# from day17.HTMLTestRunnerNew import HTMLTestRunner
# with open(r'D:\PYthon\untitled_test\Ningmengban\day17\report.html','wb') as f:
#     runner = HTMLTestRunner(
#         stream=f,description='第一份測試報告',title='測試報告',tester='馮昆壘'
#     )
#     runner.run(ts)

# BeautifulReport
from BeautifulReport import BeautifulReport
br = BeautifulReport(ts)
br.report('測試報告','bReport.html',report_dir=r'D:\PYthon\untitled_test\Ningmengban\day17')