javascript unit testing

21
Unit Testing JavaScript Keir Bowden CTO, BrightGen @bob_buzzard Unit Tests – They’re not just for Apex

Upload: keir-bowden

Post on 14-Apr-2017

440 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: JavaScript Unit Testing

Unit Testing JavaScript

Keir Bowden CTO, BrightGen @bob_buzzard

Unit Tests – They’re not just for Apex

Page 2: JavaScript Unit Testing

• Introduction

• Tools

• Visualforce

• Lightning Components

• Q & A

What we’ll cover

Page 3: JavaScript Unit Testing

Introduction

Page 4: JavaScript Unit Testing

Why write unit tests

• Give confidence

• Reduce cost of bugs

• Produce testable code

• Promote refactoring

Introduction

Page 5: JavaScript Unit Testing

No test context for client

• Changes aren’t rolled back

Side effects

• DOM manipulation

• Server calls

ChallengesJavaScript on Salesforce

Page 6: JavaScript Unit Testing

Unobtrusive JavaScript

Avoid anonymous functions

Functional decomposition

• Function to decide on action

• Function to take the action

Writing Testable Code

function redirectToURL(url) { if (“#”===url.charAt(0)) { window.location.hash=url; } else if (“/”===url.charAt(0)) window.location.pathname=url; }....

Page 7: JavaScript Unit Testing

Github: bobbuzz.me.uk/JSUTSF

Public Site

• Jobs:

• bobbuzz.me.uk/1Ad25OG

• Tests:

• bobbuzz.me.uk/1PvhII3

Demo App

Page 8: JavaScript Unit Testing

Tools

Page 9: JavaScript Unit Testing

Pure JavaScript Unit Test Framework

Executes in-browser

From the developers of jQuery

QUnit

<apex:includeScript value="{!$Resource.qunitJS}"/>

<apex:stylesheet value="{!$Resource.qunitCSS}"/>

<div id="qunit"></div><div id="qunit-fixture"></div>

Test markup container

Page 10: JavaScript Unit Testing

Module – group of tests

Test – single test

Assert – confirm behaviour

ConceptsQUnit

QUnit.module("JOBLIST", {beforeEach: function(assert) {

// setup code},

afterEach : function(assert) {// teardown code

}});

QUnit.test("Show Progress", function( assert ) { jobCtrl.showProgress(); });

assert.equal(jobCtrl.progressCount, 1, "Progress count is one");

Page 11: JavaScript Unit Testing

Pure JavaScript

Works with any test framework

Three key concepts

• Spies – records execution, parameters

• Stubs – Spies + replace functions

• Mocks – Stubs + expected behaviour

Sinon.JS

Page 12: JavaScript Unit Testing

Sinon Stub

this.searchStub = sinon.stub(jobCtrl, "doSearch");

var jobCtrl={ doSearch : function(ev) {

// remote call to server }};

jobCtrl.doSearch(event);doSearch : function() {

// sinon stub code}

assert.equal(this.searchStub.callCount,1, "search called once");

this.searchStub.restore();

doSearch : function(ev) {// remote call to server

}

$('#searchbtn').on("click", jobCtrl.doSearch);

Page 13: JavaScript Unit Testing

Code coverage!

Pure JavaScript

Works with QUnit, Mocha and Jasmine

JavaScript must be external

Blanket.JS

<apex:includeScript value="{!$Resource.blanketJS}"/>

<script src="{!$Resource.JobsJS}" data-cover="true"></script>

Page 14: JavaScript Unit Testing

Blanket.JS

Page 15: JavaScript Unit Testing

Visualforce

Page 16: JavaScript Unit Testing

Dedicated test page

Replicate markup as required

Include JavaScript to be tested

Can capture coverage

Demo

Visualforce

Page 17: JavaScript Unit Testing

Lightning Components

Page 18: JavaScript Unit Testing

Components are isolated

JavaScript in controller + helper

Cannot capture coverage

Markup is fixed

How to trigger tests?

ChallengesLightning Components

Page 19: JavaScript Unit Testing

Qunit tests in helper function

• Controller method to execute helper function

Lightning test application (page equivalent)

Tests executed via event

• Fired by application

• Handled by component under test

Demo

My Solution!Lightning Components

Page 20: JavaScript Unit Testing

Unobtrusive JavaScript

Functional decomposition

Avoid anonymous functions

No client-side test contextStubs are your best friend

Takeaways

Page 21: JavaScript Unit Testing

Q & A

Keir Bowden CTO, BrightGen @bob_buzzard