成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Python中的單元測(cè)試

Heier / 1701人閱讀

摘要:每個(gè)測(cè)試方法的名稱以單詞開頭,單元測(cè)試是如何識(shí)別它們是測(cè)試的。它還意味著知道測(cè)試文件中有多少單元測(cè)試,而不是簡(jiǎn)單地知道有多少表達(dá)式您可能已經(jīng)注意到將每個(gè)行作為多帶帶的測(cè)試計(jì)數(shù)。

來源 | 愿碼(ChainDesk.CN)內(nèi)容編輯

愿碼Slogan | 連接每個(gè)程序員的故事

網(wǎng)站 | http://chaindesk.cn

愿碼愿景 | 打造全學(xué)科IT系統(tǒng)免費(fèi)課程,助力小白用戶、初級(jí)工程師0成本免費(fèi)系統(tǒng)學(xué)習(xí)、低成本進(jìn)階,幫助BAT一線資深工程師成長(zhǎng)并利用自身優(yōu)勢(shì)創(chuàng)造睡后收入。

官方公眾號(hào) | 愿碼 | 愿碼服務(wù)號(hào) | 區(qū)塊鏈部落

免費(fèi)加入愿碼全思維工程師社群 | 任一公眾號(hào)回復(fù)“愿碼”兩個(gè)字獲取入群二維碼


本文閱讀時(shí)長(zhǎng):11min

基本單元測(cè)試

在我們開始討論新的概念和功能之前,讓我們來看看如何使用unittest來表達(dá)我們已經(jīng)學(xué)到的想法。這樣,我們就能有一些堅(jiān)實(shí)的基礎(chǔ)來建立我們的新理解。

采取行動(dòng)的時(shí)間-用unittest測(cè)試PID

我們將訪問PID類(或至少訪問PID類的測(cè)試)。我們將編寫測(cè)試,以便它們?cè)趗nittest框架內(nèi)運(yùn)行。

我們將使用unittest框架實(shí)現(xiàn)測(cè)試。

創(chuàng)建一個(gè)名為新文件test_pid.py在同一目錄pid.py。請(qǐng)注意,這是一個(gè).py文件:unittest測(cè)試是純 python源代碼,而不是包含源代碼的純文本。這意味著從紀(jì)錄片的角度來看,測(cè)試的用處不大,但可以交換其他好處。

將以下代碼插入到新創(chuàng)建的test_pid.py中

from unittest import TestCase, main
from mocker import Mocker
import pid
class test_pid_constructor(TestCase):
 def test_without_when(self):
 mocker = Mocker()
 mock_time = mocker.replace("time.time")
 mock_time()
 mocker.result(1.0)
 mocker.replay()
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12)
 mocker.restore()
 mocker.verify()
 self.assertEqual(controller.gains, (0.5, 0.5, 0.5))
 self.assertAlmostEqual(controller.setpoint[0], 0.0)
 self.assertEqual(len(controller.setpoint), 1)
 self.assertAlmostEqual(controller.previous_time, 1.0)
 self.assertAlmostEqual(controller.previous_error, -12.0)
 self.assertAlmostEqual(controller.integrated_error, 0)
 def test_with_when(self):
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=1, initial=12,
 when=43)
 self.assertEqual(controller.gains, (0.5, 0.5, 0.5))
 self.assertAlmostEqual(controller.setpoint[0], 1.0)
 self.assertEqual(len(controller.setpoint), 1)
 self.assertAlmostEqual(controller.previous_time, 43.0)
 self.assertAlmostEqual(controller.previous_error, -11.0)
 self.assertAlmostEqual(controller.integrated_error, 0)
class test_calculate_response(TestCase):
 def test_without_when(self):
 mocker = Mocker()
 mock_time = mocker.replace("time.time")
 mock_time()
 mocker.result(1.0)
 mock_time()
 mocker.result(2.0)
 mock_time()
 mocker.result(3.0)
 mock_time()
 mocker.result(4.0)
 mock_time()
 mocker.result(5.0)
 mocker.replay()
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12)
 self.assertEqual(controller.calculate_response(6), -3)
 self.assertEqual(controller.calculate_response(3), -4.5)
 self.assertEqual(controller.calculate_response(-1.5), -0.75)
 self.assertEqual(controller.calculate_response(?2.25), 
?1.125)
 mocker.restore()
 mocker.verify()
 def test_with_when(self):
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12,
 when=1)
 self.assertEqual(controller.calculate_response(6, 2), -3)
 self.assertEqual(controller.calculate_response(3, 3), -4.5)
 self.assertEqual(controller.calculate_response(?1.5, 4), 
?0.75)
 self.assertEqual(controller.calculate_response(?2.25, 5), 
?1.125)
if __name__ == "__main__":
 main()

