單元測試

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_OPTIONSUBSAN_OPTIONSMSAN_OPTIONS 會設定為在偵測到違規時中止,並提供回溯。此功能可以停用,如 test() 中所述。

覆蓋率

如果您透過給予 Meson 命令列旗標 -Db_coverage=true 來啟用覆蓋率測量,您可以在執行測試後產生覆蓋率報告(執行測試是收集呼叫函式清單的必要條件)。Meson 會自動偵測您已安裝的覆蓋率產生器工具,並產生對應的目標。這些目標是 coverage-xmlcoverage-text,兩者都由 Gcovr(3.3 或更高版本)提供,coverage-sonarqubeGcovr(4.2 或更高版本)提供,以及 coverage-html,這需要 lcovGenHTMLGcovr。為方便起見,也會產生一個高階的 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 版中的新增功能

搜尋結果為