Testing in JavaScript
How Writing Tests for Your Code Can Help Improve Your Code
An important part of the process of writing clean, effective code is writing and running tests for your code. As a relative newcomer to the field of software engineering, the thought of writing tests for your code might initially seem intimidating and complicated. You know you should do it, but you’re not sure of where or how to start. You might think writing tests for your code is time-consuming and unnecessary, but quite the opposite is true — implementing tests helps us to spot any bugs before we deploy our code and allows our programs to run smoother, ultimately resulting in saved time and a more professional, efficient end product.
A good practice is to adhere to test-driven development (TDD). In TDD, we first write tests for our code, keeping in mind what we want our code to ultimately do, write some initial code to pass the tests, and then refactor our code to make the code clean and as DRY as possible. We can think of this process as red, green, and refactor. When we initially write our tests, the tests will fail, giving us red lights. We then write enough code to make our tests pass, turning the lights green. Next, we refactor and clean up our code, which might then break some of our tests, so we repeat the whole process as necessary. The below diagram is helpful in illustrating the concept:
What are some different types of tests?
While there are many different types of tests, we’ll cover three of the most common and useful ones for web development here.
- Unit Tests
- Integration Tests
- End-to-End (E2E) Tests
Unit tests involve testing one individual piece of our code, such as a single function or a class, at a time. Unit tests are fully isolated and check that given an input, the output is what we expect it to be.
In unit testing, it is good practice to separate tests into a dedicated file. Below are common naming patterns used:
- {file_name}.test.js
- {file_name}.spec.js
The below code snippet is an example of of a unit test for the specified generateText function:
In comparison, integration tests look at how functions interact and work together. This involves dependencies.
E2E tests look at the full flow of the code and imitates a real user experience. This involves looking at DOM manipulation based on what a user does on the screen.
As a general rule, unit tests are less complex and costly, thus we usually end up writing unit tests with more frequency. The idea is that if all of the individual pieces of our code are working as expected, then we have a good foundation for how our code will work as a whole. We should always use unit tests and then use integration and E2E tests as needed.
Testing Frameworks
While it is possible to write your own tests from scratch, there are many testing frameworks that exist that make testing much easier, more efficient, and more reliable.
Below are a few of the most popular ones for testing JavaScript, with links to the documentation: