Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automated Tests for AngularJS

Automated Tests for AngularJS

A short introduction into TDD in AngularJS applications, showing how to run unit and e2e tests (Inaka Lighting Talks)

Flávio Granero

May 15, 2015
Tweet

More Decks by Flávio Granero

Other Decks in Technology

Transcript

  1. • Open Source JavaScript Framework! • Single Page Applications (SPA)!

    • Extends HTML with Directives! • Two-way data binding! • Concepts: Controllers, Services, Factories, …
  2. describe('Unit: AuthToken', function() {! var service;! ! beforeEach(function() {! //

    instantiate the app module! angular.mock.module('app');! // mock the service! angular.mock.inject(function(authToken, $window) {! service = authToken;! });! });! ! it('should exist', function() {! expect(service).toBeDefined();! });! ! it('stores and retrieve a token', function() {! service.setToken('token_value');! expect(service.getToken()).toBe('token_value');! });! });!
  3. describe('Unit: AuthToken', function() {! var service;! ! beforeEach(function() {! //

    instantiate the app module! angular.mock.module('app');! // mock the service! angular.mock.inject(function(authToken, $window) {! service = authToken;! });! });! ! it('should exist', function() {! expect(service).toBeDefined();! });! ! it('stores and retrieve a token', function() {! service.setToken('token_value');! expect(service.getToken()).toBe('token_value');! });! });!
  4. describe('Unit: AuthToken', function() {! var service;! ! beforeEach(function() {! //

    instantiate the app module! angular.mock.module('app');! // mock the service! angular.mock.inject(function(authToken) {! service = authToken;! });! });! ! it('should exist', function() {! expect(service).toBeDefined();! });! ! it('stores and retrieve a token', function() {! service.setToken('token_value');! expect(service.getToken()).toBe('token_value');! });! });!
  5. describe('Unit: AuthToken', function() {! var service;! ! beforeEach(function() {! //

    instantiate the app module! angular.mock.module('app');! // mock the service! angular.mock.inject(function(authToken, $window) {! service = authToken;! });! });! ! it('should exist', function() {! expect(service).toBeDefined();! });! ! it('stores and retrieves a token', function() {! service.setToken('token_value');! expect(service.getToken()).toBe('token_value');! });! });!
  6. $ gulp unit [19:02:02] Using gulpfile ~/Sites/project/gulpfile.js [19:02:02] Starting 'unit'...

    [19:02:02] Starting Karma server... INFO [karma]: Karma v0.12.31 server started at http://localhost: 9876/__karma__/ INFO [launcher]: Starting browser Chrome INFO [Chrome 42.0.2311 (Mac OS X 10.9.5)]: Connected on socket Vqvid8KHt3frga3RTIP5 with id 36271559 INFO [framework.browserify]: 4775122 bytes written (5.42 seconds) INFO [framework.browserify]: bundle built Chrome 42.0.2311 (Mac OS X 10.9.5) LOG: 'WARNING: Tried to load angular more than once.' ! Chrome 42.0.2311 (Mac OS X 10.9.5): Executed 127 of 127 SUCCESS (1.854 secs / 1.83 secs) [19:02:12] Finished 'unit' after 10 s
  7. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  8. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  9. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  10. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  11. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  12. describe('E2E: Settings', function() {! var AuthHelper = require('./helpers/auth_helper.js');! ! beforeAll(function()

    {! AuthHelper.signIn();! });! ! beforeEach(function() {! browser.get('/settings');! browser.waitForAngular();! });! ! it('should route correctly', function() {! expect(browser.getLocationAbsUrl()).toMatch('/settings');! });! ! it('should show dashboard layout', function() {! var el = element(by.css('.content-header h1'));! expect(el.getText()).toEqual('Settings');! });! ! it('does not allow creating a new setting', function() {! expect(element(by.css('.create-link')).isPresent()).toBe(false);! });! });!
  13. // app/views/signin.html! ! <h4>Sign in</h4>! <form ng-submit="signin.submitLogin(loginForm)" ng-init="loginForm = {}">!

    <input type="email" name="email" ng-model="loginForm.email" required placeholder="Email"/>! <input type="password" name="password" ng-model="loginForm.password" required="required" placeholder="Password"/>! <button type="submit">Sign In</button>! </form>! //helpers/auth_helper.js! ! module.exports = {! signIn: function() {! browser.get('/admin/signin');! element(by.model('loginForm.email')).sendKeys('[email protected]');! element(by.model('loginForm.password')).sendKeys('foobar\n');! browser.waitForAngular();! }! };!
  14. // app/views/signin.html! ! <h4>Sign in</h4>! <form ng-submit="signin.submitLogin(loginForm)" ng-init="loginForm = {}">!

    <input type="email" name="email" ng-model="loginForm.email" required placeholder="Email"/>! <input type="password" name="password" ng-model="loginForm.password" required="required" placeholder="Password"/>! <button type="submit">Sign In</button>! </form>! //helpers/auth_helper.js! ! module.exports = {! signIn: function() {! browser.get('/admin/signin');! element(by.model('loginForm.email')).sendKeys('[email protected]');! element(by.model('loginForm.password')).sendKeys('foobar\n');! browser.waitForAngular();! }! };!
  15. // app/views/signin.html! ! <h4>Sign in</h4>! <form ng-submit="signin.submitLogin(loginForm)" ng-init="loginForm = {}">!

    <input type="email" name="email" ng-model="loginForm.email" required placeholder="Email"/>! <input type="password" name="password" ng-model="loginForm.password" required="required" placeholder="Password"/>! <button type="submit">Sign In</button>! </form>! //helpers/auth_helper.js! ! module.exports = {! signIn: function() {! browser.get('/admin/signin');! element(by.model('loginForm.email')).sendKeys('[email protected]');! element(by.model(‘loginForm.password')).sendKeys('foobar\n');! browser.waitForAngular();! }! };!
  16. $ gulp protractor [16:12:50] Using gulpfile ~/Sites/project/gulpfile.js [16:12:50] Starting 'webdriver-update'...

    [16:12:50] Starting 'webdriver'... [16:12:50] Finished 'webdriver' after 118 μs [16:12:50] Starting 'server'... [16:12:51] Finished 'server' after 87 ms selenium standalone is up to date. chromedriver is up to date. [16:12:51] Finished 'webdriver-update' after 230 ms [16:12:51] Starting 'protractor'... Starting selenium standalone server... [launcher] Running 1 instances of WebDriver Selenium standalone server started at http://192.168.1.107:56232/wd/hub Started GET /admin/signin 200 15.286 ms - 802 GET /admin/css/main.css 200 10.579 ms - 93071 GET /admin/js/main.js 200 29.622 ms - 4555872 GET /favicon.ico 404 7.852 ms - 24 POST /admin/api/auth/sessions 200 32.698 ms - 344 . 115 specs, 0 failures, 1 pending spec Finished in 265.959 seconds Shutting down selenium standalone server. [launcher] 0 instance(s) of WebDriver still running [launcher] chrome #1 passed [16:17:21] Finished 'protractor' after 4.48 min