Best Practices für Tests

Zum Entwickeln einer Aktion für Actions on Google-Plattform müssen Sie häufig Dialogflow für Natural Language Understanding (NLU) und die Dialogflow-Auftragsausführung implementieren, die die Logik für Ihre Aktion übernimmt. Tests in Ihrer Codebasis tragen dazu bei, dass Ihre Aktion in der Produktion wie erwartet funktioniert.

Beim Implementieren von Einheiten-, Integrations- oder End-to-End-Tests für Ihre Aktion sollten Sie den Dialogflow-Agent und die Auftragsausführung als separate Komponenten betrachten.

Ein Flussdiagramm führt von einer Nutzerabfrage zu Actions on Google, Dialogflow und einem Auftragsausführungs-Webhook und kehrt schließlich zum Nutzer zurück.

Abbildung 1: Flussdiagramm zu Systemen, die für Tests in Betracht kommen

Dialogflow-Agent testen

Der Dialogflow-Agent und die Auftragsausführung werden als separate Komponenten getestet. In den folgenden Unterabschnitten wird beschrieben, wie Sie den Dialogflow-Agent für Ihre Aktion konzipieren und testen können.

Dialogflow als Query-In- und Intent-Out-System

Der Dialogflow-Agent ist dafür verantwortlich, die Abfrage eines Nutzers zu übernehmen, sie einem Intent zuzuordnen und vordefinierte Entitäten aus der Abfrage zu extrahieren. Der Agent interagiert mit der Auftragsausführung, indem er eine Nachricht übergibt, die den übereinstimmenden Intent, seine Parameter und Actions on Google-Metadaten enthält.

Als Entwickler steuern Sie die Konfiguration des Dialogflow-Agents, z. B. die Struktur von Intents und Entitäten. Die Actions on Google-Metadaten stammen von Actions on Google und können davon ausgehen, dass sie die richtigen Daten zum Testen enthalten.

Konzentrieren Sie sich beim Testen darauf, dass der Agent in der Lage ist, Intent-Parameter korrekt zu extrahieren und Abfragen mit Intents abzugleichen. Dieser Ansatz bietet einen quantifizierbaren Messwert für die Bewertung der Leistung des Agents. Sie können diesen Messwert berechnen, indem Sie einzelne Testläufe oder ein Validierungs-Dataset vorbereiten und verwenden.

Ein Dialogflow-Agent kann mit einer Textabfrage als Eingabe und einem Intent sowie extrahierten Intent-Parametern als Ausgabe dargestellt werden.

Abbildung 2: Darstellung von Dialogflow als Query-In- und Intent-Out-System

Unittests

Für den Dialogflow-Agent können Sie Tests schreiben, bei denen jeder Fall eine Textabfrage als Eingabe erwartet und Intent-Metadaten als Ausgabe erstellt. Diese Metadaten sollten (mindestens) den Namen des übereinstimmenden Intents und eine Liste übereinstimmender Parameter enthalten.

Der Endpunkt detectIntent der Dialogflow API nimmt die Textabfrage als Eingabe und generiert eine strukturierte Ausgabe, die den Namen des aufgelösten Intents und der extrahierten Parameter enthält. Diese Ausgabe ist nützlich, um die Leistung des Agents für den Intent-Abgleich zu bewerten. Eine vollständige Referenz anderer nützlicher Felder finden Sie in der Referenz zu QueryResult.

Ein Beispieltest sieht so aus:

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');
});

In diesem Snippet werden Mocha und Chai verwendet. Unter Fakten über Google finden Sie ein vollständiges Beispiel für den in Node.js geschriebenen Dialogflow-Einheitentest.

Die Testdateien können parallel ausgeführt werden, da die Dialogflow API ein sessionId als Argument akzeptiert. Daher können Sie für jede Unterhaltung eine separate Sandbox haben, während Sie einen einzelnen Dialogflow API-Client verwenden.

Da Sie Anfragen an die Dialogflow API senden, können Gebühren anfallen, wenn Ihr Kontingent an kostenlosen Anrufen erreicht ist. Weitere Informationen finden Sie unter Kontingente und Limits.

Integrationstests

Der Endpunkt detectIntent der Dialogflow API löst außerdem die Auftragsausführung durch Drittanbieter aus. Daher ist es möglich, Testfälle für die Einbindung zwischen dem Dialogflow-Agent und der Dialogflow-Auftragsausführung zu schreiben.

Der Hauptunterschied zwischen dem Schreiben von Integrations- und Einheitentests für Dialogflow besteht darin, dass Sie beim Integrationstest Antworten aus dem Webhook sowie vom Dialogflow-Intent und der Entitätsextraktion bestätigen können.

