unittest框架學習筆記


1、unittest全部屬性

['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader',
'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner',
'_TextTestResult', '__all__', '__builtins__', '__doc__', '__file__', '__name__',
'__package__', '__path__', '__unittest', 'case', 'defaultTestLoader',
'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'loader',
'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result',
'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util']

2、用例基本類:unittest.TestCase

TestCase類,所有測試用例類繼承的基本類。

使用方法:

class BaiduTest(unittest.TestCase):
    pass

2.1、前置條件:setUp()

  • 用於測試用例執行前的初始化工作。
  • 如:連接數據庫、初始化瀏覽器等。
# 使用方法:

    def setUp(self):
        '''這里編寫執行用例的前置條件'''
        pass

2.2、后置條件:tearDown()

  • 用於測試用例執行之后的善后工作。
  • 如:關閉數據庫、關閉瀏覽器之內的。
# 使用方法:

    def tearDown(self):
        '''這里編寫執行用例的善后工作'''
        pass

2.3、斷言:assert*()

  • assert*():一些斷言方法:在執行測試用例的過程中,最終用例是否執行通過,是通過判斷測試得到的實際結果和預期結果是否相等決定的。
assertEqual(a,b,[msg='測試失敗時打印的信息']):斷言a和b是否相等,相等則測試用例通過。

assertNotEqual(a,b,[msg='測試失敗時打印的信息']):斷言a和b是否相等,不相等則測試用例通過。

assertTrue(x,[msg='測試失敗時打印的信息']):斷言x是否True,是True則測試用例通過。

assertFalse(x,[msg='測試失敗時打印的信息']):斷言x是否False,是False則測試用例通過。

assertIs(a,b,[msg='測試失敗時打印的信息']):斷言a是否是b,是則測試用例通過。

assertNotIs(a,b,[msg='測試失敗時打印的信息']):斷言a是否是b,不是則測試用例通過。

assertIsNone(x,[msg='測試失敗時打印的信息']):斷言x是否None,是None則測試用例通過。

assertIsNotNone(x,[msg='測試失敗時打印的信息']):斷言x是否None,不是None則測試用例通過。

assertIn(a,b,[msg='測試失敗時打印的信息']):斷言a是否在b中,在b中則測試用例通過。

assertNotIn(a,b,[msg='測試失敗時打印的信息']):斷言a是否在b中,不在b中則測試用例通過。

assertIsInstance(a,b,[msg='測試失敗時打印的信息']):斷言a是是b的一個實例,是則測試用例通過。

assertNotIsInstance(a,b,[msg='測試失敗時打印的信息']):斷言a是是b的一個實例,不是則測試用例通過。

3、單元測試:unittest.main()

【1】作用:可以運行單個測試用例檢查用例是否正確,單元測試。

【2】執行條件:執行的時候會自動搜索模塊中以“test”命名開頭的測試方法。

【3】執行默認順序:
1、根據ASCII碼的順序加載測試用例。
2、數字與字母的順序為:0-9,A-Z,a-z。
3、所以A開頭的測試用例方法會優先執行,以a開頭會后執行。

【4】使用方法:

import unittest

class Test(unittest.TestCase):

    def setUp(self):
        print('start')

    def test_01(self):
        print('test_01')

    def test_02(self):
        print('test_02')

    def tearDown(self):
        print('end')


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

# 執行順序:setUp() -> test_01() -> tearDown() -> setUp() -> test_01() -> tearDown()

#完整流程即 [前置 -> 用例 -> 后置]這樣一個循環反復的順序。

4、用例套件_1:unittest.TestSuite()

  • unittest框架的TestSuite()類是用來創建測試套件的。

addTest():

  • addTest()方法是將測試用例添加到測試套件中。
import unittest

class Test(unittest.TestCase):

    def test_01(self):
        print('test_01')


if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTest(Test('test_01'))
    suite.addTest(Test('test_02'))
    runner = unittest.TextTestRunner()
    runner.run(suite)

5、用例套件_2:unittest.defaultTestLoader()

  • unittest框架的defaultTestLoader()類,通過該類下面的discover()方法可根據測試目錄匹配查找測試用例文件(test*.py),並將查找到的測試用例組裝到測試套件,因此可以直接通過run()方法執行discover。用法如下:
···
····
·····

if __name__ == '__main__':
    case_path =os.path.join(os.getcwd(),'case')
    discover = unittest.defaultTestLoader.discover(case_path, pattern='test_*.py')
    runner = unittest.TextTestRunner()
    runner.run(discover)
    
#case_path是存放測試用例的地方

備注:discover方法里面有三個參數

-case_dir:這個是待執行用例的目錄。

-pattern:這個是匹配腳本名稱的規則,test*.py意思是匹配test開頭的所有腳本。

-top_level_dir:這個是頂層目錄的名稱,一般默認等於None就行了。

6、執行套件:unittest.TextTextRunner()

  • unittest框架的TextTextRunner()類,配合TestSuite()、defaultTestLoader()類一起使用,通過TextTextRunner類下面的run()方法來運行套件所組裝的測試用例,入參為suite測試套件。
import unittest

class Test(unittest.TestCase):

    def setUp(self):
        print('start')

    def test_01(self):
        print('test_01')

    def test_02(self):
        print('test_02')

    def tearDown(self):
        print('end')


if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTest(Test('test_01'))
    suite.addTest(Test('test_02'))
    runner = unittest.TextTestRunner()
    runner.run(suite)

