Skip to content

Utiliser le framework de test

Tock met à disposition des extensions pour tester le bot unitairement.

Pour les utiliser, il est nécessaire d’ajouter la librairie bot-test à votre projet.

Avec Maven :

        <dependency>
            <groupId>ai.tock</groupId>
            <artifactId>bot-test</artifactId>
            <version>23.9.2</version>
            <scope>test</scope>
        </dependency>

ou Gradle :

      testCompile 'ai.tock:bot-test:23.9.2'

L’ensemble de ce framework est documenté au format KDoc ici.

Ecrire un test simple

L’ensemble des exemples suivants utilisent JUnit5. Une extension dédiée à Tock et JUnit5 est disponible.


    @RegisterExtension
    @JvmField
    val ext = TockJUnit5Extension(bot)

Afin de tester la story greetings du bot Open Data, il suffit d’utiliser la méthode ext.send() qui permet d’obtenir un mock du bus conversationnel. Le test unitaire s’écrit alors ainsi :


    @Test
    fun `greetings story displays welcome message WHEN locale is fr`() {
        ext.send(locale = Locale.FRENCH) {
            firstAnswer.assertText("Bienvenue chez le Bot Open Data Sncf! :)")
            secondAnswer.assertText("Il s'agit d'un bot de démonstration du framework Tock : https://github.com/theopenconversationkit/tock")
        }
    }

Comme le connector par défaut est celui de Messenger, il est possible de tester de la même manière le message spécifique à Messenger :


    lastAnswer.assertMessage(
                buttonsTemplate(
                    "Il est volontairement très limité, mais demandez lui un itinéraire ou les départs à partir d'une gare et constatez le résultat! :)",
                    postbackButton("Itinéraires", search),
                    postbackButton("Départs", Departures),
                    postbackButton("Arrivées", Arrivals)
                )
            )

Pour tester le message spécifique à Google Assistant (ou tout autre connecteur), il est nécessaire de spécifier le connecteur que l’on souhaite tester :

    ext.send(connectorType = gaConnectorType, locale = Locale.FRENCH) {
            firstAnswer.assertText("Bienvenue chez le Bot Open Data Sncf! :)")
            secondAnswer.assertText("Il s'agit d'un bot de démonstration du framework Tock : https://github.com/theopenconversationkit/tock")
            lastAnswer.assertMessage(
                gaMessage(
                    "Il est volontairement très limité, mais demandez lui un itinéraire ou les départs à partir d'une gare et constatez le résultat! :)",
                    "Itinéraires",
                    "Départs",
                    "Arrivées"
                )
            )
        }

Tester une Story spécifique

Dans les exemples précédents, il n’était pas nécessaire d’indiquer la story à tester (greetings étant la story par défaut). Supposons que nous souhaitons la story search, nous devons préciser la story à tester de la manière suivante :


    @Test
    fun `search story asks for destination WHEN there is no destination in context`() {
        ext.send(intent = search, locale = Locale.FRENCH) {
            firstAnswer.assertText("Pour quelle destination?")
        }
    }

Tester un dialogue

Il est possible de simuler un dialogue complet. Par exemple, on simule ici que l’utilisateur indique la destination, puis l’origine :


    @Test
    fun `search story asks for origin WHEN there is a destination but no origin in context`() {
        ext.send("Je voudrais rechercher un itinéraire", search, locale = Locale.FRENCH) {
            firstAnswer.assertText("Pour quelle destination?")
        }
        ext.send("Lille", indicate_location, locationEntity setTo lille) {
            firstBusAnswer.assertText("Pour quelle origine?")
        }
        ext.send("Paris", indicate_location, locationEntity setTo paris) {
            firstBusAnswer.assertText("Quand souhaitez-vous partir?")
        }
    }

Le texte en premier paramètre de la méthode send est simplement indicatif, pour aider à la compréhension des tests. Les paramètres suivants permettent de définir comment le NLP va analyser la phrase. Par exemple :

    private val lille = PlaceValue(
        SncfPlace(
            "stop_area",
            90,
            "Lille Europe",
            "Lille Europe (Lille)",
            "stop_area:OCE:SA:87223263",
            Coordinates(50.638861, 3.075774)
        )
    )

    ext.send("Lille", indicate_location, locationEntity setTo lille)

permet d’indiquer que la phrase “Lille” est catégorisée comme une intention indicate_location et avec une valeur pour l’entité location qui va être la localisation lille

Enfin il est possible de modifier toutes les valeurs du bus mocké à l’initialisation. Dans l’exemple suivant, on simule l’intention secondaire indicate_location afin d’indiquer l’origine :


    @Test
    fun `search story asks for departure date WHEN there is a destination and an origin but no departure date in context`() {
        ext.newRequest("Recherche", search, locale = Locale.FRENCH) {
            destination = lille
            origin = paris

            run()

            firstAnswer.assertText("Quand souhaitez-vous partir?")
        }
    }

Les variables origin et destination sont mises à jour, puis un appel au bus est simulé avec la fonction run().