Tests make sure that changes in code don't break its functionality. For testing an app, we need a test runner.
src directory contains all the app code and a file called
App.test.tsx. This file contains a test that makes sure that the
App component renders a link:
Let's break it down and write our own tests to understand what's going on.
Every test is a statement that claims something. In our case, test in
App.test.tsx claims that the
App component should render a “Learn React” link.
This kind of statements consist of 3 stages:
Arrange: we prepare the testing environment, all of the arguments for the function being tested and its dependencies;
Act: we call the tested function;
Assert: we compare function results with expected results, if they are equal the function worked correctly.
This is true for the test in the
App.test.tsx, let's check:
This is considered a good practice to structure tests in this way. Tests that comply the Arrange-Act-Assert structure are clean and easy to read.
Let's start with a test for good ol' functions, and then come back to testing components. Testing functions is a bit easier to grasp and it will be much easier to apply this knowledge later, when testing components.
App.tsx and add a new function:
Now, open the
App.test.tsx file and start testing this
divide function. First of all, we need to describe what we want to test. For descriptions,
jest has a
describe function, which we can use like this:
We can indent
describe functions to create describe specific details about current tests we write:
For actually running tests
test functions. We can use either of those, they do the same. The only difference is the name semantics: we can use
it to construct test sentences more naturally. For example:
Finally, let's actually write our first test!
In our case we use
.toEqual method to check if the
expect argument is equal to
toEqual argument, i.e. if the expected result is equal to actual result.
Now, it is time to check if our test is working, open the console and run:
You will see that all the tests are passing:
This is great! But we have to break our test 🤯
Breaking Our Tests#
The immediately appearing thought is: “What would we do that?”.
The reason is that we need to make sure that our test is working and that it tests the right thing. Let's look at the example:
So, to test our test we're going to break it and see if it breaks with the correct intent.
In this case we will see an error output:
If we examine the reason why the test has failed, we will see that expected value is not equal to actual. This reason is valid, so the works correctly.
Now let's try to test that
divide function doesn't allow to divide by 0.
Notice that we pass a
() => divide(1, 0) here, this way
jest knows that the occurred error is expected and there is no need to stop the testing itself.
Again, let's test our test:
The output will be:
Thus, we know that our tests are correct.
When using TDD, it is recommended to write tests before writing a function itself. However, we don't cover TDD in this post, this is a topic for a post in its own.
Later, we will use
jest for writing tests for React component.