測試項目框架
測試項目框架是一組套件和使用者介面功能,能輕易撰寫和執行 Julia 套件的測試。
這個框架的主要好處是,測試程式碼可以建構為測試項目,然後輕鬆獨立執行。
Julia VS Code 擴充功能廣泛支援測試項目框架,但測試項目框架本身可以完全獨立於 VS Code 使用。使用者可以在不使用 VS Code 的情況下撰寫測試項目,並使用命令列介面 (或僅使用標準的 Pkg.test
功能) 執行它們。
撰寫測試項目
測試項目框架的核心功能是可以將測試建構為 @testitem
區塊,然後個別執行這些區塊,而不用一次執行所有測試。典型的 @testitem
可能如下所示
@testitem "First tests" begin
x = foo("bar")
@test length(x)==3
@test x == "bar"
end
@testitem
有一個名稱 (例如「第一個測試」),以及 begin ... end
區塊中的一些程式碼。@testitem
內的程式碼必須能單獨執行,例如不能依賴 @testitem
外部的程式碼,除非在 @testitem
內明確匯入或包含該程式碼。這種情況只有一個例外:@testitem
內的程式碼會在暫時模組中執行,其中已執行 using Test
和 using MYPACKAGENAME
,因此可以從 Test
模組或您開發的套件匯出的任何內容都能直接使用。在以上範例中,這會套用至 foo
函數 (假設定義於受測套件中) 和 @test
巨集。
@testitem
可以在套件中的任何位置出現。它們不需要位於 test
資料夾中,也不需要位於 test/runtests.jl
包含的檔案中。事實上,@testitem
甚至可以位於您的常規套件程式碼中,例如位在它們所測試程式碼旁邊。在這種情況下,您只需建立對 TestItems.jl 套件的相依關係,以便存取 @testitem
巨集。如果您有一個套件 MyPackage
,那麼檔案 src/MyPackage.jl
可能如下所示
module MyPackage
using TestItems
export foo
foo(x) = x
@testitem "First tests" begin
x = foo("bar")
@test length(x)==3
@test x == "bar"
end
end
如果您不喜歡這種內嵌 @testitem
的樣式,您也可以在測試資料夾的 Julia 檔案中加入 @testitem
塊。
在 VS Code 中執行測試項目
當您在 VS Code 中開啟一個 Julia 套件,並且已安裝 Julia 擴充功能,它將持續 (每次按鍵後) 尋找 Julia 檔案中所有 @testitem
。如果找到,它們將出現在 UI 中的不同位置。
您可以在 VS Code 中的「測試」活動欄位找到所有偵測到的 @testitem
。
然後,測試活動區域會提供您選項,可執行個別 @testitem
、查看結果等。
VS Code 也會在文字編輯器本身中將一個小的執行按鈕置於每個偵測到的 @testitem
旁邊。
除了所有這些允許您執行測試的 UI 元素外,還有一個 UI 可顯示測試結果。舉例來說,當您執行測試,且某些測試失敗時,擴充功能會收集所有這些測試失敗,然後以有條理的方式將它們顯示在程式碼中特定測試失敗處。
特別是在您使用大的測試檔案執行大量測試時,這將使您更容易找到失敗的特定測試,無需再在 REPL 中搜尋檔案和行資訊!
從命令列執行測試
您可以使用 TestItemRunner.jl 套件來執行 @testitem
,作為傳統 Pkg.test
工作流程的一部份。
要為使用 @testitem
的套件啟用與 Pkg.test
的整合,您只需要做兩件事
- 將 TestItemRunner.jl 新增至套件的測試相依性
- 將下列程式碼加入套件的
test/runtests.jl
檔案
using TestItemRunner
@run_package_tests
標記
您現在可以將標記新增至 @testitem
。標記可以在 VS Code UI 和 TestItemRunner.jl 中使用,以過濾您想要執行的測試項目。
新增標記的語法如下
@testitem "My testitem" tags=[:skipci, :important] begin
x = foo("bar")
@test length(x)==3
@test x == "bar"
end
然後,您可以使用這些相同的標籤過濾 VS Code UI 中的測試清單。
此外,您可以在 test/runtests.jl
中使用標籤過濾將通過傳統 Pkg.test
進入點執行的測試清單。
using TestItemRunner
@run_package_tests filter=ti->!(:skipci in ti.tags)
篩選 部分下方有更完整的描述,說明 @run_package_tests
巨集的新篩選關鍵字。
VS Code 中的平行測試執行
VS Code 擴充功能有一個設定控制您想要用來進行平行測試執行的 Julia 程序數量
預設值為 1
,因此您必須更改此值才能使用平行測試執行功能。0
的值將使用與處理器一樣多的測試程序。
一旦您設定超過一個測試程序,個別 @testitem
將會平行執行。
這裡有一個權衡:更多的測試程序表示需要更多的記憶體,而且潛在也會產生額外的開銷,讓所有程序啟動並準備好實際執行 @testitem
。
管理測試程序
在 VS Code 中透過這個新的測試使用者界面啟動的測試流程並不會自動終止,也就是說它們會繼續執行並佔用記憶體及其他資源。這當然有不少好處,其中一項就是,一旦測試流程啟動並執行,@testitem
就會執行得非常快,不過在某些情況下,您可能還是希望直接終止所有目前執行的測試流程。
要達成這個目的,所有測試流程都會顯示在 Julia 工作空間中,並會顯示其他可能正在執行的 REPL 或筆記本流程。您可以透過按一下 停止測試流程
按鈕,然後透過這個使用者界面終止 Julia 測試流程。在這個螢幕截圖中有四個測試流程正在執行
過濾 TestItemRunner.jl 中的支援
您可以將一般過濾函式傳遞給 @run_package_tests
巨集,以選擇您想要執行的 @testitem
。上方的區段使用標籤來選擇要執行的測試,但您也可以根據 @testitem
定義所在的文件檔名或 @testitem
的名稱進行過濾。
執行的方式是,您可以將過濾函式傳遞給 @run_package_tests
巨集。這個過濾函式會在您的專案中偵測到的每個 @testitem
中呼叫一次,而且如果這個測試項目應該執行,則該函式必須傳回 true
;如果不應該執行,則傳回 false
。@run_package_tests
會將包含特定測試項目資訊元資料的名稱組傳遞給您的過濾函式,亦即 filename
欄位(定義 @testitem
的文件檔位的完整路徑)、name
(您所定義的 @testitem
的名稱)及 tags
(Symbol
的向量)。有了這些資訊,您可以撰寫任意複雜的過濾條件。例如,我在這裡過濾任何具有 :skipci
標籤的 @testitem
,而且我只執行在一個特定文件檔中定義的測試
@run_package_tests filter=ti->( !(:skipci in ti.tags) && endswith(ti.filename, "test_foo.jl") )
預設匯入選項
當您撰寫 @testitem
時,預設會透過隱藏的 using 敘述匯入正測試的套件及 Test
套件。在某些情況下這可能不太理想,因此可以透過 default_imports
選項來控制這種行為,該選項接受 Bool
值。如要停用這些預設匯入,您會撰寫
@testitem "Another test for foo" default_imports=false begin
using MyPackage, Test
x = foo("bar")
@test x != "bar"
end
請注意,現在我們需要手動將 using MyPackage, Test
這個行加入我們的 @testitem
,這樣我們才能存取 foo
函式及 @test
巨集。
在各 @testitem
中共用程式碼
預設情況下,@testitem
彼此之間不共用任何程式碼,而且彼此之間也沒有相依性。這些屬性讓 @testitem
得以單獨執行,但有時您會希望在多個 @testitem
之間共用共用程式碼。測試項目架構提供了兩個巨集來達成這個目的:@testsnippet
及 @testmodule
。這兩個巨集都可以出現在套件中的任何 .jl
文件檔中。
測試片段
@testsnippet
是程式碼區塊,個別 @testitem
的程式碼在執行自己的程式碼之前可以執行這個區塊。如果 @testitem
使用特定 @testsnippet
,則系統在每次執行 @testitem
時都會執行該片段。
@testsnippet
的定義可能會如下所示
@testsnippet MySnippet begin
foo = "Hello world"
end
@testitem
可以透過使用 setup
關鍵字來利用這個片段,如下所示
@testitem "My test item" setup=[MySnippet] begin
@test foo == "Hello world"
end
測試模組
@testmodule
定義一個可以從 @testitem
存取的 Julia 模組。此模組只會在每個 Julia 測試程式中執行一次。如果例如有兩個 @testitem
依賴於一個 @testmodule
,則只會評估一次,然後整個模組就會提供給兩個 @testitem
使用。
@testmodule
的定義可能如下所示
@testmodule MyModule begin
foo = "Hello world"
end
@testitem
可以再次使用 setup
關鍵字來使用此模組。與 @testsnippet
不同的是,@testmodule
的內容在正規 Julia module
內部執行,因此要存取其中的內容,必須將模組名稱作為前綴附加到測試模組中定義的任何名稱。使用剛才定義的 @testmodule
的 @testitem
可能如下所示
@testitem "My test item" setup=[MyModule] begin
@test MyModule.foo == "Hello world"
end
請注意我們如何使用 MyModule.foo
表達式來存取 foo
。
偵錯 @testitem
@testitem
可以透過 Debug Test
指令啟動,在偵錯工具中執行。此指令可以在 VS Code UI 的不同位置存取。在測試主測試檢視中,可在此找到
您也可以在文字編輯器中右鍵按一下執行測試圖示來選擇偵錯選項
當測試項目於偵錯工具中執行時,您可以在受測程式碼或 @testitem
本身中設定中斷點,然後使用 Julia VS Code 偵錯工具的所有常規功能。
程式碼涵蓋率
在 Julia 1.11 及更高版本中,您可以在程式碼涵蓋率模式中執行測試項目,並直接在 VS Code 中顯示程式碼涵蓋率結果。
要在程式碼涵蓋率模式中執行測試項目,請使用 Run Tests with Coverage
指令啟動它們。此指令同時在主測試檢視中可用
以及在文字編輯器的內容功能表中
然後會在 VS Code UI 中以不同的方式顯示涵蓋率結果。例如,摘要檢視會顯示每個檔案的涵蓋率
您可以在文字編輯器中看到詳細的行涵蓋率資訊
涵蓋率結果也會直接顯示在 VS Code UI 的常規瀏覽器部分。