So far, we’ve been writing just one test using a single
it() block. However, in most situations, we will need to write many tests for a particular feature that get executed in succession.
Running multiple tests can introduce issues if the tests make changes to the testing environment: changes to the environment in one test might affect the next test. Some common changes to an environment include:
- altering files and directory structure
- changing read and write permissions on a file
- editing records in a database
To address this issue, we often add a teardown step to the end of our tests. The teardown phase makes our tests isolated by resetting the environment before the next test runs. This provides two key benefits:
- Changes to the environment caused by one test do not affect the other tests.
- Isolated tests can be executed in any order!
Note: In some cases — including the previous exercises — the teardown phase isn’t needed because there are no conditions to reset.
This exercise uses Node’s filesystem library
fs in addition to
assert. It’s okay if you’re not familiar with
fs — we will briefly explain the key methods we are using:
fs.appendFileSync(path, str)creates a new file at
pathwith the string
stras content. If a file at
pathexists, the string
strwill be appended to the end.
fs.readFileSync(path)returns the contents of the file found at
The first test found in this exercise verifies that we can use
fs.appendFileSync() to create a file called ./message.txt with the string
'Hello Node.js'. The second test verifies that we can do the same but with an empty string.
If you open up your file system, you’ll see that the file message.txt doesn’t exist yet. Run the test in the terminal. Why does the first test pass but the second test fails?
Note the new file
message.txt created in your directory. It should have the text
project |_ node_modules |_ test |___ index_test.js |_ message.txt <--- new file |_ package.json
In both tests, we are modifying the environment by creating a new message.txt file. However, the current tests do not have a teardown phase. The test fails because the second test appends an empty string to the file created from the first test instead of creating a new file with just an empty string.
Furthermore, if you were to run the test file again, the first test would now fail. Run the test again and see for yourself — the message.txt file will now have the text
You got different output because the test was not isolated.
- In the first run the file didn’t exist, so
fs.appendFileSync()created a message.txt file containing the string.
- In the second run, the method added the string to the end of
message.txtbecause it already existed.
- The second test run failed because the string
Hello Node.jswas added twice to the same file!
In the terminal enter
rm message.txt to delete the file.
To ensure that each test is isolated from each other, and that each run of the test file isolated, we will add a teardown step to the tests. In this case, we want to make sure that after each test, the file found at
path is deleted.
Add this code below
// Teardown in both tests to delete the file after the test has completed.
Why do we delete the file after the second test? We want to ensure that the environment returns to its state before the tests were executed. This keeps the tests isolated.
Verify that you fixed the issue: run the test suite twice and compare the outputs. It should pass both times!