how to write testable javascript

69
How do I write Testable Javascript?

Upload: coldfusionconference

Post on 22-Jan-2017

89 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: How to write Testable Javascript

★How do I writeTestable Javascript?

Page 2: How to write Testable Javascript

★Agenda★Who Am I?

★State of the Room?

★Ways to test Javascript?

★Different Testing Environments?

★Overview of Testing Tools

★Using Testing in your Workflow

★Spaghetti Javascript

★Refactor Spaghetti into Testable Javascript

★Installing Jasmine + Live Demo

Page 3: How to write Testable Javascript

★Who Am I?★Gavin Pickin – developing Web Apps since late 90s

○Ortus Solutions Software Consultant

○ContentBox Evangelist

★What else do you need to know?

○CFMLRepo.com http://www.cfmlrepo.com

○Blog - http://www.gpickin.com

○Twitter – http://twitter.com/gpickin

○Github - https://github.com/gpickin

★Lets get on with the show.

Page 4: How to write Testable Javascript

★State of the Room

★ A few questions for you guys★ If you have arms, use them.

Page 5: How to write Testable Javascript

★State of the RoomTesting? What’s testing?

Page 6: How to write Testable Javascript

★State of the Room

Yeah,I’ve heard of it.

Why do you think I’m here?

Page 7: How to write Testable Javascript

★State of the RoomYes I know I should be testing, but I’m not sure how to do it

Page 8: How to write Testable Javascript

★State of the RoomMy Boss and my Customers wouldn’t let me

Page 9: How to write Testable Javascript

★State of the Room

I’m a tester

Page 10: How to write Testable Javascript

★State of the RoomI’m a test writing ninjaCall me Majano, Luis Majano

Page 11: How to write Testable Javascript

★Ways to Test your Code★Click around in

the browser yourself

★Setup Selenium / Web Driver to click around for you

★Structured Programmatic Tests

Page 12: How to write Testable Javascript

★Types of Testing

Page 13: How to write Testable Javascript

★Types of Testing

★Black/White Box

★Unit Testing

★Integration Testing

★Functional Tests

★System Tests

★End to End Tests

★Sanity Testing

★Regression Test

★Acceptance Tests

★Load Testing

★Stress Test

★Performance Tests

★Usability Tests

★+ More

Page 14: How to write Testable Javascript

★Levels of Testing

Page 15: How to write Testable Javascript

★Cost of a Bug

The bug will cost one way or another

Page 16: How to write Testable Javascript

★Integration Testing

Page 17: How to write Testable Javascript

★Integration Testing

★Integration Tests several of the pieces together

★Most of the types of tests are variations of an Integration Test

★Can include mocks but can full end to end tests including DB / APIs

Page 18: How to write Testable Javascript

★Unit Testing

Page 19: How to write Testable Javascript

★Unit Testing

“unit testing is a software verification and validation method in which a programmer tests if individual units of source code are fit for use. A unit is the smallest testable part of an application”- wikipedia

Page 20: How to write Testable Javascript

★Unit Testing★Can improve code quality -> quick error

discovery

★Code confidence via immediate verification

★Can expose high coupling

★Will encourage refactoring to produce > testable code

★Remember: Testing is all about behavior and expectations

Page 21: How to write Testable Javascript

★Styles – TDD vs BDD

★TDD = Test Driven Development

○Write Tests

○Run them and they Fail

○Write Functions to Fulfill the Tests

○Tests should pass

○Refactor in confidence

★Test focus on Functionality

Page 22: How to write Testable Javascript

★Styles – TDD vs BDD

★BDD = Behavior Driven DevelopmentActually similar to TDD except:

★Focuses on Behavior and Specifications

★Specs (tests) are fluent and readable

★Readability makes them great for all levels of testing in the organization

★Hard to find TDD examples in JS that are not using BDD describe and it blocks

Page 23: How to write Testable Javascript

★TDD Example

Test( ‘Email address must not be blank’, function(){

notEqual(email, “”, "failed");});

Page 24: How to write Testable Javascript

★BDD ExampleDescribe( ‘Email Address’, function(){

It(‘should not be blank’, function(){

expect(email).not.toBe(“”);});

});

Page 25: How to write Testable Javascript

★Matchers

expect(true).toBe(true);expect(true).toBe(true);expect(true).toBe(true);expect(true).toBe(true);

Page 26: How to write Testable Javascript

★Matchers

expect(true).not.toBe(true);expect(true).not.toBe(true);expect(true).not.toBe(true);expect(true).not.toBe(true);expect(true).not.toBe(true);

Page 27: How to write Testable Javascript

★Matcher Samples

expect(true).toBe(true);

expect(a).not.toBe(null);

expect(a).toEqual(12);

expect(message).toMatch(/bar/);

expect(message).toMatch("bar");

expect(message).not.toMatch(/quux/);

