testing javascript applications

70
TESTING JAVASCRIPT APPLICATIONS by Alexander Gerasimov and Dmitrey Gerasimov

Upload: the-rolling-scopes

Post on 27-Jan-2015

393 views

Category:

Software


13 download

DESCRIPTION

Some brief overview of technologies and frameworks that are used for testing front-end and javascript.

TRANSCRIPT

Page 1: Testing JavaScript Applications

TESTING JAVASCRIPT APPLICATIONSby Alexander Gerasimov and Dmitrey Gerasimov

Page 2: Testing JavaScript Applications

¿POR QUÉ?

Page 3: Testing JavaScript Applications

¡PORQUE!refactoringorganization, modularization, extensibilitydocumentationdefect preventioncollaboration

Page 4: Testing JavaScript Applications

"Any feature without a test doesn’t exist"

Steve Loughran HP Laboratories

Page 5: Testing JavaScript Applications

TDD & BDD

Page 6: Testing JavaScript Applications

TESTS FIRST

Page 7: Testing JavaScript Applications

RED/GREEN/REFACTORRed: Write a failing test

Page 8: Testing JavaScript Applications

RED/GREEN/REFACTORGreen: Make it pass

Page 9: Testing JavaScript Applications

RED/GREEN/REFACTORRefactor: Eliminate redundancy

Page 10: Testing JavaScript Applications

STRUCTURESetup: Put the Unit Under Test (UUT) or the overall test system in the state needed

to run the test.

Execution: Trigger/drive the UUT to perform the target behavior and capture all

output, such as return values and output parameters.

Validation: Ensure the results of the test are correct.

Cleanup: Restore the UUT or the overall test system to the pre-test state.http://en.wikipedia.org/wiki/Test-driven_development#Test_structure

Page 11: Testing JavaScript Applications

TDD ASSERTIONSvar assert = chai.assert;assert.typeOf(foo, 'string');assert.equal(foo, 'bar');assert.lengthOf(foo, 3)assert.property(tea, 'favors');assert.lengthOf(tea.flavors, 3);

Page 12: Testing JavaScript Applications

BDDBehavior-driven development

Page 13: Testing JavaScript Applications

GIVEN-WHEN-THENStory: Returns go to stockIn order to keep track of stockAs a store ownerI want to add items back to stock when they're returned

Scenario 1: Refunded items should be returned to stockGiven a customer previously bought a black sweater from meAnd I currently have three black sweaters left in stockWhen he returns the sweater for a refundThen I should have four black sweaters in stock

Page 14: Testing JavaScript Applications

CUCUMBERFeature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two number

Scenario: Add two numbers Given I have entered 50 into the calculator And I have entered 70 into the calculator When I press add Then the result should be 120 on the screen

Page 15: Testing JavaScript Applications

CUCUMBER Given /I have entered (.*) into the calculator do calculator = new Calculator(); calculator.push(n); end

Page 16: Testing JavaScript Applications

EXPECTvar expect = require("chai").expect , foo = "bar" , beverages = { tea: [ "chai", "matcha", "oolong" ] };

expect(foo).to.be.a("string");expect(foo).to.equal("bar");expect(foo).to.have.length(3);expect(beverages).to.have.property("tea").with.length(3);

Page 17: Testing JavaScript Applications

SHOULDvar should = require("chai").should() , foo = "bar" , beverages = { tea: [ "chai", "matcha", "oolong" ] };

foo.should.be.a("string");foo.should.equal("bar");foo.should.have.length(3);beverages.should.have.property("tea").with.length(3);

Page 18: Testing JavaScript Applications

FUNCTIONAL TESTING

Page 19: Testing JavaScript Applications

UX/BEHAVIOR VERIFICATIONUnit tests just prove that your code doesn't work

Page 20: Testing JavaScript Applications

AUTOMATION & CONTROL

Page 21: Testing JavaScript Applications

METRICS & PROFILINGExecution timeLoading, rendering, paintingCPU & MemoryGoogle Chrome Metrics

Page 22: Testing JavaScript Applications

HELPS QA TESTERSWhy not let QA guys concentrate on quality rather than

routine?

Page 23: Testing JavaScript Applications

TOOLS & EXAMPLESgeneratorsframeworks[assertion] librariespluginsstat toolscomplex solutions + Grunt

Page 24: Testing JavaScript Applications

TECHNIQUES

Page 25: Testing JavaScript Applications

DUMMIES

Page 26: Testing JavaScript Applications

STUBS

Page 27: Testing JavaScript Applications

MOCKS

Page 28: Testing JavaScript Applications

SPIES

Page 29: Testing JavaScript Applications

FIXTURES

Page 30: Testing JavaScript Applications

JASMINE

Page 31: Testing JavaScript Applications

What is it?..

Page 32: Testing JavaScript Applications

JASMINESuites & specs

describe("A suite is just a function", function() { var a;

it("and so is a spec", function() { a = true;

expect(a).toBe(true); });});

Page 33: Testing JavaScript Applications

