欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

全面介紹python中很常用的單元測試框架unitest

 更新時間:2020年12月14日 10:24:46   作者:luyuze95  
這篇文章主要介紹了python中很常用的單元測試框架unitest的相關資料,幫助大家更好的利用python進行單元測試,感興趣的朋友可以了解下

1、unitest主要功能模塊介紹

unitest主要包含TestCase、TestSuite、TestLoader、TextTestRunner、TextTestResult這幾個功能模塊。

  • TestCase:一個TestCase實例就是一個測試用例,一個測試用例就是一個完整的測試流程,包括測試前環(huán)境的搭建,測試代碼的執(zhí)行,以及測試后環(huán)境的還原或者銷毀。元測試的本質也就在這里,一個測試用例是一個完整的測試單元,可以對某一具體問題進行檢查驗證。
  • TestSuite:多個測試用例集合在一起就是TestSuite,TestSuite也可以嵌套TestSuite。
  • TestLoader:TestLoader的作用是將Testcase加載到TestSuite中。
  • TextTestRunner:TextTestRunner是用來執(zhí)行測試用例的,其中的run(test)會執(zhí)行TestSuite/TestCase中的run(result)方法。
  • TextTestResult:TextTestResult用來保存測試結果,其中包括運行了多少測試用例,成功了多少,失敗了多少等信息。

整個流程為:寫好TestCase,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運行TestSuite,運行的結果保存在TextTestResult中。

2、實例介紹

首先準備幾個待測的方法,寫在test_func.py中。

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


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


def lower_str(string):
  return string.lower()


def square(x):
  return x ** 2

準備好幾個待測的方法之后,為這些方法寫一個測試用例,寫入our_testcase.py中。

import unittest
from test_func import *


class TestFunc(unittest.TestCase):
  """Test test_func.py"""

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

  def test_multi(self):
    """Test func multi"""
    self.assertEqual(6, multi(2, 3))
    self.assertNotEqual(8, multi(3, 3))

  def test_lower_str(self):
    """Test func lower_str"""
    self.assertEqual("abc", lower_str("ABC"))
    self.assertNotEqual("Dce", lower_str("DCE"))

  def test_square(self):
    """Test func square"""
    self.assertEqual(17, square(4)) # 這里故意設計一個會出錯的用例,測試4的平方等于17,實際上并不等于。
    self.assertNotEqual(35, square(6))


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

這里寫好之后,進入命令行終端,執(zhí)行python our_testcase.py,執(zhí)行結果如下。

...F
======================================================================
FAIL: test_square (__main__.TestFunc)
Test func square
----------------------------------------------------------------------
Traceback (most recent call last):
 File "our_testcase.py", line 27, in test_square
  self.assertEqual(17, square(4))
AssertionError: 17 != 16

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

FAILED (failures=1)

這里分析一下這個執(zhí)行結果。首先能夠看到一共運行了4個測試用例,失敗了1個,并且給出了失敗原因,AssertionError: 17 != 16,這是我們故意留下的錯誤漏洞,被測試用例測試出來了。

第一行...F中,一個點.代表測試成功,F代表失敗,我們的測試結果中,前三個成功了,第四個失敗了,總共是四個測試,其余的符號中E代表出錯,S代表跳過。

特別說明的一點是,測試的執(zhí)行順序跟方法的順序沒有關系,四個測試是隨機先后執(zhí)行的。

每個測試方法編寫的時候,都要以test開頭,比如test_square,否則是不被unitest識別的。

在unitest.main()中加上verbosity參數可以控制輸出的錯誤報告的詳細程序,默認是1,如果設為0,則不輸出每一用例的執(zhí)行結果,即上面的第一行的執(zhí)行結果內容。如果設為2,則輸出詳細的執(zhí)行結果。

修改our_testcase.py中主函數。

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

執(zhí)行結果如下。

test_add (__main__.TestFunc)
Test func add ... ok
test_lower_str (__main__.TestFunc)
Test func lower_str ... ok
test_multi (__main__.TestFunc)
Test func multi ... ok
test_square (__main__.TestFunc)
Test func square ... FAIL

======================================================================
FAIL: test_square (__main__.TestFunc)
Test func square
----------------------------------------------------------------------
Traceback (most recent call last):
 File "our_testcase.py", line 27, in test_square
  self.assertEqual(17, square(4))
AssertionError: 17 != 16

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

FAILED (failures=1)

可以看到,每一個用例的詳細執(zhí)行情況以及用例名,用例描述均被輸出了出來,在測試方法下加代碼示例中的"""Doc String""",在用例執(zhí)行時,會將該字符串作為此用例的描述,加合適的注釋能夠使輸出的測試報告更加便于閱讀。

3、組織TestSuite

按照上面的測試方法,我們無法控制用例執(zhí)行的順序,這樣顯然是不合理的,因為在一些測試過程中,我們肯定需要控制先測試某些用例,再測試某些用例,這些用例有先后的因果關系。在這里,我們就需要用到TestSuite。我們添加到TestSuite中的case是會按照添加的順序執(zhí)行的。

