-
Notifications
You must be signed in to change notification settings - Fork 4
Testing Overview
This page outlines our current approach to frontend unit testing.
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. |
The goals for testing in this project are to:
- Improve code quality and application performance through small, iterative, and best-practice driven updates.
- 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.
- Write tests as they will benefit you, your current work, or your learning objectives.
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.
- 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.
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!
When we start seeing the following, we should consider adding more tests:
- Be clear and concise in describing the test scenario and intent.
- 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.
- 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.
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.
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 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.
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.
- Snapshot Testing - Jest - quick and dirty overview of how snapshots in Jest work.
- Testing React with Jest and Enzyme I
- Testing React Components with Jest and Enzyme- In Depth
- Continuously testing React applications with Jest and Enzyme
- Jest mock default and named export
- How to test software, part I: mocking, stubbing, and contract testing