expect(a.foo).toBeDefined();

expect(a.bar).not.toBeDefined();

Page 28: How to write Testable Javascript

★Different Testing Environments?

NodeJS - CLI In the Browser

Page 29: How to write Testable Javascript

★Overview of Testing Tools★There are a few choices

Page 30: How to write Testable Javascript

★Main Testing Players★Jasmine, Mocha and QUnit

Page 31: How to write Testable Javascript

★Jasmine★Jasmine comes ready to go out of the box

★Fluent Syntax – BDD Style

★Includes lots of matchers

★Has spies included

★Very popular, lots of support

★Angular uses Jasmine with Karma (CLI)

★Headless running and plays well with CI servers

Page 32: How to write Testable Javascript

★Jasmine - Cons

★Async testing in 1.3 can be a headache

★Expects *spec.js suffix for test files

○This can be modified depending on how you are running the tests

Page 33: How to write Testable Javascript

★Jasmine – Sample Test

describe("Hello world function", function() {

it(”contains the word world", function() {

expect(helloWorld()).toContain("world");

});

});

Page 34: How to write Testable Javascript

★Mocha★Simple Setup

★Simple Async testing

★Works great with other Assertion libraries like Chai ( not included )

★Solid Support with CI Servers, with Plugins for others

★Opinion says Mocha blazing the trail for new features

Page 35: How to write Testable Javascript

★Mocha - Cons★Requires other Libraries for key features

○No Assertion Library included

○No Mocking / Spied included

○Need to create the runner manually

★Newer to the game so not as popular or supported as others but gaining traction.

Page 36: How to write Testable Javascript

★Mocha – BDD Sample Testvar expect = require('chai').expect;

describe(’Hello World Function', function(){

it('should contain the word world', function(){

expect(helloWorld()).to.contain(’world');

})

})

Page 37: How to write Testable Javascript

★QUnit

★The oldest of the main testing frameworks

★Is popular due to use in jQuery and age

★Ember’s default Unit testing Framework

Page 38: How to write Testable Javascript

★QUnit - Cons

★Development slowed down since 2013 (but still under development)

★Syntax – No BDD style

★Assertion libraries – limited matchers

Page 39: How to write Testable Javascript

★QUnit – Sample TestQUnit.test( "ok test", function( assert ) {

assert.ok( true, "true succeeds" );

assert.ok( "non-empty", "non-empty string succeeds" );

assert.ok( false, "false fails" );

assert.ok( 0, "0 fails" );

assert.ok( NaN, "NaN fails" );

assert.ok( "", "empty string fails" );

assert.ok( null, "null fails" );

assert.ok( undefined, "undefined fails" );

});

Page 40: How to write Testable Javascript

★Spaghetti Javascript

Photo Credit – Kombination http://www.kombination.co.za/wp-content/uploads/2012/10/baby_w_spaghetti_mess_4987941.jpg

Page 41: How to write Testable Javascript

★Spaghetti Javascript ExampleIf we have time at the end

Page 42: How to write Testable Javascript

★Spaghetti Javascript Example

Page 43: How to write Testable Javascript

★Refactoring Spaghetti

★Things to refactor to make your code testable

○Code should not be one big chunk of Javascript in onReady()

○Deep nested callbacks & Anon functions cannot easily be singled out and tested

○Remove Tight Coupling – DOM access for example

Page 44: How to write Testable Javascript

★Object Literals

var personObjLit = {

ssn: ’xxxxxxxx',age: '35',name: 'Gavin Pickin',

getAge: function(){return this.age;

},getName: function() {

return this.name;}

};

Page 45: How to write Testable Javascript

★Module Pattern

var personObjLit2 = function() {ssn = ’xxxxxxx';age = '35';name = 'Gavin Pickin’;return {

getAge: function(){return age;

},getName: function() {

return name;}

};};

Page 46: How to write Testable Javascript

★Using Testing in your Workflow

★Using HTML Test Runners

○Keep a Browser open○F5 refresh tests

Page 47: How to write Testable Javascript

★Command Line Tests

★Run Jasmine – manual

○Run tests at the end of each section of work

★Run Grunt-Watch – automatic

○Runs Jasmine on every file change

○Grunt can run other tasks as well, minification etc

Page 48: How to write Testable Javascript

★Testing in your IDE

★Browser Views

○Eclipse allows you to open files in web view – uses HTML Runner

★Run Jasmine / Grunt / Karma in IDE Console

○Easy to setup – See Demo– Sublime Text 2

Page 49: How to write Testable Javascript

★Live Demo and Examples

*Install / Run Jasmine Standalone for Browser

*Install / Run Jasmine with NodeJs

*Install/ Run Jasmine with Grunt Watch

*Install / Run Grunt Watch inside Sublime Text 2

Page 50: How to write Testable Javascript