還有一個問題是,我們現在只有一個測試文件,我們直接執(zhí)行該文件即可,但如果有多個測試文件,怎么進行組織,總不能一個個文件執(zhí)行吧,答案也在TestSuite中。

新建一個文件,test_suite.py。

import unittest
from our_testcase import TestFunc

if __name__ == '__main__':
  suite = unittest.TestSuite()
  tests = [TestFunc("test_square"), TestFunc("test_lower_str"), TestFunc("test_multi")]
  suite.addTests(tests)
  runner = unittest.TextTestRunner(verbosity=2)
  runner.run(suite)

執(zhí)行結果如下。

test_square (our_testcase.TestFunc)
Test func square ... FAIL
test_lower_str (our_testcase.TestFunc)
Test func lower_str ... ok
test_multi (our_testcase.TestFunc)
Test func multi ... ok

======================================================================
FAIL: test_square (our_testcase.TestFunc)
Test func square
----------------------------------------------------------------------
Traceback (most recent call last):
 File "/Users/luyuze/projects/test/our_testcase.py", line 27, in test_square
  self.assertEqual(17, square(4))
AssertionError: 17 != 16

----------------------------------------------------------------------
Ran 3 tests in 0.000s

FAILED (failures=1)

這樣,用例執(zhí)行的順序就是按照我們添加進去的順序來執(zhí)行的了。

上面使用的是TestSuite的addTests()方法,并直接傳入TestCase列表,也有一些其他的方法可以向TestSuite中添加用例。

# 直接用addTest方法添加單個TestCase
suite.addTest(TestMathFunc("test_multi"))


# 使用loadTestFromName,傳入模塊名.TestCase名,下面?zhèn)z方法效果相同
suite.addTests(unittest.TestLoader().loadTestsFromName('our_testcase.TestFunc'))
suite.addTests(unittest.TestLoader().loadTestsFromNames(['our_testcase.TestFunc']))


# loadTestsFromTestCase(),傳入TestCase
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestFunc))

用TestLoader的方法是無法對case進行排序的,同時,suite中也可以套suite。

4、輸出文件

用例組織好了,但是結果只能輸出到控制臺,這樣沒辦法查看之前的執(zhí)行記錄,我們想將結果輸出到文件。

修改test_suite.py。

import unittest
from our_testcase import TestFunc

if __name__ == '__main__':
  suite = unittest.TestSuite()
  tests = [TestFunc("test_square"), TestFunc("test_lower_str"), TestFunc("test_multi")]
  suite.addTests(tests)

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

5、測試前后的處理

在之前的測試中,可能會存在這樣的問題:如果要在測試之前準備環(huán)境,測試完成之后做一些清理怎么辦?這里需要用到的是setUp()和tearDown()。

修改our_testcase.py。

import unittest
from test_func import *


class TestFunc(unittest.TestCase):
  """Test test_func.py"""
  
  def setUp(self):
    print("do something before testcase")

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

  def test_multi(self):
    """Test func multi"""
    self.assertEqual(6, multi(2, 3))
    self.assertNotEqual(8, multi(3, 3))

  def test_lower_str(self):
    """Test func lower_str"""
    self.assertEqual("abc", lower_str("ABC"))
    self.assertNotEqual("Dce", lower_str("DCE"))

  def test_square(self):
    """Test func square"""
    self.assertEqual(17, square(4))
    self.assertNotEqual(35, square(6))
    
  def tearDownClass(self):
    print("do something after testcase")


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

執(zhí)行結果:

test_add (__main__.TestFunc)
Test func add ... do something before testcase
do something after testcase
ok
test_lower_str (__main__.TestFunc)
Test func lower_str ... do something before testcase
do something after testcase
ok
test_multi (__main__.TestFunc)
Test func multi ... do something before testcase
do something after testcase
ok
test_square (__main__.TestFunc)
Test func square ... do something before testcase
do something after testcase
FAIL

======================================================================
FAIL: test_square (__main__.TestFunc)
Test func square
----------------------------------------------------------------------
Traceback (most recent call last):
 File "our_testcase.py", line 30, in test_square
  self.assertEqual(17, square(4))
AssertionError: 17 != 16

----------------------------------------------------------------------
Ran 4 tests in 0.001s

FAILED (failures=1)

可以發(fā)現setUp()和tearDown()在每個case前后都執(zhí)行了一次。如果要在所有case執(zhí)行之前和所有case執(zhí)行之后準備和清理環(huán)境,我們可以使用setUpClass() 與 tearDownClass()。

class TestFunc(unittest.TestCase):
  """Test test_func.py"""

  @classmethod
  def setUpClass(cls):
    print "This setUpClass() method only called once."

  @classmethod
  def tearDownClass(cls):
    print "This tearDownClass() method only called once too."

6、跳過case

