Testing your Components
As your Botonic project gets bigger, you must test every component of your bot to:
- Avoid introducing breaking changes.
- Decide whether the quality of the code is sufficient or not.
- Find as many bugs as possible.
Botonic provides a way of testing your bot, based on JEST.
You can execute your tests by running botonic test
or npm run test
.
We suggest that you use npm run test
for a better visualization.
Let's see how you can define your tests by looking at the childs
example:
src/routes.js
import Hi from './actions/hi'
import Pizza from './actions/pizza'
import Sausage from './actions/sausage'
import Bacon from './actions/bacon'
import Pasta from './actions/pasta'
import Cheese from './actions/cheese'
import Tomato from './actions/tomato'
export const routes = [
{
path: 'hi',
text: /^hi$/i,
action: Hi,
childRoutes: [
{
path: 'pizza',
payload: /^pizza$/i,
action: Pizza,
childRoutes: [
{ path: 'sausage', payload: /^sausage$/i, action: Sausage },
{ path: 'bacon', payload: /^bacon$/i, action: Bacon },
],
},
{
path: 'pasta',
payload: /^pasta$/i,
action: Pasta,
childRoutes: [
{ path: 'cheese', payload: /^cheese$/i, action: Cheese },
{ path: 'tomato', payload: /^tomato$/i, action: Tomato },
],
},
],
},
]
More concretely, let's focus on testing whether when we pass a payload with the value "pizza", the Pizza action is rendered.
{
path: "hi", text: /^hi$/i, action: Hi,
childRoutes: [
{
path: "pizza", payload: /^pizza$/i, action: Pizza, // <-- input to test
childRoutes: [
{ path: "sausage", payload: /^sausage$/i, action: Sausage },
{ path: "bacon", payload: /^bacon$/i, action: Bacon },
],
},
],
}
You can see the Pizza action will only be rendered after receiving a payload matching
the regular expression /^pizza$/i
, with an empty session {}
and coming from the hi
path. This can be defined as follows:
import { BotonicInputTester } from '@botonic/react'
let i = new BotonicInputTester(App)
i.payload('pizza', {}, 'hi')
In this way, the purpose of representing an input can be achieved. Let's have a look now at how to represent an output action to be rendered.
src/actions/pizza.js
import React from 'react'
import { Text, Reply } from '@botonic/react'
export default class extends React.Component {
render() {
return (
<Text>
You chose Pizza! Choose one ingredient:
<Reply payload='sausage'>Sausage</Reply>
<Reply payload='bacon'>Bacon</Reply>
</Text>
)
}
}
Then, this component can be defined in the following way:
import { BotonicOutputTester } from '@botonic/react'
let o = new BotonicOutputTester(App)
o.text(
'You chose Pizza! Choose one ingredient:',
o.replies(
{ text: 'Sausage', payload: 'sausage' },
{ text: 'Bacon', payload: 'bacon' }
)
)
It's that simple! Now, alongside the methods expect and toBe of JEST, you can define the entire test like this:
tests/app.test.js
import { BotonicInputTester, BotonicOutputTester } from '@botonic/react'
import App from '../src/app'
let i = new BotonicInputTester(App)
let o = new BotonicOutputTester(App)
// Put a name to your test
test('TEST: pizza.js', async () => {
await expect(i.payload('pizza', {}, 'hi')) // Expected input
.resolves.toBe(
// Expected output
o.text(
'You chose Pizza! Choose one ingredient:',
o.replies(
{ text: 'Sausage', payload: 'sausage' },
{ text: 'Bacon', payload: 'bacon' }
)
)
)
})