單元測試
Meson 具備完整功能的單元測試系統。要使用它,只需建置一個可執行檔,然後在測試中使用它。
e = executable('prog', 'testprog.c')
test('name of test', e)
您可以新增任意數量的測試。它們會以指令 meson test
執行。
Meson 會擷取所有測試的輸出,並將其寫入日誌檔案 meson-logs/testlog.txt
。
測試參數
某些測試需要使用命令列引數或環境變數。這些都很容易定義。
test('command line test', exe, args : ['first', 'second'])
test('envvar test', exe2, env : ['key1=value1', 'key2=value2'])
請注意您需要將多個值指定為陣列。
MALLOC_PERTURB_
預設情況下,環境變數 MALLOC_PERTURB_
會設定為 1 到 255 之間的隨機值。這有助於在使用 glibc 的組態上尋找記憶體洩漏,包括使用非 GCC 編譯器。此功能可以停用,如 test()
中所述。
ASAN_OPTIONS、UBSAN_OPTIONS 和 MSAN_OPTIONS
預設情況下,環境變數 ASAN_OPTIONS
、UBSAN_OPTIONS
和 MSAN_OPTIONS
會設定為在偵測到違規時中止,並提供回溯。此功能可以停用,如 test()
中所述。
覆蓋率
如果您透過給予 Meson 命令列旗標 -Db_coverage=true
來啟用覆蓋率測量,您可以在執行測試後產生覆蓋率報告(執行測試是收集呼叫函式清單的必要條件)。Meson 會自動偵測您已安裝的覆蓋率產生器工具,並產生對應的目標。這些目標是 coverage-xml
和 coverage-text
,兩者都由 Gcovr(3.3 或更高版本)提供,coverage-sonarqube
由 Gcovr(4.2 或更高版本)提供,以及 coverage-html
,這需要 lcov 和 GenHTML 或 Gcovr。為方便起見,也會產生一個高階的 coverage
目標,如果可能,它會產生所有 3 種覆蓋率報告類型。
這些指令的輸出會寫入您建置目錄中的日誌目錄 meson-logs
。
並行性
為了縮短測試時間,Meson 預設會並行執行多個單元測試。常見的情況是有一些測試無法並行執行,因為它們需要獨佔某些資源,例如檔案或 D-Bus 名稱。您必須使用關鍵字引數指定這些測試。
test('unique test', t, is_parallel : false)
然後,Meson 會確保沒有其他單元測試同時執行。非並行測試需要較長的執行時間,因此建議您盡可能將單元測試寫成可並行執行。
預設情況下,Meson 會使用測試電腦上的核心數量作為並行處理的程序數量。您可以使用環境變數 MESON_TESTTHREADS
來覆寫此設定,如下所示。
$ MESON_TESTTHREADS=5 meson test
將 MESON_TESTTHREADS
設定為 0 會啟用預設行為(核心計數),而設定為無效值會導致將工作計數設定為 1。
優先順序
(新增於 0.52.0 版本)
測試可以被分配一個優先順序,決定測試的啟動時間。優先順序較高的測試會先啟動,優先順序較低的測試會稍後啟動。預設優先順序為 0,Meson 不保證具有相同優先順序的測試的順序。
test('started second', t, priority : 0)
test('started third', t, priority : -50)
test('started first', t, priority : 1000)
請注意,測試優先順序僅影響測試的啟動順序,後續測試會受到先前測試完成所需時間的影響。因此,在較短執行時間的較低優先順序測試完成時,較高優先順序的測試仍有可能在執行中。
跳過的測試和嚴重錯誤
有時,測試只能在執行時確定它無法執行。
對於預設的 exitcode
測試協定,在這種情況下,GNU 標準方法是以錯誤碼 77 結束程式。Meson 會偵測到這一點,並將這些測試報告為已跳過,而不是失敗。此行為新增於 0.37.0 版本。
對於基於 TAP 的測試,跳過的測試應列印以 1..0 # SKIP
開頭的單行。
此外,有時測試失敗會導致即使標記為預期失敗也應失敗。在這種情況下,GNU 標準方法是以錯誤碼 99 結束程式。同樣,Meson 會偵測到這一點,並將這些測試報告為 ERROR
,忽略 should_fail
的設定。此行為新增於 0.50.0 版本。
測試工具
Meson 測試工具的目標是以簡單的方式執行各種不同方式的測試。該工具設計為在建置目錄中執行。
最簡單的方法就是執行所有測試。
$ meson test
執行測試的子集
為了清楚起見,請考慮包含以下內容的 meson.build
test('A', ..., suite: 'foo')
test('B', ..., suite: ['foo', 'bar'])
test('C', ..., suite: 'bar')
test('D', ..., suite: 'baz')
依名稱指定測試,例如
$ meson test A D
您可以從特定(子)專案執行測試
$ meson test (sub)project_name:
或從特定專案執行特定測試
$ meson test (sub)project_name:test_name
自 1.2.0 版起,您可以在專案和測試名稱中使用萬用字元。例如,要執行所有以「foo」開頭的測試和所有以「bar」開頭的專案的測試
$ meson test "foo*" "bar*:"
屬於套件 suite
的測試可以如下方式執行
$ meson test --suite (sub)project_name:suite
自 0.46 版起,如果它是頂層專案,則可以省略 (子)專案名稱
。
多個套件指定如下
$ meson test --suite foo --suite bar
注意:如果您選擇同時指定套件和特定測試名稱,則測試名稱必須包含在套件中。但是,這是多餘的 - 指定特定測試名稱或套件會更有用。
其他測試選項
有時您需要多次執行測試,如下所示
$ meson test --repeat=10
Meson 會將 MESON_TEST_ITERATION
環境變數設定為測試的目前迭代(新增於 1.5.0)。
可以透過輔助可執行檔(例如 Valgrind)來呼叫測試,使用 --wrap
引數
$ meson test --wrap=valgrind testname
可以像這樣給予包裝器二進位檔引數
$ meson test --wrap='valgrind --tool=helgrind' testname
Meson 也支援在 GDB 下執行測試。只需執行此操作
$ meson test --gdb testname
Meson 會啟動 gdb
,並完成執行測試的所有設定。只需在 GDB 命令提示字元中鍵入 run
即可啟動程式。
第二個用例是很少出現段錯誤的測試。在這種情況下,您可以呼叫以下指令
$ meson test --gdb --repeat=10000 testname
這會在 GDB 下自動執行測試最多 10,000 次。如果程式崩潰,GDB 會停止,使用者可以偵錯應用程式。請注意,在這種情況下會停用測試逾時,因此當開發人員仍在偵錯時,meson test
不會終止 gdb
。缺點是,如果測試二進位檔凍結,測試執行器將會永遠等待。
有時,GDB 二進位檔不在 PATH 變數中,或者使用者想要使用 GDB 替代程式。因此,可以指定呼叫的 GDB 程式(新增於 0.52.0)
$ meson test --gdb --gdb-path /path/to/gdb testname
$ meson test --print-errorlogs
可以使用 --interactive
選項來互動式執行測試。meson test --interactive
會呼叫測試,其中 stdout、stdin 和 stderr 直接連線到呼叫終端機。如果您的測試是在容器或虛擬機器中執行的整合測試,並且在失敗時會產生偵錯 shell,這會很有用(新增於 1.5.0)
$ meson test --interactive testname
Meson 會報告失敗測試產生的輸出以及其他有用的資訊,作為環境變數。例如,當您在 Travis-CI、Jenkins 等環境上執行測試時,這會很有用。
預設情況下,測試的輸出會限制為最後 100 行。可以使用 --max-lines
選項來設定要顯示的最大行數(新增於 1.5.0)
$ meson test --max-lines=1000 testname
逾時
在測試案例選項中,timeout
選項以秒為單位指定。
若要停用測試案例中的逾時,請新增 timeout: 0
或負值,以允許測試案例在無限的時間內完成。
對於執行測試,您也可以指定命令列引數來覆寫逾時
$ meson test --timeout-multiplier 0
如需更多資訊,請執行 meson test -h
查看 Meson 的命令列說明。
舊版注意事項
如果 meson test
對您不起作用,您可能擁有舊版本的 Meson。在這種情況下,您應該改為呼叫 mesontest
。如果 mesontest
也無法運作,則您擁有 0.37.0 之前的非常舊的版本,應該升級。
測試輸出
Meson 會寫入數個不同的檔案,其中包含執行測試的詳細結果。這些將會寫入 $builddir/meson-logs/ 中
testlog.json
這不是正確的 json 檔案,而是一個檔案,每行包含一個有效的 json 物件。此檔案的設計是,當每個測試執行時,每行都會以串流方式輸出,因此可以在測試機具執行時以串流方式讀取。
testlog.junit.xml
這是所有已執行測試的有效 JUnit XML 描述。它不會以串流方式輸出,而是在所有測試完成執行後才寫入一次。
當測試使用 tap
協定時,每個測試都將記錄為測試套件容器,每個案例都依結果的編號命名。
當測試使用 gtest
協定時,Meson 會將引數插入測試中,以產生其自己的 JUnit XML,Meson 會將其納入此 XML 檔案中。
0.55.0 版中的新增功能
搜尋結果為