javascript tdd with jasmine, karma, and gulp

38
JavaScript TDD with Jasmine, Karma, and Gulp All Things Open 2015 Jason Krol 1 / 38

Upload: all-things-open

Post on 21-Jan-2017

1.262 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Javascript TDD with Jasmine, Karma, and Gulp

JavaScript TDD with

Jasmine, Karma, and Gulp

All Things Open 2015

Jason Krol

1 / 38

Page 2: Javascript TDD with Jasmine, Karma, and Gulp

About Me

Jason Krol

! " ShortTompkins# Kroltech.com

Currently working at:

Dad, Author, Gamer, Geek!

http://ShortTompkins.JS.org

2 / 38

Page 3: Javascript TDD with Jasmine, Karma, and Gulp

Why should we test?

Google is 2 Billion lines of code!1

Acts as a kind of guarantee

Built-in code documentation!

Testing can be fun?!

3 / 38

Page 4: Javascript TDD with Jasmine, Karma, and Gulp

Why we probably aren't

Roughly 50% of FE devs aren't testing2

Its time consuming

It can be tedious and difficult

Where to start?!

4 / 38

Page 5: Javascript TDD with Jasmine, Karma, and Gulp

Tools of the Trade

Jasmine (test/assertion library/framework)

Others: Mocha, Chai, QUnit, et al

Karma (test runner)

Gulp (task runner)

Others: Grunt, Brocolli, npm, make, et al

Requires node.js and npm installed locally

5 / 38

Page 6: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

6 / 38

Page 7: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

Suites, specs, assertions, spies, mocks, stubs,

wtf?!

7 / 38

Page 8: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

Suites, specs, assertions, spies, mocks, stubs,

wtf?!

Describe a piece of code / functionality

being tested

8 / 38

Page 9: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

Suites, specs, assertions, spies, mocks, stubs,

wtf?!

Describe a piece of code / functionality

being tested

Define setup work before and/or after

every test

9 / 38

Page 10: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

Suites, specs, assertions, spies, mocks, stubs,

wtf?!

Describe a piece of code / functionality

being tested

Define setup work before and/or after

every test

It should do exactly what you expect (all

possible scenarios!)

10 / 38

Page 11: Javascript TDD with Jasmine, Karma, and Gulp

Test Driven Development Crash Course

Suites, specs, assertions, spies, mocks, stubs,

wtf?!

Describe a piece of code / functionality

being tested

Define setup work before and/or after

every test

It should do exactly what you expect (all

possible scenarios!)

Thats it!

11 / 38

Page 12: Javascript TDD with Jasmine, Karma, and Gulp

Describe

describe('Description/Label', function(){

});

Typically a single word description/label

Can be nested (and very well should be)

12 / 38

Page 13: Javascript TDD with Jasmine, Karma, and Gulp

beforeEach/afterEach

