Top Banner
Intro To Unit Testing In AngularJS
53

Intro to Unit Testing in AngularJS

Apr 11, 2017

Download

Software

Jim Lynch
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Intro to Unit Testing in AngularJS

Intro To Unit Testing In AngularJS

Page 2: Intro to Unit Testing in AngularJS

Jim LynchFront-End Engineer at Altered Image

twitter.com/webWhizJim

Slides available here: http://www.slideshare.net/JimLynch22/intro-to-unit-testing-in-angularjs

Page 3: Intro to Unit Testing in AngularJS

Who is This Talk For?

• People interested in unit testing.

• AngularJS developers.

• Front-End developers.

Page 4: Intro to Unit Testing in AngularJS

Why Test?• To prevent regression (recurring bugs).

• Catches bugs before end users see them.

• Removes fear from refactoring.

• Much quicker and less error-prone than manual testing.

• Can be a form of documentation for your code.

Page 5: Intro to Unit Testing in AngularJS

If You Don’t Test…

WRITE UNIT TESTS!!

Page 6: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Page 7: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Suite

Page 8: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Case

Test Case

Test Suite

Page 9: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Case

Assertion

Assertion

AssertionTest Case

Test Suite

Page 10: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Suite

• A collection of independent tests.

• Usually exists as its own file.

• Contains methods for setting up for and tearing down unit tests.

Test Case

Assertion

Assertion

AssertionTest Case

Test Suite

Page 11: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Case

• Tests a single “piece” of your application independent of the other code.

• A function that can either pass or fail.

• Each case should test a different “situation” from the user’s perspective (BDD).

Test Case

Assertion

Assertion

AssertionTest Case

Test Suite

Page 12: Intro to Unit Testing in AngularJS

Anatomy of a Test Suite

Test Case

Assertion

Assertion

AssertionTest Case

Test Suite

Assertion

• Uses a matcher API for comparing values eg. expected(var).toEqual(5)

• Tells the test case when it should pass and when it should fail.

• If output values for SUT (system under test) are as expected from known input then behavior of SUT is as expected.

Page 13: Intro to Unit Testing in AngularJS

Unit testing in JavaScript

uses a peculiar syntax…

Page 14: Intro to Unit Testing in AngularJS

If you are ever feeling lost,

just remember that a test

suite in JavaScript is this:

Page 15: Intro to Unit Testing in AngularJS

A describefull of it’s

with some beforeEach’s

Page 16: Intro to Unit Testing in AngularJS

Test Suite Anatomy for JS Testing Frameworks

it

describeTest Suite

Test CaseAssertion expect

itexpect

expect

Page 17: Intro to Unit Testing in AngularJS

Building Your First Test Suite• A test suite is simply a Javascript file.• Karma will automatically consider *.spec.js

files to be test suites.

Step 1) Create an empty *.spec.js file.

Page 18: Intro to Unit Testing in AngularJS

describe describe(‘MyController’, function() {

})

Building Your First Test SuiteAdding a describe.

Page 19: Intro to Unit Testing in AngularJS

describe describe(‘MyController’, function() {

})

A name for your test suite (can be anything, but it should describe what you are testing!).

Building Your First Test SuiteAdding a describe.

Page 20: Intro to Unit Testing in AngularJS

describe describe(‘MyController’, function() {

})

A function that takes no arguments. This creates the “wrapper” around your test

cases.

Building Your First Test SuiteAdding a describe.

Page 21: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an it.

Page 22: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

Some text that describes the purpose of this test case. Can be anything but usually begins with

the word should.

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an it.

Page 23: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

A function that takes no arguments. The code for this test case is contained in this

function.

Adding an it.

Page 24: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an assertion.

expectexpect(true).toEqual(true);

Page 25: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an assertion.

expectexpect(true).toEqual(true);

The expect keyword lets the test case know that we want to

do an assertion here.

Page 26: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an assertion.

expectexpect(true).toEqual(true);

The expect method takes one argument: the variable whose

value you wish to check.

Page 27: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an assertion.

expectexpect(true).toEqual(true);

Depending on how you wish to compare the two values, a matcher method is chained onto the end of the expect.

Page 28: Intro to Unit Testing in AngularJS

describedescribe(‘MyController’, function() {

})

it

Building Your First Test Suite

it(‘Should do something…’, function() {

});

Adding an assertion.

expectexpect(true).toEqual(true);

The matcher method takes one argument: the expected value for the variable being passed

into the expect method.

Page 29: Intro to Unit Testing in AngularJS

Building Your First Test SuiteYou did it!

describe(‘MyController’, function() {

})

it(‘Should do something…’, function() {

});expect(true).toEqual(true);

Ahhh, so a test suite is really just…

Page 30: Intro to Unit Testing in AngularJS

A describefull of it’s!

…with some beforeEach’s.

Page 31: Intro to Unit Testing in AngularJS

beforeEach

• Goes inside the describe but outside of the it’s.

describe

itexpect

itexpect

beforeEach