鍵入以下命令運(yùn)行測(cè)試:$ python test_pid.py

讓我們?yōu)g覽代碼部分,看看每個(gè)部分的作用。

from unittest import TestCase, main
from mocker import Mocker
import pid
class test_pid_constructor(TestCase):
 def test_without_when(self):
 mocker = Mocker()
 mock_time = mocker.replace("time.time")
 mock_time()
 mocker.result(1.0)
 mocker.replay()
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12)
 mocker.restore()
 mocker.verify()
 self.assertEqual(controller.gains, (0.5, 0.5, 0.5))
 self.assertAlmostEqual(controller.setpoint[0], 0.0)
 self.assertEqual(len(controller.setpoint), 1)
 self.assertAlmostEqual(controller.previous_time, 1.0)
 self.assertAlmostEqual(controller.previous_error, -12.0)
 self.assertAlmostEqual(controller.integrated_error, 0)

在一些設(shè)置代碼之后,我們進(jìn)行了測(cè)試,當(dāng)沒有給出when參數(shù)時(shí),PID控制器正常工作。Mocker用于將time.time替換為始終返回可預(yù)測(cè)值的模擬,然后我們使用多個(gè)斷言來確認(rèn)控制器的屬性已初始化為預(yù)期值。

def test_with_when(self):
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=1, initial=12,
 when=43)
 self.assertEqual(controller.gains, (0.5, 0.5, 0.5))
 self.assertAlmostEqual(controller.setpoint[0], 1.0)
 self.assertEqual(len(controller.setpoint), 1)
 self.assertAlmostEqual(controller.previous_time, 43.0)
 self.assertAlmostEqual(controller.previous_error, -11.0)
 self.assertAlmostEqual(controller.integrated_error, 0)

此測(cè)試確認(rèn)在提供when參數(shù)時(shí)PID構(gòu)造函數(shù)正常工作。與之前的測(cè)試不同,不需要使用Mocker,因?yàn)闇y(cè)試的結(jié)果不應(yīng)該依賴于除參數(shù)值之外的任何東西 - 當(dāng)前時(shí)間是無關(guān)緊要的。

class test_calculate_response(TestCase):
 def test_without_when(self):
 mocker = Mocker()
 mock_time = mocker.replace("time.time")
 mock_time()
 mocker.result(1.0)
 mock_time()
 mocker.result(2.0)
 mock_time()
 mocker.result(3.0)
 mock_time()
 mocker.result(4.0)
 mock_time()
 mocker.result(5.0)
 mocker.replay()
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12)
 self.assertEqual(controller.calculate_response(6), -3)
 self.assertEqual(controller.calculate_response(3), -4.5)
 self.assertEqual(controller.calculate_response(-1.5), -0.75)
 sel+f.assertEqual(controller.calculate_response(?2.25), 
?1.125)
 mocker.restore()
 mocker.verify()

此類中的測(cè)試描述了calculate_response方法的預(yù)期行為。第一個(gè)測(cè)試檢查未提供可選的when參數(shù)時(shí)的行為,并模擬time.time以使該行為可預(yù)測(cè)。

def test_with_when(self):
 controller = pid.PID(P=0.5, I=0.5, D=0.5,
 setpoint=0, initial=12,
 when=1)
 self.assertEqual(controller.calculate_response(6, 2), -3)
 self.assertEqual(controller.calculate_response(3, 3), -4.5)
 self.assertEqual(controller.calculate_response(?1.5, 4), 
?0.75)
 self.assertEqual(controller.calculate_response(?2.25, 5), 
?1.125)

在此測(cè)試中,提供了when參數(shù),因此無需模擬time.time。我們只需檢查結(jié)果是否符合預(yù)期。

我們執(zhí)行的實(shí)際測(cè)試與doctest中編寫的測(cè)試相同。到目前為止,我們所看到的只是一種表達(dá)它們的不同方式。

首先要注意的是,測(cè)試文件被劃分為繼承自unittest.TestCase的類,每個(gè)類都包含一個(gè)或多個(gè)測(cè)試方法。每個(gè)測(cè)試方法的名稱以單詞test開頭,單元測(cè)試是如何識(shí)別它們是測(cè)試的。

每種測(cè)試方法都包含對(duì)單個(gè)單元的單個(gè)測(cè)試。這為我們提供了一種方便的方法來構(gòu)建我們的測(cè)試,將相關(guān)測(cè)試組合到同一個(gè)類中,以便更容易找到它們。

