UNPKG

6.97 kBMarkdownView Raw
1# Hubot test helper
2
3[![Build Status](https://travis-ci.org/mtsmfm/hubot-test-helper.svg?branch=master)](https://travis-ci.org/mtsmfm/hubot-test-helper)
4
5Helper for testing Hubot script.
6
7## Install
8
9`npm install hubot-test-helper --save-dev`
10
11## Usage
12
13If you have a following hubot script:
14
15```javascript
16module.exports = robot =>
17 robot.respond(/hi$/i, msg => msg.reply('hi'))
18```
19
20You can test it like:
21
22```javascript
23const Helper = require('hubot-test-helper');
24// helper loads all scripts passed a directory
25const helper = new Helper('./scripts');
26
27// helper loads a specific script if it's a file
28const scriptHelper = new Helper('./scripts/specific-script.js');
29
30const co = require('co');
31const expect = require('chai').expect;
32
33describe('hello-world', function() {
34 beforeEach(function() {
35 this.room = helper.createRoom();
36 });
37 afterEach(function() {
38 this.room.destroy();
39 });
40
41 context('user says hi to hubot', function() {
42 beforeEach(function() {
43 return co(function*() {
44 yield this.room.user.say('alice', '@hubot hi');
45 yield this.room.user.say('bob', '@hubot hi');
46 }.bind(this));
47 });
48
49 it('should reply to user', function() {
50 expect(this.room.messages).to.eql([
51 ['alice', '@hubot hi'],
52 ['hubot', '@alice hi'],
53 ['bob', '@hubot hi'],
54 ['hubot', '@bob hi']
55 ]);
56 });
57 });
58});
59```
60
61#### HTTPD
62
63By default Hubot enables a built in HTTP server. The server continues between
64tests and so requires it to be shutdown during teardown using `room.destroy()`.
65
66This feature can be turned off in tests that don't need it by passing using
67`helper.createRoom(httpd: false)`.
68
69See [the tests](test/httpd-world_test.js) for an example of testing the
70HTTP server.
71
72
73#### Manual delay
74
75Sometimes we can't access callback actions from a script.
76Just like in real use-case we may have to wait for a bot to finish processing before replying,
77in testing we may anticipate the delayed reply with a manual time delay.
78
79For example we have the following script:
80
81```javascript
82module.exports = robot =>
83 robot.hear(/(http(?:s?):\/\/(\S*))/i, res => {
84 const url = res.match[1];
85 res.send(`ok1: ${url}`);
86 robot.http(url).get()((err, response, body) => res.send(`ok2: ${url}`));
87 });
88```
89
90To test the second callback response "ok2: ..." we use the following script:
91
92```javascript
93const Helper = require('hubot-test-helper');
94const helper = new Helper('../scripts/http.js');
95
96const Promise = require('bluebird');
97const co = require('co');
98const expect = require('chai').expect;
99
100// test ping
101describe('http', function() {
102 beforeEach(function() {
103 this.room = helper.createRoom({httpd: false});
104 });
105
106 // Test case
107 context('user posts link', function() {
108 beforeEach(function() {
109 return co(function*() {
110 yield this.room.user.say('user1', 'http://google.com');
111 // delay one second for the second
112 // callback message to be posted to @room
113 yield new Promise.delay(1000);
114 }.bind(this));
115 });
116
117 // response
118 it('expects deplayed callback from ok2', function() {
119 console.log(this.room.messages);
120 expect(this.room.messages).to.eql([
121 ['user1', 'http://google.com'],
122 ['hubot', 'ok1: http://google.com'],
123 ['hubot', 'ok2: http://google.com']
124 ]);
125 });
126 });
127});
128```
129
130Note that `yield` and *generators* are part of [**ECMA6**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*), so it may not work on older node.js versions. It will wait for the delay to complete the `beforeEach` before proceeding to the test `it`.
131
132
133#### Testing messages sent to other rooms
134
135You can also test messages sent by your script to other rooms through Hubot's `robot.messageRoom(...)` method.
136
137Given the following script:
138```javascript
139module.exports = robot =>
140 robot.respond(/announce otherRoom: (.+)$/i, msg => {
141 robot.messageRoom('otherRoom', "@#{msg.envelope.user.name} said: #{msg.msg.match[1]}");
142 })
143```
144
145you could test the messages sent to other rooms like this:
146```javascript
147const Helper = require('../src/index');
148const helper = new Helper('../scripts/message-room.js');
149
150const expect = require('chai').expect;
151
152describe('message-room', function() {
153 beforeEach(function() {
154 this.room = helper.createRoom({name: 'room', httpd: false});
155 });
156
157 context('user asks hubot to announce something', function() {
158 beforeEach(function() {
159 return co(function*() {
160 yield this.room.user.say('alice', '@hubot announce otherRoom: I love hubot!');
161 }.bind(this));
162 });
163
164 it('should not post to this channel', function() {
165 expect(this.room.messages).to.eql([
166 ['alice', '@hubot announce otherRoom: I love hubot!']
167 ]);
168 });
169
170 it('should post to the other channel', function() {
171 expect(this.room.robot.messagesTo['otherRoom']).to.eql([
172 ['hubot', '@alice says: I love hubot!']
173 ]);
174 });
175 });
176});
177```
178
179
180#### Testing events
181
182You can also test events emitted by your script. For example, Slack users
183may want to test the creation of a
184[message attachment](https://api.slack.com/docs/attachments).
185
186Given the following script:
187
188```javascript
189module.exports = robot =>
190 robot.respond(/check status$/i, msg =>
191 robot.emit('slack.attachment', {
192 message: msg.message,
193 content: {
194 color: "good",
195 text: "It's all good!"
196 }
197 })
198 )
199```
200
201you could test the emitted event like this:
202
203```javascript
204const Helper = require('hubot-test-helper');
205const helper = new Helper('../scripts/status_check.js');
206
207const expect = require('chai').expect;
208
209describe('status check', function() {
210 beforeEach(function() {
211 this.room = helper.createRoom({httpd: false});
212 });
213
214 it('should send a slack event', function() {
215 let response = null;
216 this.room.robot.on('slack.attachment', event => response = event.content);
217
218 this.room.user.say('bob', '@hubot check status').then(() => {
219 expect(response.text).to.eql("It's all good!");
220 });
221 });
222});
223```
224
225## Development
226
227### Requirements
228
229- docker
230- docker-compose
231
232### Setup
233
234```
235git clone https://github.com/mtsmfm/hubot-test-helper
236cd hubot-test-helper
237docker-compose up -d
238docker-compose exec app bash
239yarn install
240```
241
242### Run test
243
244```
245yarn run test
246```
247
248#### Debug
249
250```
251yarn run test-unit-debug
252```
253
254Above command will output:
255
256```
257yarn run v0.18.1
258$ mocha --inspect --debug-brk --compilers coffee:coffee-script/register test
259Debugger listening on port 9229.
260Warning: This is an experimental feature and could change at any time.
261To start debugging, open the following URL in Chrome:
262 chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/59631086-0a0c-424b-8f5b-8828be123894
263```
264
265Then open `chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/59631086-0a0c-424b-8f5b-8828be123894` in Chrome.