Front End TDD


For Fun and Profit

Victor Aponte
Front-end Dev @ Wells Fargo
gh: FunnyDewd
@FunnyDewd

Impromptu Survey

Why I test...


Then, one day...







TDD

T.D.D.

(Test Dat code! Dammit!)

BDD

B.D.D.

(Blame Dat other Developer)

but seriously...

Focus on Testing


There are a lot of different types

Unit Testing

(This is where TDD/BDD usually comes in.)

Here we test the individual functionality of the object/component  you are coding.

Your tests are completely focused on the
singular piece of code you're writing.

Integration testing

( this is a very different mode of testing )

Here you test how your code fits in with the
 other components in your application.

In front end dev, this also means how
your code can be interacted with.

Think of how it integrates with the rest of the page/app.

Others

  • Component Integration
  • Systems Integration
  • Stress Testing (load testing)
  • Quality Assurance Testing
  • User Acceptance Testing
  • Drug Testing
  • Sobriety Testing
  • ... and many more ...

Testing Styles:



  • TDD - Test Driven Development
  • BDD - Behavior Driven Development



TDD Style (a la qunit):

module("User Registration: Validation");
test("validate user input", function() { var emailIsValid = function_to_validate_email(user_input); ok(emailIsValid, "Validation successful");};
test("verify unique email in database", function() { var emailExists = function_to_search_db(user_input); ok(!emailExists, "Email is unique and can be added to db.");};
module("User Registration: Save to DB");test("verify user record is saved to DB", function() { // This assumes DB.save() returns a truthy/falsey value ok(DB.save(user_input), "Record saved successfully");};

BDD Style (jasmine):

 describe("User Registration", function() {   describe("While validating the registration info", function() {     it("should make sure the email address is valid", function() {       expect(function_to_validate_email(user_input)).toBeTrue();     });     it("should verify the email doesn't already exist", function() {       expect(function_to_search_db(user_input)).toBeEmpty();     });   });   describe("While creating the user's database record", function() {     it("should save successfully in the database", function() {       expect(function_to_save_user(user_input)).toBeTruthy();     });   }); });

TDD is Terse

User Registration: Validation

 - validate user input
    1. Validation Successful

 - verify email does not exist in db
    1. Email is unique and can be added to DB.

User Registration: Save to DB

 - verify user record is saved successfully
    1. Record saved successfully.



Tests show clear linear test progression.

BDD is narrative

Describe User Registration

  While validating the registration info

   - it should make sure the email address is valid

   - it should verify the email doesn't already exist

     ...


  While creating the user's database record

   - it should save successfully in the database

     ...


Tests are expressed in behavioral terms

Ok, but what kind of tests should I write??

What you should be Unit testing:

  • Instantiation
  • Error Handling
  • API
  • State changes
  • DOM changes
  • Functions/Calculations
  • Events/Behaviors
  • Performance

What you shouldn't be Unit testing:


  • Third party libraries/frameworks (like jQuery, backbone)
  • Remote services (like twitter, github api) *
  • Application related services (database, messaging, etc.) *
  • Other libraries and modules written by your team *


*Remember: These are done during integration testing.

TDD/BDD Workflow


The tools for Front End Testing


  • Testing Framework/Library (for JS & DOM)
  • Mocks, Stubs, Spies & Fixtures (oh my!)
  • Command-line based test runners

For the Jargon Cup

  • Fixtures
  • Spies
  • Stubs & Mocks
  • Assertion Library
  • Matchers
  • Sync vs Async testing

Testing Frameworks


  • QUnit
  • Jasmine
  • Mocha
  • Buster.JS
  • YUI Test
  • JSUnit
  • DOH
  • Screw.Unit
  • and many more...

QUnit


  • Developed by the jQuery folks
  • Designed to run inside the browser
  • TDD Style
  • QUnit is easy to get started with.
  • Supports Async testing
  • Easy support for DOM testing
  • Supports Fixtures
  • No built-in support for Spies & Mocks

Jasmine

  • Brought to you by Pivotal Labs (popular in rails)
  • Also designed to run in the browser
  • Supports BDD Style
  • Built-in support for function spies
  • Supports Async testing
  • Supports custom matchers
  • No built-in support for fixtures and mocks (jasmine-jquery)

Mocha.js

  • Written by Mr. VisionMedia (TJ Holowaychuk)
  • Originally for Node testing
  • Supports both TDD and BDD style
  • Does NOT come with an assertion library (chai.js)
  • Supports Async testing (super easy!)
  • No built-in support for spies, mocks and fixtures (js-fixtures)
  • Global Leak Detection
  • Displays slow running tests
  • Configurable timeout for tests

Command Line test runners

  • Guard, Guard-Jasmine, Jasmine-Headless-Webkit (ruby)
  • Cucumber/Capybara (ruby)
  • Testem (node)
  • Karma (node)

Guard-Jasmine

  • Ruby Based
  • Uses a "headless" browser for DOM testing
  • Supports file watching
  • No built-in support for multi-browser testing (Selenium)

Cucumber/Capybara


  • Ruby based
  • Specifically for doing Integration/User Acceptance tests
  • Also uses a headless browser
  • No built-in multi-browser testing. (Selenium, watir)
  • Uses Gherkin for describing user actions

Testem & Karma

  • Node.js based
  • Supports many testing libraries (QUnit, Jasmine, Mocha)
  • File watching to re-run tests when files are updated
  • Creates a "server" in which each browser loads and runs tests.
  • Each browser runs the test suite and reports back the results to the server which is reported by the command line interface.
  • Testem is easier to set up and run, while Karma is more extensible (via plugins) and is highly configurable.
  • Testem has a nicer UI than Karma.

My Testing Stack...


  • Karma (via Grunt.js)
  • Jasmine (including spies)
  • Jasmine-jQuery (for fixtures, extra matchers)
  • occasionally Sinon.js (for mocks & stubs) 

Demo: Getting Started with Karma



Conclusion



Stay testing my friends!

Front-End TDD

By funnydewd

Front-End TDD

Presentation for Charlotte Front End Dev meetup on front end testing.

  • 4,710