BotSpec is a BDD-style framework for testing chatbots created with the Microsoft Bot Framework inspired by FluentAssertions.
BotSpec tests your bot over the Direct Line channel. For BotSpec to be able to communicate with your bot, the Direct Line channel needs to be enabled and you need to have your Direct Line secret or token to hand.
To start sending messages to your bot and testing the responses just create a new instance of the Expect
object using your Direct Line
secret or token:
var expect = new Expect("my secret or token");
Using Expect you can send messages to your bot:
expect.SendMessage("Hello!");
And then test the response:
expect.Message().TextMatching("Hi!");
Methods like TextMatching
take a regex string so can match on patterns:
expect.SendMessage("Hello, I am Kristian");
expect.Message().TextMatching("Hi [A-Za-z]*!");
The result of a pattern can also be saved for later use:
var names = new List<string>();
expect.SendMessage("Hello, I am Kristian");
expect.Message().TextMatching("Hi [A-Za-z]*!", "Hi ([A-Za-z]*)!", out names);
The second regex contains capture groups,
results of which are output as a list of strings (the 3rd parameter).
The names
list in the above example would contain just one value; "Kristian".
Bots can return a number of different types of attachments which can also be tested:
expect.SendMessage("Help me pick a movie");
expect.Message().TextMatching("Choose some movies from this list that you like");
expect.Message().WithAttachment().OfTypeThumbnailCard().TextMatching("Fight Club").WithButtons().TitleMatching("Yes");
expect.Message().WithAttachment().OfTypeThumbnailCard().TextMatching("The Matrix").WithButtons().TitleMatching("Yes");
The above code does the following:
- Sends a message to the bot with the text "Help me pick a movie"
- Expects a response from the bot with text that matches "Choose some movies from this list that you like"
- Expects a response from the bot that contains a thumbnail card with text that matches "Fight Club" and has a button with a title matching "Yes"
- Expects a response from the bot that contains a thumbnail card with text that matches "The Matrix" and has a button with a title matching "Yes"
The test will pass if any message matches these conditions. This means that there may be one message that satisifies the expectations shown above or there may be many where different messages satisfy one of the expectations each.
Using NUnit a test putting all of that together may look like:
[Test]
public void When_I_ask_for_help_picking_a_movie_I_get_choices_on_buttons_back()
{
var expect = new Expect("my token here");
expect.SendMessage("Hello, I am Kristian");
expect.Message().TextMatching("Hi [A-Za-z]*!");
expect.SendMessage("Help me pick a movie");
expect.Message().TextMatching("Choose some movies from this list that you like");
expect.Message().WithAttachment().OfTypeThumbnailCard().TextMatching("Fight Club").WithButtons().TitleMatching("Yes");
expect.Message().WithAttachment().OfTypeThumbnailCard().TextMatching("The Matrix").WithButtons().TitleMatching("Yes");
}