將每個(gè)測(cè)試放入自己的方法意味著每個(gè)測(cè)試都在一個(gè)獨(dú)立的命名空間中執(zhí)行,這使得相對(duì)于doctest風(fēng)格的測(cè)試,使得單元測(cè)試式測(cè)試更容易相互干擾。它還意味著unittest知道測(cè)試文件中有多少單元測(cè)試,而不是簡(jiǎn)單地知道有多少表達(dá)式(您可能已經(jīng)注意到doctest將每個(gè)>>>行作為多帶帶的測(cè)試計(jì)數(shù))。最后,將每個(gè)測(cè)試放在自己的方法中意味著每個(gè)測(cè)試都有一個(gè)名稱,這可能是一個(gè)有價(jià)值的功能。

unittest中的測(cè)試并不直接關(guān)注任何不屬于調(diào)用TestCase的assert方法的任何內(nèi)容。這意味著當(dāng)我們使用Mocker時(shí),我們不必?fù)?dān)心從演示表達(dá)式返回的模擬對(duì)象,除非我們想要使用它們。這也意味著我們需要記住寫一個(gè)斷言來描述我們想要檢查的測(cè)試的每個(gè)方面。我們將很快介紹TestCase的各種斷言方法。

如果您無法執(zhí)行測(cè)試,則測(cè)試沒有多大用處。目前,我們將采用的方式是通過Python解釋器將測(cè)試文件作為程序執(zhí)行時(shí) 調(diào)用unittest.main。這是運(yùn)行unittest代碼的最簡(jiǎn)單方法,但是當(dāng)你在很多文件中分布了大量測(cè)試時(shí),這很麻煩。

如果__name__ =="__ main__":當(dāng) Python加載任何模塊時(shí),它將該模塊的名稱存儲(chǔ)在模塊中名為__name__的變量中(除非該模塊是在命令行上傳遞給解釋器的模塊)。該模塊始終將字符串"__main__"綁定到其__name__變量。因此,如果__name__ =="__ main__":表示 - 如果此模塊直接從命令行執(zhí)行。

Assertions

Assertions是我們用來告訴unittest測(cè)試的重要結(jié)果是什么的機(jī)制。通過使用適當(dāng)?shù)臄嘌裕覀兛梢詼?zhǔn)確地告訴unittest每次測(cè)試的期望。

assertTrue

當(dāng)我們調(diào)用self.assertTrue(expression)時(shí),我們告訴unittest表達(dá)式必須為true才能使測(cè)試成功。

這是一個(gè)非常靈活的斷言,因?yàn)槟梢酝ㄟ^編寫適當(dāng)?shù)牟紶柋磉_(dá)式來檢查幾乎任何內(nèi)容。這也是你應(yīng)該考慮使用的最后一個(gè)斷言之一,因?yàn)樗鼪]有告訴unittest你正在進(jìn)行的比較的類型,這意味著unittest無法清楚地告訴你如果測(cè)試失敗會(huì)出現(xiàn)什么問題。

有關(guān)此示例,請(qǐng)考慮以下測(cè)試代碼,其中包含兩個(gè)保證失敗的測(cè)試:

from unittest import TestCase, main
class two_failing_tests(TestCase):
 def test_assertTrue(self):
 self.assertTrue(1 == 1 + 1)
 def test_assertEqual(self):
 self.assertEqual(1, 1 + 1)
if __name__ == "__main__":
 main()

看起來兩個(gè)測(cè)試似乎是可以互換的,因?yàn)閮蓚€(gè)測(cè)試都是相同的。當(dāng)然他們都會(huì)失?。ɑ蛘咴诓惶赡艿那闆r下,他們都會(huì)失?。?,所以為什么選擇一個(gè)而不是另一個(gè)呢?

看看我們運(yùn)行測(cè)試時(shí)會(huì)發(fā)生什么(并且還注意到測(cè)試沒有按照它們編寫的順序執(zhí)行;測(cè)試完全相互獨(dú)立,所以沒關(guān)系,對(duì)吧?):

你看得到差別嗎?該assertTrue測(cè)試能夠正確地確定測(cè)試失敗,但它不知道夠報(bào)告關(guān)于失敗原因的任何有用的信息。該assertEqual便測(cè)試,而另一方面,他知道首先,它是檢查兩個(gè)表達(dá)式是相等的,其次它知道如何呈現(xiàn)的結(jié)果,因此,他們將是最有用的:通過評(píng)估各個(gè)它是表達(dá)的比較并在結(jié)果之間放置一個(gè)!=符號(hào)。它告訴我們什么期望失敗,以及相關(guān)表達(dá)式評(píng)估的內(nèi)容。