describe('Description/Label', function(){

beforeEach(function(){ // do some work before every test });

afterEach(function(){ // do some cleanup/resets after });

});

13 / 38

Page 14: Javascript TDD with Jasmine, Karma, and Gulp

it

describe('Description/Label', function(){ beforeEach(function(){ ... });

it('should do something...', function(){

});

it('should also...', function(){

});

});

14 / 38

Page 15: Javascript TDD with Jasmine, Karma, and Gulp

expect & matchers

describe('Sum', function(){

it('should sum 2 numbers', function(){ expect(sum(1, 1)).toEqual(2); expect(sum(3, 2)).toEqual(5); expect(sum(5, 5)).not.toEqual(99); });

});

15 / 38

Page 16: Javascript TDD with Jasmine, Karma, and Gulp

Some common matchers:

toBe, toEqual, toMatch, toBeDefined,

toBeUndefinedtoBeTruthy, toBeFalsytoContain, toBeGreaterThan, toBeLessThanCan be chained with .not

not.toBeDefined(), not.toEqual(0)Specials:

jasmine.any([Function, Number, String])jasmine.anything()

16 / 38

Page 17: Javascript TDD with Jasmine, Karma, and Gulp

Spies

17 / 38

Page 18: Javascript TDD with Jasmine, Karma, and Gulp

Spies

spyOn(object, 'functionToSpyOn')jasmine.createSpy('nameOfSpy')

Control spy's behavior:

.and.callThrough()

.and.returnValue(newValue)

.and.callFake(function(){ ... })

Matchers:

.toHaveBeenCalled(),

.toHaveBeenCalledWith(params)

18 / 38

Page 19: Javascript TDD with Jasmine, Karma, and Gulp

spyOn

describe('Sum', function(){ beforeEach(function() { spyOn(window, 'alert'); });

it('should alert the sum', function (){ sum(1, 1); expect(window.alert) .toHaveBeenCalledWith(2); });});

19 / 38

Page 20: Javascript TDD with Jasmine, Karma, and Gulp

jasmine.createSpy

describe('window.setTimeout', function(){ var cbSpy; beforeEach(function() { cbSpy = jasmine.createSpy('cbSpy'); setTimeout(cbSpy, 0); });

it('should execute callback', function (){ expect(cbSpy).toHaveBeenCalled(); expect(cbSpy).calls.count()).toBe(1); });});

20 / 38

Page 21: Javascript TDD with Jasmine, Karma, and Gulp

Create a quick project

$ mkdir -p jstdd/src/js && cd jstdd$ touch src/js/sample.js$ touch src/js/sample_tests.js

21 / 38

Page 22: Javascript TDD with Jasmine, Karma, and Gulp

File contents:

// sample.js:function sum(a, b) { window.alert(a + b); return a + b;}

22 / 38

Page 23: Javascript TDD with Jasmine, Karma, and Gulp

// sample_tests.js:describe('Sample', function(){ beforeEach(function () { spyOn(window, 'alert'); }); it('should sum 2 numbers', function(){ expect(sum(1,1)).toEqual(2); }); it('should alert the value', function(){ sum(2, 2); expect(window.alert) .toHaveBeenCalledWith(4); });});

23 / 38

Page 24: Javascript TDD with Jasmine, Karma, and Gulp

Setup our Dev Environment

First, install Karma's CLI as a global package:

$ sudo npm install -g karma-cli phantomjs

24 / 38

Page 25: Javascript TDD with Jasmine, Karma, and Gulp

Setup our Dev Environment

First, install Karma's CLI as a global package:

$ sudo npm install -g karma-cli phantomjs

Initialize our project:

$ npm init -y

25 / 38

Page 26: Javascript TDD with Jasmine, Karma, and Gulp

Setup our Dev Environment

First, install Karma's CLI as a global package:

$ sudo npm install -g karma-cli phantomjs

Initialize our project:

$ npm init -y

Locally install karma for the project:

$ npm install --save-dev karma

26 / 38

Page 27: Javascript TDD with Jasmine, Karma, and Gulp

Initialize Karma for the project:

$ karma init

jasmine

no (Require.js)

PhantomJS

src/js/**/*.jsno exclusions

yes (watch for changes)

27 / 38

Page 28: Javascript TDD with Jasmine, Karma, and Gulp

Run our first tests!

$ karma start17 09 2015 22:10:09.116:WARN [karma]: No captured browser, open http://localhost:17 09 2015 22:10:09.128:INFO [karma]: Karma v0.17 09 2015 22:10:09.132:INFO [launcher]: Starting browser PhantomJS17 09 2015 22:10:10.064:INFO [PhantomJS 1.9.PhantomJS 1.9.8: Executed 2 of 2 SUCCESS (0.003|

28 / 38

Page 29: Javascript TDD with Jasmine, Karma, and Gulp

Introducing Gulp

Why do we need an automated build tool?

29 / 38

Page 30: Javascript TDD with Jasmine, Karma, and Gulp

Introducing Gulp

Why do we need an automated build tool?

Bundle/Minify our source code

Transpile CSS preprocessors like SASS

ES6 Transpiling (Babel)

Run tests!!

30 / 38

Page 31: Javascript TDD with Jasmine, Karma, and Gulp

Install Gulp

First, like Karma, globally install the Gulp CLI:

$ sudo npm install -g gulp

31 / 38

Page 32: Javascript TDD with Jasmine, Karma, and Gulp

Install Gulp

First, like Karma, globally install the Gulp CLI:

$ sudo npm install -g gulp

Locally install gulp and the gulp-karma plugin

for the project:

$ npm install --save-dev gulp gulp-karma

32 / 38

Page 33: Javascript TDD with Jasmine, Karma, and Gulp

Install Gulp

First, like Karma, globally install the Gulp CLI:

$ sudo npm install -g gulp

Locally install gulp and the gulp-karma plugin

for the project:

$ npm install --save-dev gulp gulp-karma

Create a gulpfile.js:

$ touch gulpfile.js

33 / 38

Page 34: Javascript TDD with Jasmine, Karma, and Gulp

Gulpfile.js

// gulpfile.jsvar gulp = require('gulp'), karma = require('gulp-karma');

gulp.task('default', function() { gulp.src(['src/js/**/*.js']) .pipe(karma({ configFile: 'karma.conf.js', action: 'watch' }));});

34 / 38

Page 35: Javascript TDD with Jasmine, Karma, and Gulp

Run our first Gulp test task!

$ gulp[21:37:43] Using gulpfile ~/repos/jstdd/gulpfile.js[21:37:43] Starting 'default'...[21:37:43] Finished 'default' after 8.52 ms[21:37:43] Starting Karma server...17 09 2015 21:37:44.077:WARN [karma]: No captured browser, open http://localhost:17 09 2015 21:37:44.087:INFO [karma]: Karma v0.17 09 2015 21:37:44.093:INFO [launcher]: Starting browser PhantomJS17 09 2015 21:37:45.044:INFO [PhantomJS 1.9.PhantomJS 1.9.8: Executed 2 of 2 SUCCESS (0.003|

35 / 38

Page 36: Javascript TDD with Jasmine, Karma, and Gulp

Lets look at some real tests!

VideoPlayer.js & VideoPlayer_tests.js

Basic video player module

Uses jQuery

12 functions (100 lines)

46 tests (over 300 lines)

36 / 38

Page 37: Javascript TDD with Jasmine, Karma, and Gulp

Resources

Jasmine Docs: http://jasmine.github.io/

Karma: http://karma-runner.github.io/

Gulp: http://gulpjs.com/

Sources

1. http://www.wired.com/2015/09/google-2-

billion-lines-codeand-one-place/

2. http://ashleynolan.co.uk/blog/frontend-

tooling-survey-2015-results

37 / 38

Page 38: Javascript TDD with Jasmine, Karma, and Gulp

Start Testing!!

38 / 38