Setting up TDD with Intern.js
Preparing for Test Driven Development with Intern.js and BrowserStack
"Experience is a hard teacher because she gives the test first, the lesson afterwards."
~Vernon Saunders Law
Lesson Goal
This lesson will setup a new application using Intern.js and BrowserStack for TDD.
Why do TDD?
You should use TDD for many reasons, including:
- immediate feedback
- confident refactoring
- less time debugging
- tests as documentation
- verification across platforms and browsers
"If it's worth building, it's worth testing. If it's not worth testing, why are you wasting your time working on it?"
~Scott W. Ambler
Assumptions
- familiarity with the terminal or command line (bash)
- node.js or io.js installed
- npm installed
Start a basic app
mkdir chatapp
cd chatapp
npm init
Provide your initial npm package.json details
name: (chatapp)
version: 0.0.1
description: an app for rapid-fire chatting
entry point: (index.js)
test command: ./node_modules/.bin/intern-client config=tests/intern
git repository: YourGitHubName/chat-app
keywords: demo, chat, intern.js, gun
author: YourName
license: (Zlib OR MIT OR Apache-2.0)
About to write to /Volumes/.../Users/.../projects/chatapp/package.json:
...
Is this ok? (yes)
Install Intern
sudo npm install intern --save-dev
You will be prompted for your password.
Set up file structure
mkdir tests // for tests
mkdir app // for deployment code
Copy then open the intern config file intern.js
cp node_modules/intern/tests/example.intern.js tests/intern.js
// Open test/intern.js in a text editor such as Sublime or Textmate, e.g.
subl tests/intern.js
Point config to app directory
packages: [ { name: 'myPackage', location: '.' } ]
packages: [ { name: 'ChatApp', location: 'app' } ]
Verify initial test setup
./node_modules/.bin/intern-client config=tests/intern
// verify the test command response is
0/0 tests failed
The intern-client
command runs unit tests locally.
Setup local functional testing
Modify the tunnel
config option
Modify the environment
config option
Start the chromedriver
From the command line run
chromedriver --port=4444 --url-base=wd/hub
- This terminal or command line window will now be running the server. A new terminal or command line window will be needed to run subsequent commands against this server.
ctl-c
(Mac) to stop the server.
Verify the local functional test set-up
This command uses intern-runner
instead of intern-client
.
Review test results
Listening on 0.0.0.0:9000
Starting tunnel...
Initialised chrome 43.0.2357.132 on Mac OS X
No unit test coverage for chrome 43.0.2357.132 on Mac OS X
chrome 43.0.2357.132 on Mac OS X: 0/0 tests failed
TOTAL: tested 1 platforms, 0/0 tests failed
Set-up BrowserStack
- Create an account at https://www.browserstack.com.
- After logging in, expand the left hand side labeled "Username and Access Keys"
- In "intern.js" add the following block, with your username and key:
tunnel: 'NullTunnel',
tunnel: 'BrowserStackTunnel',
tunnelOptions: {
username: 'YOUR-USERNAME',
accessKey: 'YOUR-ACCESSKEY'
},
Verify the remote functional test set-up
- From the command line re-run:
node_modules/.bin/intern-runner config=tests/intern
- After setting up the tunnel, when this command is run, a chromium based test browser is being created on the tunneled provider's machines.
- Verify the test command response ends with:
TOTAL: tested 1 platforms, 0/0 tests failed; fatal error occurred
Add additional browsers
- Visit https://www.browserstack.com/automate/node#setting-os-and-browser
- Configure at least two more recent browsers (e.g. OS X Firefox, and Windows IE)
- Add the config to your "intern.js"
environments
array. Quotes may be removed from each key.environments: [
,{ browserName: 'chrome', version: '34', platform: 'MAC'}
,{ browser : 'IE', browser_version : '11.0',
os : 'Windows', os_version : '8.1',
resolution : '1024x768' }
,{ browser : 'Firefox', browser_version : '39.0',
os : 'OS X', os_version : 'Yosemite',
resolution : '1920x1080' }
],
- Modify
maxConcurrency: 3,
maxConcurrency: 4
,
At this point if you get a TypeError: undefined is not a function
logged to the console, do not worry.
Prepare to Test Locally
- In
intern.js
comment out the BrowserStack related configs tunnel: 'NullTunnel',
- And comment out all but the local environments:
environments: [
,{ browserName: 'chrome', version: '34', platform: 'MAC'}
],
Test Locally
- From the command line run:
node_modules/.bin/intern-runner config=tests/intern
- Verify the test command response ends with:
TOTAL: tested 1 platforms, 0/0 tests failed; fatal error occurred
Create first functional test file
- Create functional test directory
mkdir tests/functional
- Create and open
tests/functional/index.js
, e.g.subl tests/functional/index.js
- Add test file to
intern.js
functionalSuite's array
functionalSuites: [ ],
functionalSuites: [ 'tests/functional/index' ],
Create first functional test
Add the first test
define(function (require) {
var registerSuite = require('intern!object');
var assert = require('intern/chai!assert');
registerSuite({
name: 'index',
'chat index': function () {
return this.remote
.get(require.toUrl('index.html'))
.setFindTimeout(5000)
.findByTagName('body')
.getVisibleText()
.then(function (text) {
assert.strictEqual(text, 'Hello, World!',
'Greeting should be displayed when the page is loaded');
});
}
});
});
Hello World: Red
- Re-run local test
node_modules/.bin/intern-runner config=tests/intern
- Review the test total:
TOTAL: tested 1 platforms, 1/1 tests failed
- Review the initial test failure information:
Test main - index - chat index FAILED on chrome 44.0.2403.155 on Mac OS X:
AssertionError: Greeting should be displayed when the page is loaded: expected '404 Not Found' to equal 'Hello, World!'
Hello World - Local
- Create and open
index.html
, at the root level, e.g.subl index.html
- Create basic html structure, including "Hello, World!"
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
Hello, World!
</body>
</html>
- Review the test total:
TOTAL: tested 1 platforms, 0/1 tests failed
- GREEN :-)
Hello World - BrowserStack
Listening on 0.0.0.0:9000
Starting tunnel...
BrowserStackLocal v3.7
Ready
Initialised chrome 34.0.1847.116 on MAC
No unit test coverage for chrome 34.0.1847.116 on MAC
chrome 34.0.1847.116 on MAC: 0/1 tests failed
Initialised firefox 39.0.3 on MAC
No unit test coverage for firefox 39.0.3 on MAC
firefox 39.0.3 on MAC: 0/1 tests failed
Initialised internet explorer 11 on WINDOWS
No unit test coverage for internet explorer 11 on WINDOWS
internet explorer 11 on WINDOWS: 0/1 tests failed
TOTAL: tested 3 platforms, 0/3 tests failed
Conclusion
"Only a fool tests the depth of the water with both feet."
~ African proverb