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

習(xí)題 47: 自動(dòng)化測(cè)試?

為了確認(rèn)游戲的功能是否正常,你需要一遍一遍地在你的游戲中輸入命令。這個(gè)過(guò)程是很枯燥無(wú)味的。如果能寫(xiě)一小段代碼用來(lái)測(cè)試你的代碼豈不是更好?然后只要你對(duì)程序做了任何修改,或者添加了什么新東西,你只要“跑一下你的測(cè)試”,而這些測(cè)試能確認(rèn)程序依然能正確運(yùn)行。這些自動(dòng)測(cè)試不會(huì)抓到所有的 bug,但可以讓你無(wú)需重復(fù)輸入命令運(yùn)行你的代碼,從而為你節(jié)約很多時(shí)間。

從這一章開(kāi)始,以后的練習(xí)將不會(huì)有“你應(yīng)該看到的結(jié)果”這一節(jié),取而代之的是一個(gè)“你應(yīng)該測(cè)試的東西”一節(jié)。從現(xiàn)在開(kāi)始,你需要為自己寫(xiě)的所有代碼寫(xiě)自動(dòng)化測(cè)試,而這將讓你成為一個(gè)更好的程序員。

我不會(huì)試圖解釋為什么你需要寫(xiě)自動(dòng)化測(cè)試。我要告訴你的是,你想要成為一個(gè)程序員,而程序的作用是讓無(wú)聊冗繁的工作自動(dòng)化,測(cè)試軟件毫無(wú)疑問(wèn)是無(wú)聊冗繁的,所以你還是寫(xiě)點(diǎn)代碼讓它為你測(cè)試的更好。

這應(yīng)該是你需要的所有的解釋了。因?yàn)槟銓?xiě)單元測(cè)試的原因是讓你的大腦更加強(qiáng)健。你讀了這本書(shū),寫(xiě)了很多代碼讓它們實(shí)現(xiàn)一些事情。現(xiàn)在你將更進(jìn)一步,寫(xiě)出懂得你寫(xiě)的其他代碼的代碼。這個(gè)寫(xiě)代碼測(cè)試你寫(xiě)的其他代碼的過(guò)程將強(qiáng)迫你清楚的理解你之前寫(xiě)的代碼。這會(huì)讓你更清晰地了解你寫(xiě)的代碼實(shí)現(xiàn)的功能及其原理,而且讓你對(duì)細(xì)節(jié)的注意更上一個(gè)臺(tái)階。

撰寫(xiě)測(cè)試用例?

我們將拿一段非常簡(jiǎn)單的代碼為例,寫(xiě)一個(gè)簡(jiǎn)單的測(cè)試,這個(gè)測(cè)試將建立在上節(jié)我們創(chuàng)建的項(xiàng)目骨架上面。

首先從你的項(xiàng)目骨架創(chuàng)建一個(gè)叫做 ex47 的項(xiàng)目。確認(rèn)該改名稱(chēng)的地方都有改過(guò),尤其是 tests/ex47_tests.py 這處不要寫(xiě)錯(cuò),另外運(yùn)行 nosetest 確認(rèn)一下沒(méi)有錯(cuò)誤信息。檢查一下 tests/skel_tests.pyc 這個(gè)文件,有的話就把它刪掉,這一點(diǎn)需要尤其注意。

接下來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的 ex47/game.py 文件,里邊放一些用來(lái)被測(cè)試的代碼。我們現(xiàn)在放一個(gè)傻乎乎的小 class 進(jìn)去,用來(lái)作為我們的測(cè)試對(duì)象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Room(object):

    def __init__(self, name, description):
        self.name = name
        self.description = description
        self.paths = {}

    def go(self, direction):
        return self.paths.get(direction, None)

    def add_paths(self, paths):
        self.paths.update(paths)

準(zhǔn)備好了這個(gè)文件,接下來(lái)把測(cè)試骨架改成這樣子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from nose.tools import *
from ex47.game import Room


def test_room():
    gold = Room("GoldRoom", 
                """This room has gold in it you can grab. There's a
                door to the north.""")
    assert_equal(gold.name, "GoldRoom")
    assert_equal(gold.paths, {})

