- Introduction
- Testing Multiple Replies
- Simulating User Messages
- Available Assertions
- Testing Conversations
- Testing Events
- Advanced Testing
{callout-info} The BotMan testing features are only available in combination with BotMan Studio.
Like Laravel, BotMan is build with testing in mind. Every part of it is well tested and this is the only way to keep such a big project running properly.
But also your bots should be built with tests and this is why BotMan Studio will help you with that. Testing bots and conversations is very different from your other projects. This is why BotMan Studio provides lots of helper methods for you. This is the basic test example you will find in your ExampleTest.php
file.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReply('Hello!');
}
All assertion methods can be chained to test cases when your bot responds with more than one message.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReply('Hello!')
->assertReply('Nice to meet you');
}
Additionally you can you use the assertReplies()
method if you want to test multiple replies at once.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReplies([
'Hello!',
'Nice to meet you',
]);
}
BotMan can receive attachment objects from user and there are methods that help you test those cases. You can use receivesLocation
, receivesImages
, receivesVideos
, receivesAudio
and receivesFiles
methods to simulate that user has send valid attachments.
public function testBasicTest()
{
$this->bot
->receivesLocation()
->assertReply('Thanks for locations');
}
You can pass additional $latitude
and $longitude
arguments to receivesLocation
if necessary.
public function testBasicTest()
{
$this->bot
->receivesLocation($latitude, $longitude)
->assertReply('Your latidude is ' . $latitude);
}
You can pass additional array of urls to receivesImages
, receivesVideos
, receivesAudio
and receivesFiles
methods if necessary.
public function testBasicTest()
{
$this->bot
->receivesImage(['www.example.com/dog'])
->assertReply('You sent me dog image');
}
There are cases when we expect our chatbot user to respond to a question with an interactive reply - for example a button click. To simulate that, use the receivesInteractiveMessage
method. It accepts the button value as an argument.
public function testBasicTest()
{
$this->bot
->receivesInteractiveMessage('dog')
->assertReply('You chose dog!');
}
BotMan comes with handful of useful methods to test you chatbots.
The assertReply
method asserts that the chatbot replies with the given message.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReply('Hello');
}
The assertReplies
method asserts that the chatbot replies with all messages in the given array.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReplies([
'Hello!',
'Nice to meet you',
]);
}
The assertReplyIsNot
method asserts that the chatbot does not reply with the given message.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReplyIsNot('Good bye');
}
The assertReplyIn
method asserts that the chatbot replies with one message from the given array. This is helpful if your bot uses random answers.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReplyIn([
'Hi',
'Hello',
'Bonjourno'
]);
}
The assertReplyNotIn
method asserts that the chatbot does not reply with any of the given messages.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReplyNotIn([
'Bye',
'Good bye',
'Arrivederci'
]);
}
The assertReplyNothing
method asserts that the chatbot does not reply with any message at all. Useful when chained with other assertion methods to check that the chatbot stopped responding.
public function testBasicTest()
{
$this->bot
->receives('Hi')
->assertReply('Hello')
->assertReplyNothing();
}
The assertQuestion
method asserts that the chatbot replies with a Question object. If you call this method without an argument it just checks for a question occurance. Otherwise it will test for the question text.
public function testBasicTest()
{
$this->bot
->receives('Start conversation')
->assertQuestion();
}
public function testBasicTest()
{
$this->bot
->receives('Start conversation')
->assertQuestion('What do you want to talk about');
}
The assertTemplate
method asserts that the chatbot does reply with a given template class. This is especially useful when testing Facebook reply templates.
public function testBasicTest()
{
$this->bot
->receives('News feed')
->assertTemplate(GenericTemplate::class);
}
You can pass true
as a second argument to test that the templates are exactly the same (strict mode).
public function testStartJokeConversation()
{
$jokeTypeQuestion = ButtonTemplate::create('Please select the kind of joke you wanna hear:')
->addButtons([
ElementButton::create('Chuck Norris')->type('payload')->payload('chucknorris'),
ElementButton::create('Children')->type('payload')->payload('children'),
ElementButton::create('Politics')->type('payload')->payload('politics'),
]);
$this->bot
->receives('start joke conversation')
->assertTemplate($jokeTypeQuestion, true);
}
When you want to test a longer conversation you can chain the given methods. Just add another receives()
and an assertion
afterwards.
public function testStartConversation()
{
$this->bot
->receives('Hi')
->assertReplies([
'Hello!',
'Nice to meet you. What is your name?',
])->receives('BotMan')
->assertReply('BotMan, that is a beautifule name :-)');
}
BotMan supports testing for driver specific events with the receivesEvent
method.
public function testStartConversation()
{
$this->bot
->receivesEvent('event_name')
->assertReply('Received event');
}
You can pass a $payload
array as an additional argument as well.
public function testStartConversation()
{
$this->bot
->receivesEvent('event_name', ['key' => 'value'])
->assertReply('Received event');
}
If you are building multi-driver chatbots with BotMan you may have restricted some commands to specific drivers only - for example using the group
method.
$botman->group(['driver' => FacebookDriver::class], function ($bot) {
$bot->hears('Facebook only', function ($bot) {
$bot->reply('You are on messenger');
});
});
The BotMan testing environment uses a fake driver class to run the tests, but we can change the name of the driver with the setDriver
method.
public function testStartConversation()
{
$this->bot
->setDriver(FacebookDriver::class)
->receives('Facebook only')
->assertReply('You are on messenger');
}
In a similar manner you can set user information with the setUser
method.
public function testStartConversation()
{
$this->bot
->setUser([
'first_name' => 'John'
])
->receives('Hi')
->assertReply('Hi, John!);
}
In cases when your bot replies with several messages you can assert only a specific reply using the reply
method to skip assertion. All tests below will pass.
public function testStartConversation()
{
$this->bot
->receives('Tell me something')
->assertReply('Hmm..')
->assertReply('Ok')
->assertQuestion('Here are some topics we could discuss');
}
public function testStartConversation()
{
$this->bot
->receives('Tell me something')
->reply()
->assertReply('Ok')
->assertQuestion('Here are some topics we could discuss');
}
public function testStartConversation()
{
$this->bot
->receives('Tell me something')
->reply(2)
->assertQuestion('Here are some topics we could discuss');
}
If none of the helper methods can handle your specific test case you can use the receiveRaw
and assertRaw
methods.
public function testStartConversation()
{
$incoming = new IncomingMessage('Hi', '12345678', 'abcdefgh');
$outgoing = new OutgoingMessage('Hello');
$this->bot
->receivesRaw($incoming)
->assertRaw($outgoing);
}