Ein vollständiges Arbeitsbeispiel für einen in Node.js geschriebenen Integrationstest finden Sie im Repository Fakten über Google.

Dialogflow-Auftragsausführungs-Webhook testen

Der Dialogflow-Agent und die Dialogflow-Auftragsausführung werden als separate Komponenten getestet. In den folgenden Unterabschnitten wird beschrieben, wie Sie die Auftragsausführung für eine Aktion konzipieren und testen können.

Auftragsausführung als JSON-in- und JSON-out-System

Der Dialogflow-Auftragsausführungscode erwartet sowohl Anfragen als auch Antworten im JSON-Format. Daher können Sie sich den Auftragsausführungscode als JSON-in- und JSON-out-System vorstellen. Die Anfrage enthält Metadaten von Dialogflow und Actions on Google. Sie enthält also alles, was zum Auslösen eines bestimmten Intent-Handlers in der Auftragsausführung erforderlich ist.

Zum Testen des Triggers eines Intent-Handlers senden Sie eine JSON-Anfrage (Eingabe) an Ihre Aktion. Diese Anfrage wird an die Auftragsausführung übergeben, auf die im Internet zugegriffen werden kann. Die Auftragsausführung erzeugt dann eine JSON-Antwort (Ausgabe), die für die Validierung bewertet werden kann.

Eine Auftragsausführung kann mit einer JSON-Anfrageeingabe und einer Webhook-JSON-Antwortausgabe dargestellt werden.

Abbildung 3: Darstellung einer Auftragsausführung als JSON-in- und JSON-out-System

Unittests

Stellen Sie sich den Webhook-Code für die Auftragsausführung als ein System vor, das eine JSON-Eingabe akzeptiert und eine JSON-Ausgabe erstellt. Das Testen einer Aktion wird dann so vereinfacht, dass eine Anfrage an die Auftragsausführung gestellt und die resultierende JSON-Ausgabe geprüft wird.

So haben Sie die Möglichkeit, die Auftragsausführung lokal zu hosten und HTTP-Anfragen zum Testen lokal zu senden. Wenn Sie die Node.js-Clientbibliothek für Actions on Google verwenden, können Sie JSON-Anfragen auch direkt an die Middleware-Ebene der Clientbibliothek senden.

Wenn Sie den Webhook-Code mit JSON-Eingaben testen und die erwarteten JSON-Ausgaben erhalten, können Sie mit angemessener Sicherheit sagen, dass die von Ihnen gesteuerten Teile ordnungsgemäß funktionieren. Sie können davon ausgehen, dass Dialogflow und Actions on Google ordnungsgemäß funktionieren, da sie die richtigen JSON-Nutzlasten generieren. Diese Isolation bietet ein vereinfachtes Programmiermodell zum Schreiben von Tests.

Hier ein allgemeiner Überblick über den Testprozess:

  1. Verwenden Sie den Simulator in der Actions Console, um die JSON-Anfragen für jeden Schritt in einem Anwendungsfall abzurufen. Speichern Sie diese als JSON-Dateien. Alternativ können Sie diese Anfragen anhand der Informationen in der Webhook-Referenzdokumentation selbst erstellen.
  2. Schreiben Sie Tests, um den Webhook mit diesen Nutzlasten aufzurufen.
  3. Achten Sie bei jedem Test darauf, dass die JSON-Antwort die erwarteten Elemente enthält.

Darüber hinaus können Sie mit diesem Modell die Dialogflow-Auftragsausführung in einer Continuous Integration-Einstellung testen, da der Auftragsausführungsendpunkt lokal ausgeführt werden kann und die Dialogflow API ein integriertes Sitzungskonzept hat.

Ein Beispieltest sieht so aus:

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'},
    ]);
});

Im Snippet oben werden Mocha und Chai verwendet. Ein vollständiges Arbeitsbeispiel in Node.js finden Sie im Repository Facts Über Google.

Ausführung für einen Einheitentest entwerfen

Webhook-Code enthält häufig benutzerdefinierte Geschäftslogik, auf die Ihre Anwendung angewiesen ist, um ihre Anforderungen zu erfüllen. Darüber hinaus kann der Webhook-Code auch Intent-Handler enthalten.

Um den Detaillierungsgrad von Einheitentests für Ihren Auftragsausführungscode zu verbessern, sollten Sie den Code so organisieren, dass die Geschäftslogik von den Routinen zur Intent-Verarbeitung entkoppelt ist. Dies bedeutet, dass Intent-Handler und Geschäftslogik in separaten Modulen vorhanden sind, sodass jedes Teil unabhängig getestet werden kann.