def test_room_paths():
    center = Room("Center", "Test room in the center.")
    north = Room("North", "Test room in the north.")
    south = Room("South", "Test room in the south.")

    center.add_paths({'north': north, 'south': south})
    assert_equal(center.go('north'), north)
    assert_equal(center.go('south'), south)
    
def test_map():
    start = Room("Start", "You can go west and down a hole.")
    west = Room("Trees", "There are trees here, you can go east.")
    down = Room("Dungeon", "It's dark down here, you can go up.")

    start.add_paths({'west': west, 'down': down})
    west.add_paths({'east': start})
    down.add_paths({'up': start})

    assert_equal(start.go('west'), west)
    assert_equal(start.go('west').go('east'), start)
    assert_equal(start.go('down').go('up'), start)

這個(gè)文件 import 了你在 ex47.game 創(chuàng)建的 Room 這個(gè)類(lèi),接下來(lái)我們要做的就是測(cè)試它。于是我們看到一系列的以 test_ 開(kāi)頭的測(cè)試函數(shù),它們就是所謂的“測(cè)試用例(test case)”,每一個(gè)測(cè)試用例里面都有一小段代碼,它們會(huì)創(chuàng)建一個(gè)或者一些房間,然后去確認(rèn)房間的功能和你期望的是否一樣。它測(cè)試了基本的房間功能,然后測(cè)試了路徑,最后測(cè)試了整個(gè)地圖。

這里最重要的函數(shù)時(shí) assert_equal,它保證了你設(shè)置的變量,以及你在 Room 里設(shè)置的路徑和你的期望相符。如果你得到錯(cuò)誤的結(jié)果的話, nosetests 將會(huì)打印出一個(gè)錯(cuò)誤信息,這樣你就可以找到出錯(cuò)的地方并且修正過(guò)來(lái)。

測(cè)試指南?

在寫(xiě)測(cè)試代碼時(shí),你可以照著下面這些不是很?chē)?yán)格的指南來(lái)做:

  1. 測(cè)試腳本要放到 tests/ 目錄下,并且命名為 BLAH_tests.py ,否則 nosetests 就不會(huì)執(zhí)行你的測(cè)試腳本了。這樣做還有一個(gè)好處就是防止測(cè)試代碼和別的代碼互相混掉。
  2. 為你的每一個(gè)模組寫(xiě)一個(gè)測(cè)試。
  3. 測(cè)試用例(函數(shù))保持簡(jiǎn)短,但如果看上去不怎么整潔也沒(méi)關(guān)系,測(cè)試用例一般都有點(diǎn)亂。
  4. 就算測(cè)試用例有些亂,也要試著讓他們保持整潔,把里邊重復(fù)的代碼刪掉。創(chuàng)建一些輔助函數(shù)來(lái)避免重復(fù)的代碼。當(dāng)你下次在改完代碼需要改測(cè)試的時(shí)候,你會(huì)感謝我這一條建議的。重復(fù)的代碼會(huì)讓修改測(cè)試變得很難操作。
  5. 最后一條是別太把測(cè)試當(dāng)做一回事。有時(shí)候,更好的方法是把代碼和測(cè)試全部刪掉,然后重新設(shè)計(jì)代碼。

你應(yīng)該看到的結(jié)果?

~/projects/simplegame $ nosetests
...
----------------------------------------------------------------------
Ran 3 tests in 0.007s

OK

如果一切工作正常的話,你看到的結(jié)果應(yīng)該就是這樣。試著把代碼改錯(cuò)幾個(gè)地方,然后看錯(cuò)誤信息會(huì)是什么,再把代碼改正確。

加分習(xí)題?

  1. 仔細(xì)讀讀 nosetest 相關(guān)的文檔,再去了解一下其他的替代方案。
  2. 了解一下 Python 的 “doc tests” ,看看你是不是更喜歡這種測(cè)試方式。
  3. 改進(jìn)你游戲里的 Room,然后用它重建你的游戲,這次重寫(xiě),你需要一邊寫(xiě)代碼,一邊把單元測(cè)試寫(xiě)出來(lái)。