檢視原始碼 程式碼涵蓋率分析
一般
雖然 Common Test
最初是為了黑箱測試而建立,但它也能完美地作為白箱測試工具。當要測試的應用程式是以 Erlang 撰寫時尤其如此。接著,測試埠很容易以 Erlang 函式呼叫來實現。
在對 Erlang 應用程式進行白箱測試時,能夠測量測試的程式碼涵蓋率會很有用。Common Test
為此目的提供了對 OTP Cover 工具的簡單存取。Common Test
處理與 Cover 工具的所有必要通訊(啟動、編譯、分析等等)。Common Test
使用者只需要指定程式碼涵蓋率分析的範圍。
使用
若要指定要包含在程式碼涵蓋率測試中的模組,請提供涵蓋率規範檔案。透過這個檔案,您可以指出特定的模組,或指定包含要納入分析的模組的目錄。您也可以指定要從分析中排除的模組。
如果您正在測試分散式 Erlang 應用程式,您想要納入程式碼涵蓋率分析中的程式碼,很可能會在與 Common Test
執行所在的 Erlang 節點不同的節點上執行。如果是這樣,您必須在涵蓋率規範檔案中指定這些其他節點,或將它們動態新增至程式碼涵蓋率節點集合。如需後者的詳細資訊,請參閱模組 ct_cover
。
在涵蓋率規範檔案中,您也可以指定所需的程式碼涵蓋率分析層級:details
或 overview
。在詳細模式中,您會取得涵蓋率總覽頁面,顯示每個模組和總涵蓋率百分比。您也會取得為納入分析的每個模組列印的 HTML 檔案,顯示在測試期間已執行的程式碼確切部分。在總覽模式中,只會列印程式碼涵蓋率總覽頁面。
您可以選擇在測試之間匯出和匯入程式碼涵蓋率資料。如果您在涵蓋率規範檔案中指定匯出檔案的名稱,Common Test
會在測試結束時將收集到的涵蓋率資料匯出至此檔案。您可以類似地指定先前匯出的資料,以匯入並納入測試的分析中(可以指定多個匯入檔案)。如此一來,就可以分析總程式碼涵蓋率,而無需一次執行所有測試。
若要啟用程式碼涵蓋率支援,請在啟動 Common Test
時指定涵蓋率規範檔案的名稱。方法是搭配 ct_run
使用旗標 -cover
,例如
$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec
您也可以在呼叫 ct:run_test/1
時傳遞涵蓋率規範檔案名稱,方法是在引數 Opts
中加入 {cover,CoverSpec}
元組。
您也可以在測試規範中啟用程式碼涵蓋率(請參閱<執行測試和分析結果>一節中的<測試規範>一節)。
測試完成時停止 Cover 工具
預設情況下,Cover 工具會在測試完成時自動停止。這會導致原始(非 Cover 編譯)模組重新載入測試節點。如果此時有程序仍在執行任何已 Cover 編譯的模組的舊程式碼,表示它在 Cover 編譯後未執行任何完全合格的函式呼叫,則會終止該程序。若要避免這種情況,請將選項 cover_stop
的值設定為 false
。這表示模組會保持 Cover 編譯。因此,僅建議在測試完成後終止受測試的 Erlang 節點,或者可以手動停止 Cover 時才使用此設定。
可以使用搭配 ct_run
的旗標 -cover_stop
、將 {cover_stop,true|false}
新增至 ct:run_test/1
的引數 Opts
,或是在測試規範中新增 cover_stop
詞彙來設定選項(請參閱<執行測試和分析結果>一節中的<測試規範>一節)。
涵蓋率規範檔案
一般設定
以下是在涵蓋率規範檔案中允許的一般設定詞彙
%% List of Nodes on which cover will be active during test.
%% Nodes = [atom()]
{nodes, Nodes}.
%% Files with previously exported cover data to include in analysis.
%% CoverDataFiles = [string()]
{import, CoverDataFiles}.
%% Cover data file to export from this session.
%% CoverDataFile = string()
{export, CoverDataFile}.
%% Cover analysis level.
%% Level = details | overview
{level, Level}.
%% Directories to include in cover.
%% Dirs = [string()]
{incl_dirs, Dirs}.
%% Directories, including subdirectories, to include.
{incl_dirs_r, Dirs}.
%% Specific modules to include in cover.
%% Mods = [atom()]
{incl_mods, Mods}.
%% Directories to exclude in cover.
{excl_dirs, Dirs}.
%% Directories, including subdirectories, to exclude.
{excl_dirs_r, Dirs}.
%% Specific modules to exclude in cover.
{excl_mods, Mods}.
%% Cross cover compilation
%% Tag = atom(), an identifier for a test run
%% Mod = [atom()], modules to compile for accumulated analysis
{cross,[{Tag,Mods}]}.
詞彙 incl_dirs_r
和 excl_dirs_r
會指示 Common Test
遞迴搜尋指定的目錄,並包含或排除搜尋期間找到的任何模組。詞彙 incl_dirs
和 excl_dirs
會導致非遞迴模組搜尋(也就是說,只會包含或排除在指定目錄中找到的模組)。
注意
包含要納入程式碼涵蓋率測試的 Erlang 模組的目錄,必須存在於程式碼伺服器路徑中。否則,Cover 工具無法重新編譯模組。僅在
Common Test
的涵蓋率規範檔案中指定這些目錄是不夠的。
OTP 應用程式設定
在測試 OTP 應用程式本身時使用涵蓋率規範時,會有一個特殊的 incl_app 指示詞,該指示詞會包含應用程式的模組以進行 Cover 編譯。
{incl_app, AppName, Cover :: overview | details}.
注意
如果您也希望將其他一般 Cover 設定與此選項一起使用,您應該在選項及其值之間插入 AppName,以建立三元組。
跨涵蓋率分析
跨涵蓋率機制允許跨多個測試分析模組的涵蓋率。如果多個不同的測試使用某些程式碼(例如,程式庫模組),並且需要累積的涵蓋率結果,這會很有用。
也可以透過在涵蓋率規範中使用參數 export
並離線分析結果,以更自訂的方式達成此目的。但是,跨涵蓋率機制是一個內建解決方案,也提供記錄。
此機制最容易透過範例說明
假設有兩個系統 s1
和 s2
,它們在個別的測試執行中進行測試。系統 s1
包含程式庫模組 m1
,該模組由測試執行 s1
進行測試,並包含在 s1
的涵蓋率規範中,如下所示
s1.cover:
{incl_mods,[m1]}.
在分析程式碼涵蓋率時,可以在 s1
測試結果中的涵蓋率記錄中看到 m1
的結果。
現在,假設 m1
是一個程式庫模組,它也經常被系統 s2
使用。測試執行 s2
並未特別測試 m1
,但查看 s2
測試涵蓋 m1
的哪些部分仍然很有趣。若要執行此操作,m1
也可以包含在 s2
的涵蓋率規範中,如下所示
s2.cover:
{incl_mods,[m1]}.
這會在測試執行 s2
的涵蓋率記錄中提供 m1
的項目。問題是,這僅反映 s2
測試的涵蓋率,而不是 s1
和 s2
的累積結果。這就是跨涵蓋率機制派上用場的地方。
如果 s2
的涵蓋率規範改為如下所示
s2.cover:
{cross,[{s1,[m1]}]}.
那麼 m1
會在測試執行 s2
中進行 Cover 編譯,但不會顯示在涵蓋率記錄中。相反地,如果在完成 s1
和 s2
測試執行後呼叫 ct_cover:cross_cover_analyse/2
,則可以在測試執行 s1
的跨涵蓋率記錄中取得 m1
的累積結果。
對分析函式的呼叫必須如下
ct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).
在這裡,S1LogDir
和 S2LogDir
分別是每個測試的 <TestName>.logs
的目錄名稱。
請注意標籤 s1
和 s2
,它們在涵蓋率規範檔案和呼叫 ct_cover:cross_cover_analyse/2
中使用。這些標籤的目的僅是將涵蓋率規範中指定的模組對應到呼叫分析函式時指定的記錄目錄。標籤名稱除此以外沒有任何意義。
記錄
若要檢視程式碼涵蓋率測試的結果,請按一下測試執行最上層索引頁面中標示為「涵蓋率記錄」的按鈕。
在 Erlang/OTP 17.1 之前,如果您的測試執行包含多個測試,則會為測試執行中的每個測試啟動和停止 Cover。可透過測試套件結果頁面上的「涵蓋率記錄」連結取得個別的記錄。這些連結仍然可用,但現在它們全部指向與最上層索引頁面上的按鈕相同的頁面。記錄包含完整測試執行的累積結果。如需此變更的詳細資訊,請參閱版本資訊。
該按鈕會將您帶到程式碼涵蓋率總覽頁面。如果您已成功執行詳細的涵蓋率分析,則可以在這裡找到每個模組涵蓋率頁面的連結。
如果執行了跨涵蓋率分析,且目前測試有累積的涵蓋率結果,則連結「所有測試收集的涵蓋率資料」會將您帶到這些結果。