JASMINEMatchers

expect(x).toEqual(y);expect(x).toBe(y);expect(x).toMatch(pattern);expect(x).toBeDefined();expect(x).toBeUndefined();expect(x).toBeNull();expect(x).toBeTruthy();expect(x).toBeFalsy();expect(x).toContain(y);expect(x).toBeLessThan(y);expect(x).toBeGreaterThan(y);expect(function(){fn();}).toThrow(e);

Page 34: Testing JavaScript Applications

JASMINESpies

Page 35: Testing JavaScript Applications

SPIESTracks

Functions callsArgumentsNumber of calls

Page 36: Testing JavaScript Applications

SPIESAccess

All calls of functionEvery argument of every call

Page 37: Testing JavaScript Applications

SPIESCan

Track and delegateSubstitute returning valuesCall faked functionsCreate mock objects

Page 38: Testing JavaScript Applications

JASMINEAny

describe("jasmine.any", function() { it("matches any value", function() { expect({}).toEqual(jasmine.any(Object)); expect(12).toEqual(jasmine.any(Number)); });});

Page 39: Testing JavaScript Applications

JASMINEClock

beforeEach(function() { timerCallback = jasmine.createSpy("timerCallback"); //create spy jasmine.Clock.useMock(); //use wrepper of system timer});

it("causes a timeout to be called synchronously", function() { setTimeout(function() { timerCallback(); }, 100);

expect(timerCallback).not.toHaveBeenCalled(); jasmine.Clock.tick(101); //make time to go expect(timerCallback).toHaveBeenCalled();});

Page 40: Testing JavaScript Applications

JASMINEAsync

It exists, but...

Page 41: Testing JavaScript Applications

JASMINEReporter

Page 42: Testing JavaScript Applications

describe("Jasmine", function() { it("makes testing JavaScript awesome!", function() { expect (yourCode).toBeLotsBetter(); });});

Page 43: Testing JavaScript Applications

MOCHA['mɔkə]

Page 44: Testing JavaScript Applications

MOCHASupports TDD assertions and BDD should/expectReporting & CI integrationJavaScript APIBrowser Test Runner

Page 45: Testing JavaScript Applications

MOCHAdescribe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); [1,2,3].indexOf(0).should.equal(-1); }) })})

Page 46: Testing JavaScript Applications

MOCHAdescribe('User', function(){ describe('#save()', function(){ it('should save without error', function(done){ var user = new User('Luna'); user.save(function(err){ if (err) throw err; done(); }); }) })})

Page 47: Testing JavaScript Applications

MOCHAHooks: before(), after(), beforeEach(), afterEach()

beforeEach(function(done){db.clear(function(err){ if (err) return done(err); db.save([tobi, loki, jane], done); });})

Page 48: Testing JavaScript Applications

MOCHA

Page 49: Testing JavaScript Applications

MOCHAConsole reporter

Page 50: Testing JavaScript Applications

MOCHAHTML reporter

Page 51: Testing JavaScript Applications

MOCHANyan reporter

Page 52: Testing JavaScript Applications

CHAI

Page 53: Testing JavaScript Applications

CHAIAssert, expect/should

chai.should();foo.should.be.a('string');foo.should.equal('bar');foo.should.have.length(3);tea.should.have.property('flavors') .with.length(3);

Page 54: Testing JavaScript Applications

QUESTION TIME!How would you test an RNG?

Page 55: Testing JavaScript Applications

CHAIPlugins

here

Page 57: Testing JavaScript Applications

CASPERJSvar casper = require('casper').create();

casper.start('http://domain.tld/page.html', function() { if (this.exists('h1.page-title')) { this.echo('the heading exists'); }});

casper.run();

Page 58: Testing JavaScript Applications

QUESTION TIME!What happens if not everyone on the team adopts TDD/BDD?

Page 59: Testing JavaScript Applications

CODE COVERAGE

Page 60: Testing JavaScript Applications

INSTRUMENTATION

Page 61: Testing JavaScript Applications

INSTRUMENTATION

Page 62: Testing JavaScript Applications
Page 63: Testing JavaScript Applications

ISTANBULStatement, branch, and function coverageTest running toolsHTML & LCOV reportingesprima-based

Page 64: Testing JavaScript Applications

TESTING + CI = ❤fail buildsstatistics & reportingGithub is integration paradise

Page 65: Testing JavaScript Applications

GITHUB IS INTEGRATION PARADISE

Page 66: Testing JavaScript Applications

IRL, 100% COVERAGE IS A LIElegacy & untestable codepermissive testsnot applicable to functional testing

Page 67: Testing JavaScript Applications

MUTATION TESTINGWho tests tests?Coverage is paramount! (it isn't)Mutations: remove lines, alter operators, rename identifiersThe Future of Unit Testing

Page 68: Testing JavaScript Applications

QUESTION TIME!What do you do when you're offerred a project without TDD?

Page 69: Testing JavaScript Applications

YOU RUN LIKE HELL

Page 70: Testing JavaScript Applications

THE END