how do i write testable javascript?

58
*

Upload: devobjective

Post on 08-Aug-2015

35 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: How do I write testable javascript?

* 

Page 2: How do I write testable javascript?

* * 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 do I write testable javascript?

* * Gavin Pickin – developing Web Apps since late 90s

* What else do you need to know? * Blog - http://www.gpickin.com

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

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

* Lets get on with the show.

Page 4: How do I write testable javascript?

* * A few questions for you guys

* If you have arms, use them.

Page 5: How do I write testable javascript?

* * Click around in the browser yourself

* Setup Selenium / Web Driver to click around for you

* Structured Programmatic Tests

Page 6: How do I write testable javascript?

* * 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 7: How do I write testable javascript?

* * 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 8: How do I write testable javascript?

* “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 9: How do I write testable javascript?

* * 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 10: How do I write testable javascript?

* * 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 11: How do I write testable javascript?

* * BDD = Behavior Driven Development Actually 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 12: How do I write testable javascript?

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

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

});

Page 13: How do I write testable javascript?

* Describe( ‘Email Address’, function(){

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

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

});

});

Page 14: How do I write testable javascript?

* 

expect(true).toBe(true);

expect(true).toBe(true);

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

Page 15: How do I write testable javascript?

* 

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 16: How do I write testable javascript?

* 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 17: How do I write testable javascript?

* 

NodeJS - CLI In the Browser

Page 18: How do I write testable javascript?

* * There are a few choices

Page 19: How do I write testable javascript?

* * Jasmine, Mocha and QUnit

Page 20: How do I write testable javascript?

* * 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 21: How do I write testable javascript?

* 

* 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 22: How do I write testable javascript?

* 

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

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

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

});

});

Page 23: How do I write testable javascript?

* * 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 24: How do I write testable javascript?

* * 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 25: How do I write testable javascript?

* var expect = require('chai').expect;

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

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

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

})

})

Page 26: How do I write testable javascript?

* 

* The oldest of the main testing frameworks

* Is popular due to use in jQuery and age

* Ember’s default Unit testing Framework

Page 27: How do I write testable javascript?

* 

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

* Syntax – No BDD style

* Assertion libraries – limited matchers

Page 28: How do I write testable javascript?

* QUnit.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 29: How do I write testable javascript?

* 

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

Page 30: How do I write testable javascript?

* 

Page 31: How do I write testable javascript?

* 

Page 32: How do I write testable javascript?

* 

* 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 33: How do I write testable javascript?

* 

* 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 34: How do I write testable javascript?

* var personObjLit = {

ssn: ’xxxxxxxx', age: '35', name: 'Gavin Pickin', getAge: function(){ return this.age; }, getName: function() { return this.name; } };

Page 35: How do I write testable javascript?

* var personObjLit2 = function() {

ssn = ’xxxxxxx'; age = '35'; name = 'Gavin Pickin’; return { getAge: function(){ return age; }, getName: function() { return name; } }; };

Page 36: How do I write testable javascript?

* * Using HTML Test Runners * Keep a Browser open

* F5 refresh tests

Page 37: How do I write testable javascript?

* * 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 38: How do I write testable javascript?

* * 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 39: How do I write testable javascript?

* 

* 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 40: How do I write testable javascript?

* 

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 41: How do I write testable javascript?

* 

Page 42: How do I write testable javascript?

* 

Page 43: How do I write testable javascript?

* <!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 44: How do I write testable javascript?

* 

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 45: How do I write testable javascript?

* 

Once Jasmine is installed in your project

$ Jasmine init

Page 46: How do I write testable javascript?

* Edit Jasmine.json to update Locations for Spec Files and Helper Files { "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ],

"helpers": [ "helpers/**/*.js" ] }

Page 47: How do I write testable javascript?

* $ Jasmine Started F Failures: 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 failure Finished in 0.009 seconds

Page 48: How do I write testable javascript?

* 

* 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 49: How do I write testable javascript?

* 

* Install Grunt npm install grunt

* Install Grunt – Jasmine npm install grunt-contrib-jasmine

* Install Grunt – Watch npm install grunt-contrib-watch

* Note: On Mac, I also needed to install Grunt CLI npm install –g grunt-cli

Page 50: How do I write testable javascript?

* // 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 51: How do I write testable javascript?

* 

// gruntfile.js part 2

watch: {

js: {

files: [

'js/*.js',

'specs/*.js',

],

tasks: ['jasmine:all']

}

}

});

Page 52: How do I write testable javascript?

* 

// gruntfile.js part 3

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

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

};

Page 53: How do I write testable javascript?

* 

describe("A suite", function() {

it("contains spec with an expectation", function() {

expect(true).toBe(true);

});

});

Page 54: How do I write testable javascript?

* 

Page 55: How do I write testable javascript?

* 

Page 56: How do I write testable javascript?

* * 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 57: How do I write testable javascript?

* 

Page 58: How do I write testable javascript?

* * Any questions?

* Come check out my Cordova Hooks session and see how you can run Unit Tests (and much more) whenever you’re preparing a build for your cordova app.