測試最佳做法

為 Actions on Google 平台開發動作時,通常需要實作 Dialogflow 以其自然語言理解 (NLU) 及 Dialogflow 執行要求來處理動作的邏輯。在程式碼集中進行測試,有助於確保動作在實際工作環境中正常運作。

為您的動作實作單元、整合或端對端測試時,請將 Dialogflow 代理程式和執行要求視為個別的元件。

一張流程圖從使用者查詢繼續前往 Actions on Google、Dialogflow 和執行要求 Webhook,最後傳回給使用者。

圖 1 說明測試系統的流程圖

測試 Dialogflow 代理程式

Dialogflow 代理程式和執行要求會做為個別元件進行測試。下列子章節說明如何針對動作設計概念及測試 Dialogflow 代理程式。

Dialogflow 做為查詢插入與意圖傳出系統

Dialogflow 代理程式負責接收使用者的查詢、將其與意圖進行比對,以及從查詢中擷取任何預先定義的實體。代理程式會傳送包含相符意圖、相關參數和 Actions on Google 中繼資料的訊息,與執行要求互動。

開發人員可以控管 Dialogflow 代理程式的設定,例如意圖和實體的結構。Actions on Google 中繼資料來自 Actions on Google,可以假設其中包含正確的測試資料。

測試時,請著重於如何讓代理程式正確擷取意圖參數,以及比對查詢與意圖。這個方法提供可量化的指標來評估代理程式的效能。如要計算這項指標,您可以準備並使用個別測試案例或驗證集。

Dialogflow 代理程式能以文字查詢的形式表示,再以意圖和擷取的意圖參數當做輸出內容。

圖 2. 將 Dialogflow 呈現為查詢插入與意圖傳出系統

單元測試

對於 Dialogflow 代理程式,您可以撰寫測試,其中每個案例都會預期文字查詢做為輸入內容,並產生意圖中繼資料做為輸出內容。這項中繼資料至少應含有相符意圖的名稱和相符參數清單。

Dialogflow API 的 detectIntent 端點會將文字查詢視為輸入內容,並產生結構化輸出,其中包含已解析意圖的名稱和擷取的參數。這項輸出內容有助於評估代理程式的意圖比對效能。如需其他實用欄位的完整參考資料,請參閱 QueryResult 參考資料

範例測試如下所示:

it('choose_fact', async function() {
  // The `dialogflow` variable is an abstraction around the API that creates
  // and sends payloads to Dialogflow.
  const resJson = await dialogflow.detectIntent(
    'Tell me about the history of Google');
  expect(resJson.queryResult).to.include.deep.keys('parameters');
  // Check that Dialogflow extracted required entities from the query.
  expect(resJson.queryResult.parameters).to.deep.equal({
    'category': 'history',
    // Put any other parameters you wish were extracted
  });
  expect(resJson.queryResult.intent.displayName).to.equal('choose_fact');
});

這個程式碼片段使用 MochaChai。請參閱以 Node.js 編寫的 Facts About Google 完整運作範例。

由於 Dialogflow API 接受 sessionId 做為引數,因此測試檔案可以同時執行。因此,使用單一 Dialogflow API 用戶端時,您可以為每個對話設定個別的沙箱。

由於您是透過 Dialogflow API 傳送要求,因此如果免費呼叫配額達到上限,系統可能會向您收取費用。詳情請參閱配額與限制

整合測試

Dialogflow API 的 detectIntent 端點也會觸發第三方執行要求。因此,您可以編寫測試案例,涵蓋 Dialogflow 代理程式和 Dialogflow 執行要求之間的整合。

為 Dialogflow 編寫整合和單元測試的主要差異在於,在整合測試中,您可以斷言來自 Webhook、Dialogflow 意圖和實體擷取的回應。

前往關於 Google 存放區的知識頁面,查看以 Node.js 編寫的整合測試完整運作範例。

測試 Dialogflow 執行要求 Webhook

系統會將 Dialogflow 代理程式和 Dialogflow 執行要求視為個別元件進行測試。以下各節說明如何設計動作的概念及測試執行要求。

以 JSON-in 和 JSON-out 系統的形式執行要求

Dialogflow 執行要求程式碼都會預期要求並產生 JSON 格式的回應。因此,您可以把執行要求程式碼想像為 JSON-in 和 JSON-out 系統,以測試執行要求。這項要求含有來自 Dialogflow 和 Actions on Google 的中繼資料,因此具備在執行要求中觸發特定意圖處理常式所需的一切資源。

如要測試意圖處理常式的觸發動作,請將 JSON 要求 (輸入內容) 傳送至動作。這項要求會傳遞至您的執行要求,您可在網際網路上存取。執行要求便會產生 JSON 回應 (輸出),方便您評估及進行驗證。

執行要求能以 JSON 要求輸入內容和 Webhook JSON 回應輸出表示。

圖 3. 將執行要求顯示為 JSON-in 和 JSON-out 系統

單元測試

你可以將執行要求 Webhook 程式碼視為接受 JSON 輸入內容並產生 JSON 輸出內容的系統。接著,系統會簡化動作的測試程序,向執行要求提供要求,並檢查產生的輸出 JSON。

這樣就能自由在本機託管執行要求,並在本機傳送 HTTP 要求以供測試。如果您使用的是 Actions on Google Node.js 用戶端程式庫,也可以直接將 JSON 要求傳送至用戶端程式庫中介軟體層。