assertFalse

assertFalse方法會(huì)成功時(shí)assertTrue方法會(huì)失敗,反之亦然。它在產(chǎn)生assertTrue所具有的有用輸出方面具有相同的限制,并且在能夠測(cè)試幾乎任何條件方面具有相同的靈活性。

assertEqual

正如assertTrue討論中所提到的,assertEqual斷言檢查它的兩個(gè)參數(shù)實(shí)際上是相等的,并且如果它們不是,則報(bào)告失敗,以及參數(shù)的實(shí)際值。

assertNotEqual

assertNotEqual每當(dāng)斷言失敗assertEqual便斷言會(huì)成功,反之亦然。報(bào)告失敗時(shí),其輸出表明兩個(gè)表達(dá)式的值相等,并為您提供這些值。

assertAlmostEqual

正如我們之前看到的,比較浮點(diǎn)數(shù)可能很麻煩。特別是,檢查兩個(gè)浮點(diǎn)數(shù)是否相等是有問題的,因?yàn)槟憧赡芷谕嗟鹊氖虑?- 在數(shù)學(xué)上是相等的 - 可能仍然最終在最低有效位之間不同。浮點(diǎn)數(shù)僅在每個(gè)位相同時(shí)才相等。

為了解決這個(gè)問題,unittest提供了assertAlmostEqual,它檢查兩個(gè)浮點(diǎn)值是否幾乎相同; 它們之間的少量差異是可以容忍的。

讓我們看一下這個(gè)問題。如果取平方根7,然后將其平方,則結(jié)果應(yīng)為7.這是一對(duì)檢查該事實(shí)的測(cè)試:

from unittest import TestCase, main
class floating_point_problems(TestCase):
 def test_assertEqual(self):
 self.assertEqual((7.0 ** 0.5) ** 2.0, 7.0)
def test_assertAlmostEqual(self): 
 self.assertAlmostEqual((7.0 ** 0.5) ** 2.0, 7.0) 
if __name__ == "__main__": 
 main()  

test_assertEqual方法檢查

這在現(xiàn)實(shí)中是如此。然而,在計(jì)算機(jī)可用的更專業(yè)的數(shù)字系統(tǒng)中,取7的平方根然后平方它并不能讓我們回到7,所以這個(gè)測(cè)試將失敗。稍等一下。

測(cè)試test_assertAlmostEqual方法檢查

即使計(jì)算機(jī)會(huì)同意這是真的,所以這個(gè)測(cè)試應(yīng)該通過。

運(yùn)行這些測(cè)試會(huì)產(chǎn)生以下結(jié)果,盡管您返回的具體數(shù)字可能會(huì)有所不同,具體取決于運(yùn)行測(cè)試的計(jì)算機(jī)的詳細(xì)信息:

不幸的是,浮點(diǎn)數(shù)不精確,因?yàn)閷?shí)數(shù)行上的大多數(shù)數(shù)字不能用有限的,非重復(fù)的數(shù)字序列表示,更不用說僅僅64位。因此,你從評(píng)估數(shù)學(xué)表達(dá)式得到的回報(bào)并不是很好。雖然 - 或者幾乎任何其他類型的工作都足夠接近政府工作 - 所以我們不希望我們的測(cè)試對(duì)這個(gè)微小的差異進(jìn)行狡辯。因此,當(dāng)我們比較浮點(diǎn)數(shù)是否相等時(shí),我們應(yīng)該使用assertAlmostEqualassertNotAlmostEqual。

這個(gè)問題通常不會(huì)延續(xù)到其他比較運(yùn)算符中。例如,檢查一個(gè)浮點(diǎn)數(shù)小于另一個(gè),由于無意義的錯(cuò)誤,不太可能產(chǎn)生錯(cuò)誤的結(jié)果。只有在平等的情況下,這個(gè)問題才會(huì)困擾我們。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/43760.html

