React Testing
React Testing using Testing library and Jest
Last updated
React Testing using Testing library and Jest
Last updated
Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!
Jest Dom comes with create-react-app
It uses src/setup.test.js and the Jest DOM is available on all these files ending with .test.js
The above point means that the Jest DOM matchers are available in .test.js files where Jest DOM provides some of the methods that will test the screen elements -> "Tests if element is present on DOM or not" and many more methods related to screen/UI which is DOM.
The normal Jest doesn't do the testing of screen elements. It might do test of Javascript related stuff, for example, jest can test how many elements are present in an array. On the other hand, Jest DOM can test if UI shows "Learn React" or not.
Simply put, because of Jest DOM, the DOM matchers for Jest is available on .test.js files
Provides virtual DOMs for tests - Any time we are running tests without a browser, we need to have a virtual DOM so we can do things like click elements and we can see if virtual DOM behaves like it should do.
Jest is a test runner. Jest is responsible for
Finding Tests
Running the tests
Determining whether the tests pass or fail
Both React Testing Library and Jest works together.
Enzyme is replacement for React Testing Library like it's said in the stackoverflow link above. It's not the replacement for Jest.
Mocha is replacement for Jest.
Below combination are possible
React Testing Library + Jest -> Our Udemy Course and popular option
Enzyme + Jest
React Testing Library + Mocha
Enzyme + Mocha
To run the create-react-app we use npm start
To run the tests, we use npm test
Type 'a' to run our tests. This is our watch mode (More on this later)
Assertions are the statements that test our expectations against actual results.
Writing the tests even before writing the code.
Unit Testing
Tests one unit of code at a time. May be a single function or a component without depending on other units
Integration Testing
Tests how multiple units work together. Testing interaction between different functions/units/components
Functional / Behavioural Testing
Functional testing means testing the behaviour of a function/software. We might be testing if the software does the right thing with the particular set of data. That might be an integration test as it might have to interact with different units. So the functional test can be an integration test as well
The functional test can also be a simple unit test. Let's say on a button click, the div turns red. This might be a simple unit test but still it can be considered as functional test as well as it tests for a particular behaviour of CLICK TURNS RED OR NOT
So, the functional test means, not testing the code but testing the behaviour
React-Testing-Library encourages functional tests
Acceptance/End-to-End(E2E) test
This is an End-to-End testing where we need a browser and might also need the server
Popular tools for E2E testing are Cypress and Selenium
React-Testing-Library doesn't support E2E testing
If only developer is testing the code while writing the code then its TDD even though we write functional tests for testing behaviour
BDD is when different teams are involved like developer, QA, business and so on to test the software
Testing library recommends finding elements by accessibility handles like screen readers would be able to find them
Queries Accessible to everyone. Examples:
getByRole - All the role definitions can be found here https://www.w3.org/TR/wai-aria-1.1/#role_definitions
Most of the HTML / JSX elements has the role by default. For Example, the link is the default role of anchor tag <a> and we don't need to explicitly define it.
To define the role explicitly we say role = ""
. Example, <a role="link"/>
getByLabelText
2. Semantic Queries
getByAltText
getByTitle
3. Test IDs
getByTestId
Read more about this in the document given below.
If our test can't find an element like the screen reader would then our app is not friendly to the screen readers which is a bad thing 😢
In the first app, we just test the change of the colour of the button on click. If we click on red button, it will change to blue and vice versa.
Step 1
In TDD style, we first write the test before we test the functionality and make it fail
First clear the content in App.js
and make sure it just returns a simple div
Write the test for this first and see it fail and then in step 2, write enough to make the test pass
Step 2
Once the test fails, then write enough to make the test pass in App.js
file
Steps
First write the test and let it fail
Now write the function to make the button colour to blue and then see the test pass
Test Before Code
Code after Test fails
Steps
Write the test for initial condition - to check if the colorButton is enabled and the checkbox is disabled
The below test fails as it can't find checkbox
Let's make the test pass by adding a checkbox into App.js
Let's test for button being disabled after checkbox being checked
To make the test passed
Name of the checkbox comes from the label assigned to it
Steps
Disable checkbox
Check if button is grey
Enable checkbox
Check if button is red
Click the button to change colour to blue
Disable checkbox
Check if button is grey
Enable checkbox
Check if button is blue
Now after the test fails, implement the passing code and re-test to check if functionality is passed
Till now we were doing a functional/functionality/behavioural testing on components. Then what is a unit test? Let's say we have a function that is used by one or more components. We might want to test that function with different inputs (different edge cases) and this is called unit test.
Let's take an example here. Let's say our users are bored of red and blue colours and they want Mid night blue and Medium Violet Red.
Here, our function might take different type of inputs like camel case, single word and so on. But at the end, we need a camel case output.
Edge cases
Test for - Single word colour like 'red', 'blue' (with no inner capital letters)
Test for - Works for one inner capital letter like 'midnightBlue'
Test for - Works for multiple inner capital letters like 'mediumVioletRed'
Here's you can see that we need to test a single function with different edge case inputs. In this case we can group these test cases (as it is related to same test with different inputs). For grouping the test cases, we can use describe.
describe statement is used to group the tests
Function to make this pass
FIRST APP - COLOUR BUTTON
How to test text content on screen
How to check if button is enabled and disabled
How to check if checkbox is enabled and disabled
SECOND APP