This course has been updated! We now recommend you take the JavaScript Testing Practices and Principles course.
Table of Contents
Introduction
Introduction
Dave Mosher and Justin Searls the course with a brief summary of their work histories and how the came to work at Test Double.Background
Before getting into the content, Justin explains where to get the course files. He also gives a little background about the syntax used throughout the course. They will be writing most of their unit tests in CoffeeScript.CoffeeScript Basics
Since most of the testing code will be written in CoffeeScript, Dave and Justin spend a few minutes explaining the syntax. They talk about why they prefer CoffeeScript over JavaScript for unit testing and compare how tests would look in both languages.
Roman Numeral Calculator
Setup
The first demo will involve building a Roman Numeral calculator and writing tests against its functionality. Before getting into the code, Dave walks through the environment setup and project dependencies. The repo for this course is organized into folders. It also includes videos for each demo.Test-Driven Development
Before writing any application code, Dave begins with the unit tests. Part of test-driven development is writing the specification for what the application should do before implementing the functionality.Writing and Refactoring Unit Tests
Dave continues writing test cases for the Roman Numeral calculator. As his code begins to grow, he takes a few minutes to refactor it to create a more concise and readable spec.Refactoring Application Code
Dave finishes the Roman Calculator example by refactoring the application code. He demonstrates how a growing number of test cases can pinpoint areas in the applicant code that need optimization. Because the test are already written, he can monitory them during the optimization process to ensure the code is still functional.Questions
Dave and Justin take a few minutes to review the Roman Numeral Calculator and answer a number of audience questions about test-driven development.
Node
Testing Pyramid
Justin takes over and begins the next section with a explanation of the Testing Pyramid. The Testing Pyramid illustrates the greater need for discovery testing and a smaller need for end-to-end testing.Discovery Testing
Justin’s calls his approach to unit testing “discovery testing”. This involves breaking down the feature into smaller pieces and identifying each responsibility. Justin demonstrates his discovery process on his arithmetic problem generator.Trees
Diagramming the functionality in tree-form will help break down tasks into smaller units. These smaller units, or leaf nodes, are pure functions that can be easily tested. Mocks can be built to supply these leaf nodes with test data.Integration Tests
Before getting into the unit tests for their arithmetic problem generator, Dave and Justin explain the integration tests that are pre-build for this application. They also talk about a few of the additional libraries they will be using and introduce the concept of helpers.Other Dependencies
Dave finishes his summary of the project dependencies by explaining the grunt-jasmine-bundle module configuration. He also introduces the first unit test.Video 1: First Unit Test
Dave and Justin begin walking through the first video which demonstrates the coding of the initial unit tests. Justin also spends a few minutes talking about how he determines where to start with his testing and why he isn’t writing unit tests for the Express application.First Unit Test, continued
With the initial unit tests written (and failing), Justin and Dave move on to writing the code for the first collaborator and a few mocks for the subsequent collaborators. They also briefly explain the role of a Jasmine Spy.Video 2: Generating a Problem
Justin and Dave walk through the unit tests for generating a problem. The tests will verify a character is returned for the operator and numbers are generated for the left and right operands.Video 3: Picking Random Values
The next challenge is to ensure a random problem is generated. Dave and Justin explain one technique for testing randomness. After implementing the unit tests, they add the production code.Video4: Saving a Problem
Now that a random problem is being generated, the problem needs to be saved. The unit tests in this video will verify a problem is stored in memory using it’s ID as the key.Video 5: Presenting a Problem
Justin and Dave create a unit test to verify a problem is presented to the user correctly. The production code combines the left and right operands with the operator to create a well-formed problem.Videos 6 & 7: Finishing the Application
The final two videos demonstrate the application in action. Dave and Justin talk through the process of wiring in Express to finalize the production code.Discovery Testing Wrap-up
Dave switches to the answers branch in the repository to walk through the completed code and wrap-up the section on Discovery Testing. Both he and Justin field a few audience questions and talk a little more about strategies around code reuse.
Lineman
Lineman Background
Before getting into the next section on Lineman, Justin and Dave spend a few minutes answering audience questions and talking about task automation with the npm run command.Video 1: Jasmine Fixtures
After a brief explanation of the command line tool, Lineman, Dave and Justin begin walking through the first code video. They are using Jasmine Fixtures to make it easier to inject and test HTML snippets into the DOM.Jasmine Fixtures, continued
Dave and Justin next implement the createApplication function that will spin-up the application. They also talk about the test-runner, Test’em, and demonstrate how it can be used to test multiple connected browsers/devices. The video concludes with the first passing test.SpyOn Function
As mentioned earlier, Jasmine Spies are able to sub any function and track calls to it and any arguments passed. The spyOn method is used to create a spy. Dave and Justin talk about how spies can be used to monitor the instantiation of template files in client-side applications.Affix Function
The affix function in the Jasmine-Fixture library is passed a selector just like the jQuery $ function. However, instead of finding the selector, affix will create an element based on that selector. This is helpful when unit testing because Jasmine-Fixture will remove anything affixed after each test runs.Video 2: AJAX Spies
Dave and Justin explain how to write a unit test for a UI element that triggers an AJAX request. This example also demonstrates nested unit tests. A key takeaway is that Given statements will always execute before When and Then statements.Video 3: Captors
A captor will save an argument value passed to a function and allow it to be recalled later. Dave and Justin walk through the code for creating a captor and verifying a test is passing once the production code is written.Connecting the Applications
Dave pulls together the Node application written earlier and the front-end application they just completed to demonstrate the finished product. The front-end application makes API calls to the Node application and displays a problem to the user.
Testium
Testium Introduction
Testium is an integration test library created by Groupon that hooks into libraries like Mocha to provide a browser sync API. Testium will spin up a browser (either real or headless) and accept commands for test automation. Dave gives a quick demonstration of Testium and walks through the documentation.Using Testium
Dave demonstrates how to use Testium with the problem-generator application. The test navigates to the home page, clicks the new problem button, and verifies a correct result.Testing Challenges
Dave and Justin begin answering some final audience questions. While doing so, they explain some challenges they face when testing UI element. Dave shares his experience as it relates to testing single-page applications.Q&A Part 1
Dave and Justin take questions from the audience.Q&A Part 2
Dave and Justin wrap up the course with some final audience questions.