相關(guān)文章

  • 說說Python中的單元測(cè)試

    摘要:必然的,他們會(huì)拋棄標(biāo)準(zhǔn)庫(kù)中的,使用或者發(fā)明自己心儀的單元測(cè)試框架。究其原因,一些人會(huì)說時(shí)間寫代碼都不夠,哪還有空寫單元測(cè)試。最后我的個(gè)人觀點(diǎn),單元測(cè)試其實(shí)還有一個(gè)非常重要的作用,就是替代函數(shù)文檔注釋。希望從今天起,你的代碼也都有單元測(cè)試。 單元測(cè)試是每種編程語(yǔ)言必學(xué)的課題,是保護(hù)開發(fā)者的強(qiáng)力護(hù)盾,每個(gè)程序員都在時(shí)間允許的情況下盡可能多的寫單元測(cè)試,今天我們不討論其必要性,只拋磚引玉聊一...

    chengjianhua 評(píng)論0 收藏0
  • 通過demo學(xué)習(xí)OpenStack開發(fā)所需的基礎(chǔ)知識(shí) -- 單元測(cè)試

    摘要:本文將進(jìn)入單元測(cè)試的部分,這也是基礎(chǔ)知識(shí)中最后一個(gè)大塊。本文將重點(diǎn)講述和中的單元測(cè)試的生態(tài)環(huán)境。另外,在中指定要運(yùn)行的單元測(cè)試用例的完整語(yǔ)法是。中使用模塊管理單元測(cè)試用例。每個(gè)項(xiàng)目的單元測(cè)試代碼結(jié)構(gòu)可 本文將進(jìn)入單元測(cè)試的部分,這也是基礎(chǔ)知識(shí)中最后一個(gè)大塊。本文將重點(diǎn)講述Python和OpenStack中的單元測(cè)試的生態(tài)環(huán)境。 單元測(cè)試的重要性 github上有個(gè)人畫了一些不同語(yǔ)言的學(xué)...

    douzifly 評(píng)論0 收藏0
  • python學(xué)習(xí)筆記- 單元測(cè)試,UnitTest

    摘要:所謂的單元測(cè)試,就是對(duì)一個(gè)模塊,一個(gè)函數(shù),或則是一個(gè)類進(jìn)行正確性檢測(cè)的一類測(cè)試工作。當(dāng)然,單元測(cè)試也會(huì)讓代碼量大大增加。編寫單元測(cè)試代碼需要引入的包。再所有單元測(cè)試開始前運(yùn)行函數(shù)在所有單元測(cè)試運(yùn)行后運(yùn)行。 所謂的單元測(cè)試,就是對(duì)一個(gè)模塊,一個(gè)函數(shù),或則是一個(gè)類進(jìn)行正確性檢測(cè)的一類測(cè)試工作。 以測(cè)試驅(qū)動(dòng)的開發(fā)方式叫做測(cè)試驅(qū)動(dòng)開發(fā)(Test Drived Development). 這種開...

    k00baa 評(píng)論0 收藏0
  • 2021年軟件測(cè)試工具總結(jié)——單元測(cè)試工具

    摘要:?jiǎn)卧獪y(cè)試框架作為的標(biāo)準(zhǔn)庫(kù),是其他單元測(cè)試框架的基礎(chǔ)??梢院秃团浜鲜褂镁帉憜卧獪y(cè)試。官網(wǎng)地址單元測(cè)試覆蓋率工具單元測(cè)試中還需要用到代碼覆蓋率工具。代碼覆蓋率統(tǒng)計(jì)工具用來發(fā)現(xiàn)沒有被測(cè)試覆蓋的代碼,完善單元測(cè)試的覆蓋率。 在應(yīng)用程序中,單元是具有一個(gè)或多個(gè)輸入和單個(gè)輸出的軟件中最小可測(cè)試部分。單元...

    qingshanli1988 評(píng)論0 收藏0
  • Python單元測(cè)試兩種方法解答

      小編這這篇文章的主要目的,主要是給大家進(jìn)行一個(gè)詳解,解釋一下關(guān)于Python中,單元格測(cè)試的一些具體方法,那么,測(cè)試的方法都有什么呢?下面小編就給大家詳細(xì)的做出一個(gè)解答?! ∫弧⑶把浴 ython的兩個(gè)單元測(cè)試包分別是doctest和unittest,這兩個(gè)包的使用起來各有長(zhǎng)處,適用于不同的場(chǎng)景  doctest:直接寫在方法體中,利用了python動(dòng)態(tài)語(yǔ)言的特性,書寫方式簡(jiǎn)單明了,前提是項(xiàng)...

    89542767 評(píng)論0 收藏0
  • 代碼測(cè)試用例指南

    摘要:測(cè)試的通用規(guī)則測(cè)試單元應(yīng)該集中于小部分的功能,并且證明它是對(duì)的。通過去除依賴盡量使測(cè)試單元快速運(yùn)行。實(shí)現(xiàn)來持續(xù)集成通過代碼提交的本地或者來持續(xù)集成測(cè)試你的代碼。 原文鏈接:http://blog.speedx.com/backend-test-guide 將測(cè)試代碼和運(yùn)行代碼一起寫是一種非常好的習(xí)慣。聰明地使用這種方法將會(huì)幫助你更加精確地定義代碼的含義,并且代碼的耦合性更低。 測(cè)試的通...

    chinafgj 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<