Table of Contents
IntroductionDave Mosher and Justin Searls the course with a brief summary of their work histories and how the came to work at Test Double.
BackgroundBefore 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.
Roman Numeral Calculator
SetupThe 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 DevelopmentBefore 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 TestsDave 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 CodeDave 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.
QuestionsDave and Justin take a few minutes to review the Roman Numeral Calculator and answer a number of audience questions about test-driven development.
Testing PyramidJustin 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 TestingJustin’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.
TreesDiagramming 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 TestsBefore 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 DependenciesDave 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 TestDave 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, continuedWith 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 ProblemJustin 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 ValuesThe 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 ProblemNow 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 ProblemJustin 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 ApplicationThe 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-upDave 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 BackgroundBefore 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 FixturesAfter 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, continuedDave 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 FunctionAs 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 FunctionThe 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 SpiesDave 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: CaptorsA 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 ApplicationsDave 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 IntroductionTestium 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 TestiumDave 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 ChallengesDave 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 1Dave and Justin take questions from the audience.
Q&A Part 2Dave and Justin wrap up the course with some final audience questions.