Skip to content

Testing Overview

Tim Walsh edited this page Apr 10, 2020 · 2 revisions

TravelMaps Frontend Testing

Overview

This page outlines our current approach to frontend unit testing.

Testing Frameworks

We utilize the following testing utilities in our project:

Tool Purpose
Jest Test runner, assertion library, and mocking utilities designed specifically for testing React applications.
Enzyme JS testing framework for React that provides additional utilities for assertion, manipulation, and traversal of React Components’ and rendered page elements.

Goals

The goals for testing in this project are to:

  1. Improve code quality and application performance through small, iterative, and best-practice driven updates.
  2. Add tests to help in building new features, debugging issues, and refactoring existing code. You are not required to test everything, but are encouraged to utilize Test-Driven Development (TDD) as often as is beneficial to the developer.
  3. Write tests as they will benefit you, your current work, or your learning objectives.

When will tests benefit you?

Testing for the sake of testing has inherit limitations; you need to know why you're adding each test. Every line of code requires developer time to maintain; so low-value tests are often more valuable left unwritten. Good testing provides lean and highly valuable tools for the entire development team to spend less time doing things they don't enjoy and more time writing reliable and scalable code.

What Benefits do Good Tests Provide?

  • Less time researching/investigating how something was (or is) intended to work.
  • Less/no time manually clicking through complex workflows within the web-application to see if something works.
  • Less time writing code; usually takes some time to get to this point, but proper TDD can lead to less overall time spent on developing features.
  • Less time refactoring by writing it right the first time.
  • More time writing new features and functionality.
  • Better utilization of best practices.
  • Living and useful documentation of how the system works.
  • Automated quality assurance and continuous delivery of value to the end-user.

The end-result of having a lot of good tests - resulting in a high ratio of test coverage - is that most issues, bugs, and regression to the system will be caught by the test suite as opposed to manual testing, QA, or user-facing error(s). The challenge is that as the test coverage goes down, the chance that a bug will still be introduced and make its way to and end-user facing issue will go up proportionally.

As even 100% test coverage is not 100% error-proof, a good balance of high-value code and high-coverage of the codebase will be an ongoing discussion.

Testing Requirements

At this time, you are not required to introduce tests with new code; but should be starting to think about where you can introduce your first tests just as much as your first features or bugfixes!

Caveat: When we Should REALLY Consider Adding Tests

When we start seeing the following, we should consider adding more tests:

When Writing Tests: Some Guidelines

  1. Be clear and concise in describing the test scenario and intent.
  2. Don't write redundant tests; if we are already testing the same logic in the system, there should be a clear reason or specific use case we are looking to add coverage around.
  3. Add comments and descriptive commits to help provide background around why the test was introduced. Were we tracking down a challenging issue? A particularly challenging refactor? These details help as the test is maintained over time.

Frontend Testing Limitations

Mocking Data: Pro's and Con's

A key piece of frontend testing is to mock specific data or stub certain elements of the system; this essentially boils down to asserting that we expect the a set of conditions to hold true for the duration of a test or set of tests.

The downsides of this approach, and with unit testing in many cases, is that the developer must both consider and write additional test coverage for every instance in which the conditions do not hold true. This can lead to very painful "gotcha" moments where basic pieces of the system would clearly break- but each piece is being tested within it's own contained environment and set of conditions.

Future Work

Backend Unit Testing

In the short-term, adding similar coverage and testing frameworks for the TravelMaps API will be the next step for the team and overall project. This will allow for the similar benefits for our backend dependencies as we are seeing on the frontend, but will not yet solve some of the challenges and limitations of unit testing overall.

End-to-End Testing

End-to-end testing provides more expensive (i.e., slow) tests that can test the entire system and flows within the web application. We are currently evaluating and scoping adding Cypress as an end-to-end testing framework. These tests will be isolated to high-value areas of the codebase as they can sometimes take 10-20 times longer to run given how much setup and tear-down time is required.

Resources

Adding the following articles as they were the main resources I utilized while setting up our test suite and considering what would be first initial tests.

  1. Snapshot Testing - Jest - quick and dirty overview of how snapshots in Jest work.
  2. Testing React with Jest and Enzyme I
  3. Testing React Components with Jest and Enzyme- In Depth
  4. Continuously testing React applications with Jest and Enzyme
  5. Jest mock default and named export
  6. How to test software, part I: mocking, stubbing, and contract testing