7、裝飾器:unittest.skip()

  • unittest.skip():裝飾器,當運行用例時,有些用例可能不想執行等,可用裝飾器暫時屏蔽該條測試用例。
@unittest.skip(reason): skip(reason)裝飾器:無條件跳過裝飾的測試,並說明跳過測試的原因。

@unittest.skipIf(reason): skipIf(condition,reason)裝飾器:條件為真時,跳過裝飾的測試,並說明跳過測試的原因。

@unittest.skipUnless(reason): skipUnless(condition,reason)裝飾器:條件為假時,跳過裝飾的測試,並說明跳過測試的原因。

@unittest.expectedFailure(): expectedFailure()測試標記為失敗。

8、裝飾器:@classmethod

  • 作用:在某些特定情況下,避免每次執行用例時候都會執行一次unittest里面setUp()。
  • 比如進行登陸、打開瀏覽器、連接數據庫等操作的時候。
#使用方法:
import unittest

class Test(unittest.TestCase):

    @classmethod
    def setUpClass(cls):    #注意這里傳入的參數不是self,而是指定參數cls
        print('start')

    @classmethod
    def test_01(self):
        print('test_01')

    @classmethod
    def test_02(self):
        print('test_02')

    @classmethod
    def tearDownClass(cls):     #注意這里傳入的參數不是self,而是指定參數cls
        print('end')


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

#運行結果:
# start
# test_01
# test_02
# end

9、數據驅動:ddt

【1】作用:

  • 針對某些功能相同,但是輸入的參數數據不同時,可以使用數據驅動設計的模式,一組數據對應一個測試用例,用例自動加載生成,有效的較少代碼量。如:登錄時。

【2】安裝ddt模塊

pip install ddt

【3】ddt模塊使用方法

  1. 測試數據為存放多個字典的列表。
  2. 測試類的前面需要加上修飾器:@ddt.ddt
  3. 對應測試用例之前加上修飾器:@ddt.data()
import unittest
import ddt

#   測試數據:每一條數據都是一個字典;全部數據存放在一個列表中。
testDate = [{'username': 'AAA', 'password': '11111'},
            {'username': 'BBB', 'password': '22222'},
            {'username': 'CCC', 'password': '33333'}]

#測試類之前需要加上裝飾器:@ddt.ddt
@ddt.ddt
class Test(unittest.TestCase):

    def setUp(self):
        print('start')

    #測試用例前面需要加上裝飾器:@ddt.data()
    #裝飾器的參數就是測試數據:@ddt.data(*testDate)
    @ddt.data(*testDate)
    def test_ddt(self, data):
        print(data)

    def tearDown(self):
        print('end')


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

//////////////////////////////////////////////

#輸出結果:

start
{'username': 'AAA', 'password': '11111'}
end
start
{'username': 'BBB', 'password': '22222'}
end
start
{'username': 'CCC', 'password': '33333'}
end

10、生成測試報告:HTMLTestRunner

【1】安裝HTMLTestRunner

  • 1.HTMLTestRunner這個模塊下載不能通過pip安裝了,只能下載后手動導入,下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html

  • 2.Download下HTMLTestRunner.py文件就是我們需要下載的包。

  • 3.下載后手動拖到python安裝文件的Lib目錄下

【2】使用方法:

····
·····

if __name__ == '__main__':
    #將測試用例加入到套件中
    suite = unittest.TestSuite()
    suite.addTest(Test('test_01'))
    suite.addTest(Test('test_02'))
    # 獲取當前時間,這樣便於下面的使用。
    now = time.strftime("%Y-%m-%M-%H_%M_%S", time.localtime(time.time())) + '.html'
    # filePath:測試報告保存的路徑
    filePath = os.path.join(os.getcwd(), 'report', now)
    fp = open(filePath, 'wb')
    # 測試報告的title、描述
    runner = HTMLTestRunner.HTMLTestRunner(stream=fp,
                                           title='自動化測試HTML文件標題',
                                           description='自動化測試HTML文件描述')
    runner.run(suite)
    # 最后記着關閉文件
    fp.close()

11、截圖

在測試過程中,用的最多的就是截圖功能,畢竟有圖有真相嘛,截圖不僅可以把缺陷原原本本的記錄下來,也方便后面我們根據缺陷。

webdriver中提供的截圖方法一:

  • get_screenshot_as_file(filename)
  • 這個方法是獲取當前window的截圖,出現IOError時候返回False,截圖成功返回True。
  • filename參數是保存文件的路徑。
import os
import time
import unittest

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait


class Test(unittest.TestCase):

    def setUp(self):
        '''初始化瀏覽器、打開網址、並等待頁面加載完'''
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.baidu.com/')
        self.wait = WebDriverWait(self.driver, 10)
        self.wait.until(EC.presence_of_all_elements_located)

    def test_get_screenshot(self):
        '''獲取當前時間,用於后面創建圖片名'''
        now = '百度' + time.strftime("%Y-%m-%M-%H_%M_%S", time.localtime(time.time())) + '.jpg'
        filePath = os.path.join(os.getcwd(), 'image', now)
        # get_screenshot_as_file()的參數就是圖片保存路徑
        self.driver.get_screenshot_as_file(filePath)

    def tearDown(self):
        self.driver.quit()


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

方法二:

  • get_screenshot_as_base64()
  • 這個方法也是獲取屏幕截圖,保存的是base64的編碼格式,在HTML界面輸出截圖的時候,會用到。

方法三:

  • get_screenshot_as_png()
  • 這個是獲取屏幕截圖,保存的是二進制數據。


免責聲明!

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



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