35
IN SEARCH OF JAVASCRIPT CODE QUALITY: UNIT TESTING WHY? HOW? WHAT?

In search of JavaScript code quality: unit testing

Embed Size (px)

Citation preview

Page 1: In search of JavaScript code quality: unit testing

IN S

EARCH OF

JAVA

SCRIPT

CODE QUALIT

Y: UNIT

TESTI

NG

WH

Y ? HO

W? W

HAT ?

Page 2: In search of JavaScript code quality: unit testing

AGENDA

Unit Testing Concept

Why Unit Testing?

Test Driven Development (a.k.a. TDD)

Basic Terms & Structure

Tools & Libraries

Unit Testing Specifics in JavaScript

Best Practices

Page 3: In search of JavaScript code quality: unit testing

UNIT T

ESTING C

ONCEPT

Page 4: In search of JavaScript code quality: unit testing

UNIT TESTING CONCEPT

Unit is the smallest testable piece of code.

Unit testing is a method by which individual units of source codeare tested to determine if they are fit for use.

Unit tests are created by programmers.

Page 5: In search of JavaScript code quality: unit testing

WHY

UNIT T

ESTING?

Page 6: In search of JavaScript code quality: unit testing

COMMON SENSE OR WHY UNIT TESTING?

Unit tests find problems early in the development cycle (TDD & BDD)

RefactoringIntegration

DocumentationBetter design

Page 7: In search of JavaScript code quality: unit testing

IS UNIT TESTING A GOOD INVESTMENT?

Might slow down the development process.

The tests may share the same blind spots with the code.

Proving that components X and Y both work independently doesn’t prove that they’re compatible with one another or configured correctly.

Page 8: In search of JavaScript code quality: unit testing

TEST

DRIVEN

DEVELOPM

ENT

TD

D

Page 9: In search of JavaScript code quality: unit testing

TEST DRIVEN DEVELOPMENT(TDD)

Test-driven development is related to the test-first programming concepts of extreme programming (XP).

TDD is a software development process that relies on the repetition of short development cycle shown on the screen to the left.

Behavior-driven development(BDD) based on TDD…

Page 10: In search of JavaScript code quality: unit testing

ALRIGHT, SO WHAT IS BDD YOU ASK?

Behavior-driven development (BDD) isn't anything new or revolutionary. It's just TDD with any test-related terminology replaced by examples-of-behavior-related terminology:

TDD term BDD term

Test Example

Assertion Expectation

assert should, expect

Unit Behavior

Verification Specification

Page 11: In search of JavaScript code quality: unit testing

BASIC T

ERMS

AS

SE

RT

I ON

, F I X

TU

RE

, M

OC

K, S

TU

B,

SP Y

Page 12: In search of JavaScript code quality: unit testing

ASSERTION

In simple words, the goal of assertion is to forcefully define if the test fails or passes.

Example #1:

Statement Passes(True) Fails(False)

x = 1; assert (x > 0) assert (x < 0)

x++; assert (x > 1) assert (x < 1)

Page 13: In search of JavaScript code quality: unit testing

ASSERTION: EXAMPLE

Example(Chai) #2:

Given the function initialize():

function initialize() {

//… Some code goes here …

// The initialization went successfully.

return true;

}

Check that function initialize() returns true when called.

var isInitialized = initialize();

TDD syntax BDD syntax

assert.isTrue(isInitialized) expect(isInitialized).to.be.true

Page 14: In search of JavaScript code quality: unit testing

FIXTURE

A test fixture is a fixed state of the software under test used as a baseline for running tests.

In JavaScript: simulate AJAX responses; loading known set of data, such as html objects.

Example(Jasmine):

Require the piece of markup stored in myfixturemarkup.html file before each test:

beforeEach(function() {

loadFixtures('myfixturemarkup.html');

});

Page 15: In search of JavaScript code quality: unit testing

STUB

Method stubs are functions with pre-programmed behavior.

Example (Sinon):

Forcing a method to throw an error in order to test error handling.

var fn = foo.stub().throws(Error);

expect(fn).to.throw(Error);

Page 16: In search of JavaScript code quality: unit testing

SPY

A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls.

Example(Sinon):

Test that a function cursor.hide() has been only called once, and only once.

sinon.spy(cursor, "hide");

TDD

sinon.assert.calledOnce(cursor.hide)

BDD

expect(cursor.hide.calledOnce).to.be.true

Page 17: In search of JavaScript code quality: unit testing

MOCK

Mocks are fake objects with pre-programmed behavior (like stubs) and pre-programmed expectations. They are like both stubs and spies – in one.

Mocks isolate the imitate the dependency and thus isolate the unit test.

Page 18: In search of JavaScript code quality: unit testing

MOCK: EXAMPLEExample(Sinon):