如果我們臨時想要跳過某個case不執(zhí)行,unitest也有相應的方法。

1、skip裝飾器

# -*- coding: utf-8 -*-

import unittest
from test_func import *


class TestFunc(unittest.TestCase):
  """Test test_func.py"""

  @unittest.skip('do not run this case')
  def test_add(self):
    """Test func add"""
    self.assertEqual(3, add(1, 2))
    self.assertNotEqual(3, add(1, 3))

  def test_multi(self):
    """Test func multi"""
    self.assertEqual(6, multi(2, 3))
    self.assertNotEqual(8, multi(3, 3))

  def test_lower_str(self):
    """Test func lower_str"""
    self.assertEqual("abc", lower_str("ABC"))
    self.assertNotEqual("Dce", lower_str("DCE"))

  def test_square(self):
    """Test func square"""
    self.assertEqual(17, square(4))
    self.assertNotEqual(35, square(6))


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

執(zhí)行結果:

test_add (__main__.TestFunc)
Test func add ... skipped 'do not run this case'
test_lower_str (__main__.TestFunc)
Test func lower_str ... ok
test_multi (__main__.TestFunc)
Test func multi ... ok
test_square (__main__.TestFunc)
Test func square ... FAIL

======================================================================
FAIL: test_square (__main__.TestFunc)
Test func square
----------------------------------------------------------------------
Traceback (most recent call last):
 File "our_testcase.py", line 28, in test_square
  self.assertEqual(17, square(4))
AssertionError: 17 != 16

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

FAILED (failures=1, skipped=1)

結果顯示為,總共執(zhí)行4個測試,1個失敗,1個被跳過。

skip裝飾器一共有三個 unittest.skip(reason)、unittest.skipIf(condition, reason)、unittest.skipUnless(condition, reason),skip無條件跳過,skipIf當condition為True時跳過,skipUnless當condition為False時跳過。

2、TestCase.skipTest()方法

class TestFunc(unittest.TestCase):
  """Test test_func.py"""

  def test_add(self):
    """Test func add"""
    self.skipTest("do not run this case")
    self.assertEqual(3, add(1, 2))
    self.assertNotEqual(3, add(1, 3))

效果與第一種是一樣的。

以上就是全面介紹python中很常用的單元測試框架unitest的詳細內容,更多關于python 單元測試框架unitest的資料請關注腳本之家其它相關文章!

相關文章

  • python實現批量圖片格式轉換

    python實現批量圖片格式轉換

    這篇文章主要為大家詳細介紹了python實現批量圖片格式轉換的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 在django中使用post方法時,需要增加csrftoken的例子

    在django中使用post方法時,需要增加csrftoken的例子

    這篇文章主要介紹了在django中使用post方法時,需要增加csrftoken的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • 在Anaconda3下使用清華鏡像源安裝TensorFlow(CPU版)

    在Anaconda3下使用清華鏡像源安裝TensorFlow(CPU版)

    這篇文章主要介紹了在Anaconda3下使用清華鏡像源安裝TensorFlow(CPU版),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Django動態(tài)隨機生成溫度前端實時動態(tài)展示源碼示例

    Django動態(tài)隨機生成溫度前端實時動態(tài)展示源碼示例

    本篇文章主要描述的是在動態(tài)隨機生成溫度,在前端動態(tài)實時展示,主要用到兩個東西,一個是APScheduler定時任務 和websocket,最后利用echarts將數據展示出來,下面對這兩個分別進行詳細的解說
    2021-09-09
  • python開發(fā)之list操作實例分析

    python開發(fā)之list操作實例分析

    這篇文章主要介紹了python開發(fā)之list操作方法,結合實例形式分析了list操作的具體用法與相關注意事項,需要的朋友可以參考下
    2016-02-02
  • 對Python閉包與延遲綁定的方法詳解

    對Python閉包與延遲綁定的方法詳解

    今天小編就為大家分享一篇對Python閉包與延遲綁定的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python實現批量轉換文件編碼(批轉換編碼示例)

    python實現批量轉換文件編碼(批轉換編碼示例)

    這篇文章主要介紹了python實現批量轉換文件編碼示例,指定文件編碼、目錄或擴展名即可進行轉換,大家參考使用吧
    2014-01-01
  • python進階之協(xié)程你了解嗎

    python進階之協(xié)程你了解嗎

    這篇文章主要為大家詳細介紹了python進階之協(xié)程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 使用PyQt5實現一個鼠標連點器

    使用PyQt5實現一個鼠標連點器

    這篇文章主要為大家詳細介紹了如何使用PyQt5實現一個鼠標連點器,從而對QVBoxLayout、QHBoxLayout和QStackedWidget進行一個回顧復習,需要的可以參考一下
    2023-12-12
  • 淺談numpy數組中冒號和負號的含義

    淺談numpy數組中冒號和負號的含義

    下面小編就為大家分享一篇淺談numpy數組中冒號和負號的含義,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04

最新評論