unittest框架學習,一步步生成html格式測試報告
主要參考文章:
https://blog.csdn.net/xiaoquantouer/article/details/75089200
unittest中最核心的四部分是:
1.test fixture(測試韌體)
2.test case(測試用例)
3.test suite(測試套件)
4.test runner(測試執行器 )
1.測試韌體(test fixture):
一個測試用例環境的搭建和銷燬,是一個fixture。
包括兩部分setUp()和tearDown()
執行測試程式碼之前的準備部分和測試結束之後的清掃程式碼
(這裡舉例以下,例如要測試百度搜索selenium這個場景,我們的測試韌體可以這樣寫,setUp()裡寫開啟瀏覽器,瀏覽器最大化,和開啟百度首頁等指令碼程式碼;在tearDown()裡寫結束搜尋後,退出並關閉瀏覽器的程式碼。)
2.測試用例(test case):
什麼是測試用例呢?就是一個完整的測試流程,包括測試前準備環境的搭建(setUp),執行測試程式碼(run),以及測試後環境的還原(tearDown)。
一個測試用例中,包括測試韌體,但測試韌體可以不寫,但是至少有一個已test開頭的函式。unittest會自動化識別test開頭的函式是測試程式碼,如果你寫的函式不是test開頭,unittest是不會執行這個函式裡面的指令碼的,這個千萬要記住,所有的測試函式都要test開頭,記住是小寫的哦
3.測試套件 (test suite):
多個測試用例集合在一起,就是TestSuite,而且TestSuite也可以巢狀TestSuite。
如果測試用例比作單個學生,測試套件就是好像是班級的概念。
4.測試執行器 (test runner):
test runner是一個用來執行載入測試用例,並執行用例,且提供測試輸出的一個組建。test runner可以載入test case或者test suite進行執行測試任務。其中的run(test)會執行TestSuite/TestCase中的run(result)方法
5.TestLoader:
TestLoader是用來載入TestCase到TestSuite中的,其中有幾個loadTestsFrom__()方法,就是從各個地方尋找TestCase,建立它們的例項,然後add到TestSuite中,再返回一個TestSuite例項。
6.TextTestResult:
測試的結果會儲存到TextTestResult例項中,包括運行了多少測試用例,成功了多少,失敗了多少等資訊。
unittest的流程:
1.寫好TestCase
2.由TestLoader載入TestCase到TestSuite
3.由TextTestRunner來執行TestSuite
(我們通過命令列或者unittest.main()執行時,main會呼叫TextTestRunner中的run來執行,或者我們可以直接通過TextTestRunner來執行用例。)
4.執行的結果儲存在TextTestResult中
注:
verbosity引數可以控制執行結果的輸出,0 是簡單報告、1 是一般報告、2 是詳細報告。
用 setUp()、tearDown()、setUpClass()以及 tearDownClass()可以在用例執行前佈置環境,以及在用例執行後清理環境
我們可以通過skip,skipIf,skipUnless裝飾器跳過某個case,或者用TestCase.skipTest方法。
使用unittest編寫用例,必須遵守以下規則:
1.測試檔案必須先import unittest
2.測試類必須繼承unittest.TestCase
3.測試方法必須以“test_”開頭
4.測試類必須要有unittest.main()方法
先寫了一個待測試檔案mathfunc.py內容如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
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,內容如下:(注意四個規則)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import unittest
from mathfunc import *
class TestMathFunc(unittest.TestCase):
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(6,3))
if __name__== '__main__':
unittest.main(verbosity=2)
另一個測試用例test_mathfuna.py
前邊沒有用到,後邊呼叫兩個用例的時候才用到了
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import unittest
from mathfunc import *
class TestMathFuna(unittest.TestCase):
def test_multi(self):
self.assertEqual(6,multi(2,3))
def test_minus(self):
self.assertEqual(1,minus(3,2))
def test_divide(self):
self.assertEqual(2,divide(6,3))
@unittest.skip("i don't want to run this case.")
def test_minus(self):
self.assertEqual(1, minus(3, 2))
if __name__== '__main__':
unittest.main(verbosity=2)
執行單個測試方法:
呼叫test_mathfunc.py的測試方法,能執行test_mathfunc.py裡的test_minus、test_add和test_divide
test_suit.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import unittest
from test_mathfunc import TestMathFunc#匯入test_mathfunc裡的TestMathFunc類
if __name__=='__main__':
suite=unittest.TestSuite()
tests=[TestMathFunc("test_minus"),TestMathFunc("test_add"),TestMathFunc("test_divide")]
suite.addTests(tests)
runner=unittest.TextTestRunner(verbosity=2)
runner.run(suite)
執行單個測試方法或整個測試類
1.直接用addTest方法新增單個TestCase
2.用addTests + TestLoader新增整個測試類
TestLoader:
loadTestsFromName()
loadTestsFromTestCase()
test_suit1.py
import unittest
from test_mathfunc import TestMathFunc
if __name__=='__main__':
suite = unittest.TestSuite()
# 直接用addTest方法新增單個TestCase
suite.addTest(TestMathFunc("test_multi"))
# 用addTests + TestLoader
# loadTestsFromName(),傳入'模組名.TestCase名'
suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
suite.addTests(unittest.TestLoader().loadTestsFromNames(['test_mathfunc.TestMathFunc'])) # loadTestsFromNames(),類似,傳入列表
# loadTestsFromTestCase(),傳入TestCase
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
在專案中生成一個文字的測試報告
test_suit2.py
# -*- coding: utf-8 -*-
import unittest
from test_mathfunc import TestMathFunc
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))
with open('UnittestTextReport.txt', 'a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)
又寫了一個test_mathfuna來測試兩個用例的呼叫
test_suittwo.py
import unittest
from test_mathfunc import TestMathFunc
from test_mathfuna import TestMathFuna
if __name__=='__main__':
suite = unittest.TestSuite()
# 用addTests + TestLoader
# loadTestsFromName(),傳入'模組名.TestCase名'
suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfuna.TestMathFuna'))
with open('UnittestTextReporttwo.txt', 'a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)
test_suittwo1.py
# -*- coding:utf-8 -*-
import unittest
from test_mathfunc import TestMathFunc
from test_mathfuna import TestMathFuna
if __name__=='__main__':
suite=unittest.TestSuite()
tests=[TestMathFunc("test_minus"),TestMathFunc("test_add"),TestMathFunc("test_divide")]
tests1=[TestMathFuna("test_divide")]
suite.addTests(tests)
suite.addTests(tests1)
with open('UnittestTextReporttwo2.txt', 'a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)
生成html格式的測試報告
test_suit Open Html.py
# coding=utf-8
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")]
suite.addTests(tests)
with open('HTMLReport1.html', 'wb+') as f:
runner = HTMLTestRunner(stream=f,
title='MathFunc Test Report',
description='generated by HTMLTestRunner.',
verbosity=2
)
runner.run(suite)
這裡遇到了一個問題:python3 引入HTMLTestRunner執行 報錯 ImportError: No module named ‘StringIO’
這個我在個人分類的使用appium中遇到的問題中有寫:
https://blog.csdn.net/weixin_40412060/article/details/82841473