如何在本地測試Fabric Code

深藍發表於2017-12-14

前一篇部落格講到了如何編譯本地的Fabric Code成映象檔案,那麼如果我們想改Fabric原始碼,實現一些Fabric官方並沒有提供的功能,該怎麼辦呢?這時我們除了改原始碼,增加需要的功能外,還需要能夠跑通Fabric的測試。Fabric的測試主要包括單元測試和行為測試,下面分別介紹。

一、單元測試

單元測試是通過testenv這個映象來完成的,而這個映象的容器在啟動後實際執行的就是unit-test資料夾下面的run.sh指令碼。我們使用make unit-test命令即可對整個Fabric的所有單元測試進行執行。

1.單元測試

因為Fabric是用Go寫的,所以Fabric的單元測試也是用Go的單元測試命令來完成,也就是go test命令。在Fabric的原始碼中,我們看到的所有*_test.go這些就是單元測試的程式碼。這些程式碼在正式編譯的時候是會被自動忽略的,只有在go test命令的時候才會去執行。

以bccsp為例,這是提供密碼學相關方法的介面檔案,在bccsp資料夾下的bccsp.go檔案,而他的單元測試檔案自然就是bccsp_test.go檔案。在該單元測試檔案中,以Test開頭的函式,就是具體的測試用例。我們要跑具體的某一個測試用例,比如其中的TestKeyGenOpts,那麼我們的可以使用命令:

go.exe test github.com\hyperledger\fabric\bccsp -run ^TestKeyGenOpts$

這裡我們可以看到-run後面跟的是一個正規表示式,我們可以寫其他正規表示式來表示一批方法。當然我們也可以不加^$,直接寫方法名。

如果我們不指定具體的測試用例,而只指定包,那麼就是測試整個包下面的所有用例。

go test -v -timeout 30s github.com\hyperledger\fabric\bccsp

這裡我加了2個引數,這兩個引數都是在go test的時候很常用的,-v是輸出詳細資訊。-timeout是設定跑完整個測試的時間限制,如果裡面有死迴圈之類的就會超時而退出。

如果我們要測試不是某個包,而是整個資料夾下面的所有包,那麼我們可以使用“…”來表示。比如:

go test -v -timeout 60s github.com\hyperledger\fabric\bccsp\…

2.效能測試

go test除了提供單元測試外,還有效能測試的功能。前面說到_test.go檔案裡面Test開頭的是單元測試的測試用例入口函式,而效能測試則是以Benchmark開頭。

Fabric本身並沒有寫什麼效能測試的程式碼,但是我們可以從vendor程式碼中找到例子。比如:

github.com\hyperledger\fabric\vendor\github.com\docker\docker\pkg\stdcopy

這裡有個BenchmarkWrite函式,用於測試NewStdWriter.Write的效能,我們使用go test命令帶上-bench引數就可以執行效能測試。效能測試不僅僅關心執行的時間,也關係記憶體的分配情況。再加上-benchmem引數,可以檢視記憶體效能測試結果。

go test -benchmem github.com\hyperledger\fabric\vendor\github.com\docker\docker\pkg\stdcopy -bench ^BenchmarkWrite$

以下是我在本機執行的結果:

BenchmarkWrite-4   5000000     283 ns/op    15507.52 MB/s    0 B/op    0 allocs/op

PASS

ok     github.com/hyperledger/fabric/vendor/github.com/docker/docker/pkg/stdcopy   2.406s

Success: Benchmarks passed.

3.程式碼覆蓋率

程式碼覆蓋率是度量測試自身完整和有訊息的一種手段。通過覆蓋率值,我們可以分析測試程式碼的編寫質量。

在go test命令後跟上-cover引數,就可以提供程式碼覆蓋率百分比的結果。

go test -cover github.com\hyperledger\fabric\bccsp

返回結果:

ok      github.com/hyperledger/fabric/bccsp     2.828s  coverage: 100.0% of statements

但是這裡返回的結果太少了,我們如果希望得到更詳細的覆蓋率資訊,可以指定covermode和converprofile引數。

go test -cover -covermode count -coverprofile c:\Temp\cover.out github.com\hyperledger\fabric\bccsp

這裡是將覆蓋率的結果輸出到C:\Temp\cover.out這個檔案中。同時使用count可以對函式的執行次數進行計數。執行完畢後,我們可以使用以下命令將cover.out轉換為html在瀏覽器中檢視:

go tool cover -html=C:\Temp\cover.out

在瀏覽器中,用綠色表示覆蓋,而執行次數,是需要把滑鼠放上去才會顯示。這是我瀏覽器顯示的覆蓋率結果:

image

二、行為測試

我這裡翻譯成行為測試可能不一定很可取,英文是BDDTests,BDD是敏捷開發中的一個概念,英文是Behavior Driven Development,可以認為是TDD的升級版吧。所有行為測試的程式碼都在Fabric資料夾下面的bddtests資料夾中。

要進行Fabric的行為測試,需要安裝相關的環境,Fabric主要用到的是Behave這個工具,https://github.com/behave/behave

官方給我們提供了安裝指令碼,直接執行:

sudo ./scripts/install_behave.sh

這裡需要安裝的包比較多,安裝完成後我們就可以進行BDD的測試了。

官方的make命令下就為我們提供了執行全部行為測試的命令:

make behave

系統就會按照配置的場景,啟動對應的Docker容器,進行行為測試。

如果我們想跑某一個行為測試,而不是全部,那麼就需要進一步的設定,具體參考:https://github.com/hyperledger/fabric/tree/release/bddtests

依次執行以下程式碼:

sudo pip install virtualenv
sudo pip install virtualenvwrapper
export WORKON_HOME=~/Envs
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv -p /usr/bin/python2.7 behave_venv
執行完上面命令後,我們可以看到我們的命令列變成了:
(behave_venv) studyzy@ubuntu1:~/go/src/github.com/hyperledger/fabric/bddtests$ 
接下來再安裝以下工具:
pip install behave 
pip install grpcio-tools 
pip install "pysha3==1.0b1" 
pip install b3j0f.aop 
pip install jinja2 
pip install pyopenssl 
pip install ecdsa 
pip install python-slugify 
pip install pyyaml

總的來說就是給behave的執行設定了一個虛擬環境,所有程式碼的執行是在這個虛擬環境中執行,不會影響真實環境。

安裝完畢後,我們想要測試某一個BDDTest,那麼可以執行:

cd bddtests
behave -k -D cache-deployment-spec features/bootstrap.feature
這裡測試的就是在bddtests\features\bootstrap.feature的這個例子。
測試完成後,使用
deactivate
命令即可退出虛擬環境,回到我們傳統的命令列下。

三、總結

如果我們要動Fabric的原始碼,那麼首先保證能夠跑通Fabric的單元測試和行為測試,然後再改。如果是新功能模組,那麼也需要寫自己模組的單元測試程式碼。寫完之後用go test來測試,保證我們的程式碼能夠通過單元測試,而且要注意程式碼覆蓋率,保持較高的覆蓋率能夠發現很多程式碼中隱藏的問題。

如果我們的功能涉及到一系列的步驟操作,那麼就一定要寫行為測試了。行為測試可以保證整個功能串起來執行是正常的。

相關文章