★Install / Run Jasmine for In-Browser Testing

Download standalone package from Github (I have 2.1.3)

https://github.com/jasmine/jasmine/tree/master/dist

Unzip into your /tests folder

Run /tests/SpecRunner.html to see example tests

Page 51: How to write Testable Javascript

★Standalone Jasmine

Page 52: How to write Testable Javascript

★Installing Jasmine for in Browser Testing

Page 53: How to write Testable Javascript

★SpecRunner Setup Jasmine Browser Test

<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Jasmine Spec Runner v2.1.3</title> <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.1.3/jasmine_favicon.png"> <link rel="stylesheet" href="lib/jasmine-2.1.3/jasmine.css”> <script src="lib/jasmine-2.1.3/jasmine.js"></script> <script src="lib/jasmine-2.1.3/jasmine-html.js"></script> <script src="lib/jasmine-2.1.3/boot.js"></script> <!-- include source files here... --> <script src="../js/services/loginService.js"></script> <!-- include spec files here... --> <script src="spec/loginServiceSpec.js"></script></head><body></body></html>

Page 54: How to write Testable Javascript

★Installing Jasmine with NodeJS

Assuming you have NodeJs Installed… install Jasmine

$ npm install jasmine

[email protected] node_modules/jasmine

├── [email protected]

├── [email protected]

└── [email protected] ([email protected], [email protected])

Page 55: How to write Testable Javascript

★Installing Jasmine with NodeJS

Once Jasmine is installed in your project

$ Jasmine init

Page 56: How to write Testable Javascript

★Installing Jasmine with NodeJS

Edit Jasmine.json to update Locations for Spec Files and Helper Files

{ "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" ]}

Page 57: How to write Testable Javascript

★Running Jasmine Tests with NodeJS$ Jasmine

StartedFFailures:1) A suite contains spec with an expectation Message: Expected true to be false. Stack: Error: Expected true to be false. at Object.<anonymous> (/Users/gavinpickin/Dropbox/Apps/testApp/www/spec/test_spec.js:3:18)1 spec, 1 failureFinished in 0.009 seconds

Page 58: How to write Testable Javascript

★Running Jasmine Tests with NodeJS

★Jasmine-Node is great for Node

★Jasmine Node doesn’t have a headless browser

★Hard to test Browser code

★So what should I use?

Page 59: How to write Testable Javascript

★Installing Jasmine with Grunt Watcher

★ Install Gruntnpm install grunt

★ Install Grunt – Jasminenpm install grunt-contrib-jasmine

★ Install Grunt – Watchnpm install grunt-contrib-watch

★Note: On Mac, I also needed to install Grunt CLInpm install –g grunt-cli

Page 60: How to write Testable Javascript

★Configuring Jasmine with Grunt Watcher

// gruntfile.js - https://gist.github.com/gpickin/1e1e7902d1d3676d23c5

module.exports = function (grunt) {

grunt.initConfig({

pkg: grunt.file.readJSON('node_modules/grunt/package.json'),

jasmine: {

all: {

src: ['js/*.js' ],

options: {

//'vendor': ['path/to/vendor/libs/*.js'],

'specs': ['specs/*.js' ]

}

}

},

Page 61: How to write Testable Javascript

★Configuring Jasmine with Grunt Watcher

// gruntfile.js part 2

watch: {

js: {

files: [

'js/*.js',

'specs/*.js',

],

tasks: ['jasmine:all']

}

}

});

Page 62: How to write Testable Javascript

★Configuring Jasmine with Grunt Watcher

// gruntfile.js part 3

grunt.loadNpmTasks('grunt-contrib-jasmine');

grunt.loadNpmTasks('grunt-contrib-watch');

};

Page 63: How to write Testable Javascript

★Example Spec Jasmine with Grunt Watcher

describe("A suite", function() { it("contains spec with an expectation", function() { expect(true).toBe(true);

});

});

Page 64: How to write Testable Javascript

★Running Jasmine with Grunt Watcher

Page 65: How to write Testable Javascript

★Running Jasmine with Grunt Watcher

Page 66: How to write Testable Javascript

★Running in Sublime Text 2

★Install PackageControl into Sublime Text

★Install Grunt from PackageControl

○https://packagecontrol.io/packages/Grunt

★Update Grunt Sublime Settings for paths{

"exec_args": { "path": "/bin:/usr/bin:/usr/local/bin” }

}

★Then Command Shift P – grunt

Page 67: How to write Testable Javascript

★Running in Sublime Text 2

Page 68: How to write Testable Javascript

★Refactoring Spaghetti

★Lets look at some code

★This isn’t BEST PRACTICE, its BETTER PRACTICE than you were doing

★Its not really refactoring if you don’t have tests, its

“moving code and asking for trouble”

Page 69: How to write Testable Javascript

★Q&A

★Any questions?