如果您使用 JSON 輸入內容測試 Webhook 程式碼,並接收預期的 JSON 輸出內容,則可以合理確信控管的部分運作正常。您可以假設 Dialogflow 和 Actions on Google 能正常運作,因為它們產生的 JSON 酬載正確無誤。這種隔離模式提供簡化的程式設計模型編寫測試模型。

以下大致介紹測試程序:

  1. 使用動作主控台中的模擬工具取得用途中每個步驟的 JSON 要求。請將這些內容儲存為 JSON 檔案。或者,您也可以使用 Webhook 參考說明文件中的資訊,自行建構這些要求。
  2. 編寫測試,以使用這些酬載叫用 Webhook。
  3. 請確保每項測試的回應 JSON 包含預期項目。

此外,這個模型可讓您在持續整合設定中測試 Dialogflow 執行要求,因為執行要求端點可以在本機執行,而且 Dialogflow API 也有內建工作階段的概念。

測試範例如下所示:

it('yes-history', function() {
  expect(jsonRes.payload).to.have.deep.keys('google');
  expect(jsonRes.payload.google.expectUserResponse).to.be.true;
  expect(jsonRes.payload.google.richResponse.items).to.have.lengthOf(3);
  expect(jsonRes.payload.google.richResponse.suggestions).to.have
    .deep.members([
      {'title': 'Sure'}, {'title': 'No thanks'},
    ]);
});

上方程式碼片段使用的是 MochaChai。請參閱「關於 Google 的事實」存放區,查看以 Node.js 編寫的完整有效範例。

設計可測試單位的執行要求

Webhook 程式碼通常包含應用程式為了滿足其需求而仰賴的自訂商業邏輯。此外,Webhook 程式碼也可以包含意圖處理常式。

如要提高執行要求程式碼的單元測試精細程度,建議您整理程式碼,讓商業邏輯與意圖處理處理常式分離。也就是說,意圖處理常式和商業邏輯分別出現在不同的模組中,因此每個片段都能獨立測試。

如需範例,請參閱 GitHub 上的 Shiritori 動作範例。在該範例中,functions/index.jsfunctions/shiritori/*.js 分別包含意圖處理常式和商業邏輯,讓測試套件更臻完善。

整合測試

如要編寫涵蓋 Dialogflow 和執行要求 Webhook 程式碼整合的測試案例,請參閱上方的 Dialogflow 整合測試一節

載入測試

將動作部署至實際工作環境前,我們也建議您對 Webhook 執行要求進行負載測試,藉此找出導致執行要求服務降級或中斷的效能問題。

以下列舉一些在負載測試中可能發現的效能問題:

  • 有限的運算與記憶體
  • 供應商提出的配額限制
  • 資料讀取和寫入速度緩慢
  • 程式碼中的並行問題

負載測試的情境取決於動作的預期或歷來使用模式,但要測試的常見情境在負載 (遽增) 和持續負載 (浸泡) 均會突然增加。

找出呼叫 Webhook 並執行大量資源作業的情況。一般會耗用大量資源的作業包括查詢資料庫、呼叫其他 API、執行運算及耗用大量記憶體的作業,例如轉譯音效檔案。

在這些情況下,您可以從 Webhook 記錄或 Stackdriver 記錄,擷取 Actions on Google 伺服器傳送至 Webhook 的要求。您也可以透過動作主控台模擬器擷取要求。

取得要求後,您就能使用工作負載測試工具,瞭解 Webhook 在不同負載測試情境下的回應方式。以下子章節提供使用 ApacheBench 進行尖峰測試和肥皂測試的範例。

高點測試

高點測試需要您向 Webhook 傳送固定數量的要求,並在一段時間內突然增加負載。舉例來說,您可以設定測試每秒傳送 10 次查詢 (QPS) 的測試,但每秒查詢次數達到 60 次以上。

您可以執行以下 ApacheBench 指令,將 60 個並行要求傳送至 Webhook:

ab -n 60 -c 60 -p ActionRequest.json -T 'application/json' https://example.com/webhookFunctionName

假設 ActionRequest.json 檔案包含傳送至您 Webhook 的擷取要求酬載。

浸泡測試

量化測試會要求您將固定數量的要求傳送至 Webhook,並觀察回應。舉例來說,您可以設定測試,在幾分鐘內傳送每秒載入 10 至 20 次的穩定負載,看看回應時間是否增加。

您可以執行下列 ApacheBench 指令來傳送 1200 個要求,每秒處理 10 個並行要求:

ab -t 120 -n 1200 -p ActionRequest.json -T 'application/json' https://example.com/webhookFunctionName

假設 ActionRequest.json 檔案包含傳送至您 Webhook 的擷取要求酬載。

分析工作負載測試結果

執行工作負載測試後,請分析 Webhook 回應時間的結果。 Webhook 實作中的問題指標通常為趨勢,例如每次測試執行後都會增加的中位數回應時間,或是動作無法接受最糟的回應。

端對端測試

將動作送交核准前,請使用動作主控台模擬工具進行端對端測試。如需端對端測試的步驟,請參閱「動作模擬工具」說明文件。執行這些測試可協助您從 Actions on Google 基礎架構元件移除潛在的不確定性。