測試 API
Deno 語言伺服器支援一組自訂 API 以啟用測試。這些 API 旨在提供資訊,以啟用 vscode 的測試 API,但其他語言伺服器用戶端可以使用這些 API 來提供類似的介面。
功能
用戶端和伺服器都應該支援實驗性的 testingApi
功能
interface ClientCapabilities {
experimental?: {
testingApi: boolean;
};
}
interface ServerCapabilities {
experimental?: {
testingApi: boolean;
};
}
當支援測試 API 的 Deno 版本遇到支援此功能的客戶端時,它會初始化處理測試偵測的程式碼,並開始提供啟用它的通知。
還要注意的是,當測試 API 功能啟用時,測試程式碼鏡片將不再傳送給客戶端。
設定
有特定設定會變更語言伺服器的行為
deno.testing.args
- 執行測試時將作為引數提供的字串陣列。這與deno test
子指令的運作方式相同。deno.testing.enable
- 啟用或停用測試伺服器的二進位旗標
通知
伺服器會在特定條件下傳送通知給客戶端。
deno/testModule
當伺服器發現包含測試的模組時,它會透過傳送 deno/testModule
通知和 TestModuleParams
的酬載來通知客戶端。
Deno 以這種方式建構
- 一個模組可以包含 n 個測試。
- 一個測試可以包含 n 個步驟。
- 一個步驟可以包含 n 個步驟。
當 Deno 對測試模組進行靜態分析時,它會嘗試識別任何測試和測試步驟。由於在 Deno 中宣告測試的動態方式,它們無法總是靜態識別,只能在執行模組時識別。此通知旨在處理更新客戶端時的這兩種情況。當測試被靜態發現時,通知 kind
將為 "replace"
,當測試或步驟在執行時被發現時,通知 kind
將為 "insert"
。
當測試文件在編輯器中編輯,並且從客戶端收到 textDocument/didChange
通知時,這些變更的靜態分析將在伺服器端執行,如果測試已變更,客戶端將收到通知。
當客戶端收到 "replace"
通知時,它可以安全地「取代」測試模組表示,而當收到 "insert"
時,它應遞迴嘗試新增至現有表示。
對於測試模組,textDocument.uri
應作為任何表示的唯一 ID(因為它是指向唯一模組的字串 URL)。TestData
項目包含唯一的 id
字串。此 id
字串是伺服器追蹤測試的識別資訊的 SHA-256 雜湊。
interface TestData {
/** The unique ID for this test/step. */
id: string;
/** The display label for the test/step. */
label: string;
/** Any test steps that are associated with this test/step */
steps?: TestData[];
/** The range of the owning text document that applies to the test. */
range?: Range;
}
interface TestModuleParams {
/** The text document identifier that the tests are related to. */
textDocument: TextDocumentIdentifier;
/** A indication if tests described are _newly_ discovered and should be
* _inserted_ or if the tests associated are a replacement for any existing
* tests. */
kind: "insert" | "replace";
/** The text label for the test module. */
label: string;
/** An array of tests that are owned by this test module. */
tests: TestData[];
}
deno/testModuleDelete
當伺服器正在觀察的測試模組被刪除時,伺服器將發出 deno/testModuleDelete
通知。收到通知時,客戶端應移除測試模組的表示及其所有子測試和測試步驟。
interface TestModuleDeleteParams {
/** The text document identifier that has been removed. */
textDocument: TextDocumentIdentifier;
}
deno/testRunProgress
當從客戶端要求 deno/testRun
時,伺服器將透過 deno/testRunProgress
通知支援該測試執行的進度。
客戶端應處理這些訊息並更新任何 UI 表示。
狀態變更表示在 TestRunProgressParams
的 .message.kind
屬性中。狀態為
"enqueued"
- 測試或測試步驟已排隊進行測試。"skipped"
- 測試或測試步驟已略過。當 Deno 測試將ignore
選項設定為true
時,會發生這種情況。"started"
- 測試或測試步驟已開始。"passed"
- 測試或測試步驟已通過。"failed"
- 測試或測試步驟已失敗。這是用來表示測試架構的錯誤,而不是測試本身,但 Deno 目前不支援此區別。"errored"
- 測試或測試步驟已發生錯誤。有關錯誤的更多資訊將會在.message.messages
屬性中。"end"
- 測試執行已結束。
interface TestIdentifier {
/** The test module the message is related to. */
textDocument: TextDocumentIdentifier;
/** The optional ID of the test. If not present, then the message applies to
* all tests in the test module. */
id?: string;
/** The optional ID of the step. If not present, then the message only applies
* to the test. */
stepId?: string;
}
interface TestMessage {
/** The content of the message. */
message: MarkupContent;
/** An optional string which represents the expected output. */
expectedOutput?: string;
/** An optional string which represents the actual output. */
actualOutput?: string;
/** An optional location related to the message. */
location?: Location;
}
interface TestEnqueuedStartedSkipped {
/** The state change that has occurred to a specific test or test step.
*
* - `"enqueued"` - the test is now enqueued to be tested
* - `"started"` - the test has started
* - `"skipped"` - the test was skipped
*/
type: "enqueued" | "started" | "skipped";
/** The test or test step relating to the state change. */
test: TestIdentifier;
}
interface TestFailedErrored {
/** The state change that has occurred to a specific test or test step.
*
* - `"failed"` - The test failed to run properly, versus the test erroring.
* currently the Deno language server does not support this.
* - `"errored"` - The test errored.
*/
type: "failed" | "errored";
/** The test or test step relating to the state change. */
test: TestIdentifier;
/** Messages related to the state change. */
messages: TestMessage[];
/** An optional duration, in milliseconds from the start to the current
* state. */
duration?: number;
}
interface TestPassed {
/** The state change that has occurred to a specific test or test step. */
type: "passed";
/** The test or test step relating to the state change. */
test: TestIdentifier;
/** An optional duration, in milliseconds from the start to the current
* state. */
duration?: number;
}
interface TestOutput {
/** The test or test step has output information / logged information. */
type: "output";
/** The value of the output. */
value: string;
/** The associated test or test step if there was one. */
test?: TestIdentifier;
/** An optional location associated with the output. */
location?: Location;
}
interface TestEnd {
/** The test run has ended. */
type: "end";
}
type TestRunProgressMessage =
| TestEnqueuedStartedSkipped
| TestFailedErrored
| TestPassed
| TestOutput
| TestEnd;
interface TestRunProgressParams {
/** The test run ID that the progress message applies to. */
id: number;
/** The message*/
message: TestRunProgressMessage;
}
要求
伺服器處理兩個不同的要求
deno/testRun
若要要求語言伺服器執行一組測試,客戶端會傳送 deno/testRun
要求,其中包含將在未來回應中傳送給客戶端的測試執行 ID、測試執行的類型,以及要包含或排除的任何測試模組或測試。
目前 Deno 僅支援 "run"
類型的測試執行。"debug"
和 "coverage"
都計畫在未來支援。
當沒有包含的測試模組或測試時,表示應執行所有已發現的測試模組和測試。當包含測試模組,但沒有任何測試 ID 時,表示應包含該測試模組中的所有測試。一旦識別出所有測試,任何已排除的測試都會被移除,而已解決的測試組會在回應中以 "enqueued"
傳回。
由於測試步驟的宣告和執行方式具有動態特性,因此無法透過此 API 包含或排除測試步驟。
interface TestRunRequestParams {
/** The id of the test run to be used for future messages. */
id: number;
/** The run kind. Currently Deno only supports `"run"` */
kind: "run" | "coverage" | "debug";
/** Test modules or tests to exclude from the test run. */
exclude?: TestIdentifier[];
/** Test modules or tests to include in the test run. */
include?: TestIdentifier[];
}
interface EnqueuedTestModule {
/** The test module the enqueued test IDs relate to */
textDocument: TextDocumentIdentifier;
/** The test IDs which are now enqueued for testing */
ids: string[];
}
interface TestRunResponseParams {
/** Test modules and test IDs that are now enqueued for testing. */
enqueued: EnqueuedTestModule[];
}
deno/testRunCancel
如果客戶端想要取消目前執行的測試,它會傳送 deno/testRunCancel
要求,其中包含要取消的測試 ID。回傳的回應會是布林值 true
(如果測試已取消)或 false
(如果無法取消)。在取消測試時,仍會傳送適當的測試進度通知。
interface TestRunCancelParams {
/** The test id to be cancelled. */
id: number;
}