beforeEach

• Gives you access to your module, controllers, services, etc. through DI.

Page 32: Intro to Unit Testing in AngularJS

beforeEach

describe(‘MyController’, function() {

})

it(‘Should do something…’, function() {

});expect(true).toEqual(true);

beforeEach(module(‘YOUR_MODULE’));

Page 33: Intro to Unit Testing in AngularJS

beforeEach

beforeEach(module(‘YOUR_MODULE’));

Keyword that runs argument before every it.

Page 34: Intro to Unit Testing in AngularJS

beforeEach

beforeEach(module(‘YOUR_MODULE’));

Allows you to load in your module so that you have

access to it’s controllers, services, filters, etc.

Page 35: Intro to Unit Testing in AngularJS

beforeEach

beforeEach(module(‘YOUR_MODULE’));

Replace this with the name of your project’s module.

Page 36: Intro to Unit Testing in AngularJS

Injecting a Controller with beforeEach

describe(‘MyController’, function() {

})

it(‘Should do something…’, function() {

});expect(true).toEqual(true);

beforeEach(module(‘YOUR_MODULE’));

var myController = $controller('MyController', {})

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

Page 37: Intro to Unit Testing in AngularJS

Injecting a Controller with beforeEach

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

A method from the angular-mocks.js file that allows you to

inject services into your unit tests.

Page 38: Intro to Unit Testing in AngularJS

Injecting a Controller with beforeEach

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

Angular knows to “unwrap”, the underscores, find corresponding provider, and give you a

reference to the service.

Q. But what’s the deal with those underscores on either side?

Page 39: Intro to Unit Testing in AngularJS

Injecting a Controller with beforeEach

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

Angular knows to “unwrap”, the underscores, find corresponding provider, and give you a

reference to the service.

Suppose you didn’t use the underscores. You want to set a variable named $controller available inside of your “it’s” equal to the function’s argument, but

the function argument must be named $controller in order to be injected properly. Doing this is not possible in JavaScript so the Angular team

implemented the underscore notation to work around the issue.

Page 40: Intro to Unit Testing in AngularJS

Injecting a Controller with beforeEach

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

You can then use this global reference anywhere in the test suite

to instantiate controllers.

Page 41: Intro to Unit Testing in AngularJS

Using the Injected Controller

var myController = $controller('MyController', {})

This var has all of the properties and methods you defined for the

specified controller.

Page 42: Intro to Unit Testing in AngularJS

Using the Injected Controller

var myController = $controller('MyController', {})

This is the global $controller variable that was set in the

beforeEach.

Page 43: Intro to Unit Testing in AngularJS

Using the Injected Controller

var myController = $controller('MyController', {})

Replace this with the name of the controller you want

to instantiate.

Page 44: Intro to Unit Testing in AngularJS

Pass in any arguments to your controller with this object.

var myController = $controller('MyController', {})

Using the Injected Controller

Page 45: Intro to Unit Testing in AngularJS

The Complete Suite

describe(‘MyController’, function() {

})

it(‘Should do something…’, function() {

});expect(true).toEqual(true);

beforeEach(module(‘YOUR_MODULE’));

var myController = $controller('MyController', {})

beforeEach(inject(function(_$controller_) { $controller = _$controller_; }));

A good start to a nice looking test suite:

Page 46: Intro to Unit Testing in AngularJS

Okay, so how do I run these test suites?

Q )

Karma A )

Page 47: Intro to Unit Testing in AngularJS

Fun Facts About Karma

• Created at Google- now open source.

• It’s a command line test runner.

• Integrates with practically all CI tools.

• Runs tests on all browsers (even PhantomJS).

Page 48: Intro to Unit Testing in AngularJS

How Does Karma Work?

• It integrates nicely with Gulp and Grunt (gulp test) or runs on its own (karma start).

• It’s installed from npm: npm install karma

• The karma.conf.js file allows you to configure it to run with your desired settings.

• It automatically sees *.spec.js files in your project folder as test suites.

Page 49: Intro to Unit Testing in AngularJS

How do I add Karma to My Project?

Page 50: Intro to Unit Testing in AngularJS

Easy Way Hard(er) WayUse a yeoman generator to

scaffold a project that already has karma set up for you

(such as the Gulp-Angular generator).

Install and configure it manually.

karma-runner.github.io

Adding Karma to Your Project

And then you’re ready to start testing!

Page 51: Intro to Unit Testing in AngularJS

All together now!

A JavaScript test suite is:

Page 52: Intro to Unit Testing in AngularJS

A describefull of it’s

with some beforeEach’s

Page 53: Intro to Unit Testing in AngularJS

Thanks!twitter.com/webWhizJim

[email protected]

https://www.teepublic.com/t-shirt/468156-describes-full-of-its-white-text

www.wisdomofjim.com

The official “Describe’s Full of It’s” T-Shirt! Available now!

Slides available here: http://www.slideshare.net/JimLynch22/intro-to-unit-

testing-in-angularjs