Create an expectation that jQuery.each is called once, and only once, and also instructs the mock to behave as we pre-define.

var mock = sinon.mock(jQuery);

#1 – which method?(“jQuery.each”)

#2 – how many times it is called?(only once)

#3 – what are the arguments when the method called? (1, {})

#4 – what the method returns? (empty object)

Page 19: In search of JavaScript code quality: unit testing

BASIC S

TRUCTU

RE

I N E

NG

L I SH

AN

D I

N J

AV

AS

CR

I PT

Page 20: In search of JavaScript code quality: unit testing

BASIC STRUCTURE

#1. Setup/BeforeEach/Before

#2. Prepare an input

#3. Call a method

#4. Check an output

#5. Tear down/AfterEach/After

Page 21: In search of JavaScript code quality: unit testing

BASIC STRUCTURE EXPLAINED

#1. Setup/BeforeEach/Before.

before(function(done) {

// Create a basic document.

document = jsdom.jsdom();

window = document.parentWindow;

done();

});

Page 22: In search of JavaScript code quality: unit testing

BASIC STRUCTURE EXPLAINED

before(function() { console.log(‘before test’); });

test(‘first test', function() { console.log(‘first test’); });

test(‘second test', function() { console.log(‘second test’); });

afterEach(function() { console.log(‘after each test’); });

Result:

before test

first test

after each test

second test

after each test

Page 23: In search of JavaScript code quality: unit testing

BASIC STRUCTURE EXPLAINED

it('should not initialize cursor if zoom level <= minimum zoom level.',

function(done) {

#2. Prepare an input and predicted result.

var zoomLevel = 1;

var expectedCursor = {‘color’: ‘white’, ‘height’: ‘32px’, etc…};

#3. Call a method.

var actualCursor = cursor.init(zoomLevel);

#4. Check an output.

expect(actualCursor).to.deep.equal(expectedCursor);

done();

});

Page 24: In search of JavaScript code quality: unit testing

BASIC STRUCTURE EXPLAINED

#5. Tear down/AfterEach/After.

after(function(done) {

// Remove global objects document.

document = null;

window = null;

done();

});

Page 25: In search of JavaScript code quality: unit testing

OUTPUT

Page 26: In search of JavaScript code quality: unit testing

OUTPUT: SUCCESS

<testsuite name="Macchiato Tests" tests="13" failures="0" errors="0" skipped="0" timestamp="Mon, 02 Dec 2013 11:08:09 GMT" time="0.114">

<testcase classname=“cursor #init ()" name="should not

initialize cursor if zoom level &lt; minimum

zoom level.”

time="0.004"/>

</testsuite>

Page 27: In search of JavaScript code quality: unit testing

OUTPUT: FAILURE

<failure classname="cursor #init()" name="should not initialize cursor if zoom level &lt; minimum zoom level." time="0" message="Cannot read property 'show' of undefined"><![CDATA[TypeError: Cannot read property 'show' of undefined

// ..... Exception Stack Trace .....

</failure>

Page 28: In search of JavaScript code quality: unit testing

TOOLS

Page 29: In search of JavaScript code quality: unit testing

TOOLS

No framework

Known frameworks: qUnit(TDD) Jasmine(BDD) Mocha+ Chai(TDD & BDD)+ Sinon Etc…

Page 30: In search of JavaScript code quality: unit testing

TOOLS

What we use:

Run UT: Mocha Run UT in parallel: Macchiato Assert/Expect: Chai W3C DOM in JavaScript: Jsdom Mock, spy, stub: Sinon Code coverage tool: None

Page 31: In search of JavaScript code quality: unit testing

UNIT T

ESTING S

PECIFI

CS

IN JA

VASCRIP

T

DO

M,

AJ A

X,

3R

D - P AR

TY

LI B

RA

RI E

S

Page 32: In search of JavaScript code quality: unit testing

UNIT TESTING SPECIFICS IN JAVASCRIPTStubbing jQuery plugin functions(mock jQuery.fn)

Testing Ajax requests

Stub jQuery.ajax

Fake XMLHttpRequest(XMLHTTP ActiveXObject)

Fake server

Mocking DOM elements

Load fake data via “fixtures”

Use W3C Javascript implementation Jsdom

Page 33: In search of JavaScript code quality: unit testing

BEST PR

ACTICES

Page 34: In search of JavaScript code quality: unit testing

BEST PRACTICES

Fast

Isolated

Consistent

Responsibility

Self-descriptive

No exception Handling

Use assertions when needed

Page 35: In search of JavaScript code quality: unit testing

THANK YO

U

About m

e & C

onta

cts

http://da-14.com/

akhabibullina

_khabibullina

ua.linkedin.com/pub/anna-khabibullina/38/566/463/

Senior Frontend Developer at GlobalLogicCo-founder of IT company DA-14Contributor of HoganJs, Backbone.Validations