Ein Beispiel finden Sie in unserer Shiritori-Beispielaktion auf GitHub. In diesem Beispiel enthalten functions/index.js und functions/shiritori/*.js separat die Intent-Handler und die Geschäftslogik, wodurch robustere Testsuiten erstellt werden.

Integrationstests

Informationen zum Schreiben von Testläufen, die die Einbindung zwischen Dialogflow und dem Code des Auftragsausführungs-Webhooks abdecken, finden Sie oben im Abschnitt Integrationstests für Dialogflow.

Lasttests

Bevor Sie die Aktion für die Produktion bereitstellen, empfehlen wir außerdem einen Belastungstest der Webhook-Auftragsausführung, um Leistungsprobleme zu erkennen, die zu einer Beeinträchtigung oder Unterbrechung des Auftragsausführungsdienstes führen.

Hier sind einige Beispiele für Leistungsprobleme, die Sie bei Lasttests feststellen können:

  • Begrenzter Rechen- und Arbeitsspeicher
  • Kontingentbeschränkungen von Ihren Anbietern
  • Langsames Lesen und Schreiben von Daten
  • Gleichzeitigkeitsprobleme im Code

Szenarien für Lasttests hängen vom erwarteten oder bisherigen Nutzungsmuster deiner Aktion ab. Typische Szenarien zum Testen sind jedoch plötzliche Anstiege der Last (Spitze) und anhaltende Lasten (Ein-/Aus-Stoß).

Ermitteln Sie Szenarien, in denen Ihr Webhook aufgerufen wird und ressourcenintensive Vorgänge ausführt. Zu den typischen ressourcenintensiven Vorgängen gehören das Abfragen einer Datenbank, das Aufrufen einer anderen API, das Ausführen von Rechen- und speicherintensiven Vorgängen wie dem Rendern einer Audiodatei.

In diesen Szenarien können Sie Anfragen, die von Actions on Google-Servern an den Webhook gesendet werden, aus Ihren Webhook-Logs oder aus Stackdriver-Logs erfassen. Sie können Anfragen auch über den Actions Console-Simulator erfassen.

Sobald Sie die Anfragen haben, können Sie ein Lasttesttool verwenden, um herauszufinden, wie der Webhook in verschiedenen Belastungstestszenarien reagiert. In den folgenden Unterabschnitten finden Sie einige Beispiele für Spitzen- und Prüftests mit ApacheBench.

Spitzentests

Spike-Tests erfordern, dass Sie für eine gewisse Zeit eine konstante Anzahl von Anfragen an den Webhook senden und die Last plötzlich erhöhen. Sie können beispielsweise einen Test einrichten, der eine Last von 10 Abfragen pro Sekunde mit einigen Spitzen von 60 Abfragen pro Sekunde sendet.

Mit dem folgenden ApacheBench-Befehl können Sie 60 gleichzeitige Anfragen an den Webhook senden:

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

Angenommen, die Datei ActionRequest.json enthält die erfasste Anfragenutzlast, die an den Webhook gesendet wurde.

Tiefentest

Bei Volltest-Tests müssen Sie eine konstante Anzahl von Anfragen an den Webhook senden und die Antwort beobachten. Sie können beispielsweise einen Test einrichten, der mehrere Minuten lang eine konstante Last von 10 bis 20 Abfragen pro Sekunde sendet, um festzustellen, ob die Antwortzeiten länger werden.

Mit dem folgenden ApacheBench-Befehl können Sie 1.200 Anfragen mit 10 gleichzeitigen Anfragen pro Sekunde senden:

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

Angenommen, die Datei ActionRequest.json enthält die erfasste Anfragenutzlast, die an den Webhook gesendet wurde.

Ergebnisse von Lasttests analysieren

Analysieren Sie nach den Lasttests die Ergebnisse der Webhook-Antwortzeiten. Indikatoren für Probleme in deiner Webhook-Implementierung sind in der Regel Trends, z. B. eine mit jedem Testlauf zunehmende durchschnittliche Antwortzeit oder eine Antwortzeit im schlimmsten Fall, die für deine Aktion nicht akzeptabel ist.

End-to-End-Tests

End-to-End-Tests vor dem Einreichen deiner Aktion zur Genehmigung verwenden den Actions Console-Simulator. Schritte für End-to-End-Tests über den Actions Console-Simulator finden Sie in der Dokumentation zum Actions Simulator. Mit diesen Tests können Sie potenzielle Unsicherheiten bei der Infrastrukturkomponente von Actions on Google beseitigen.