Testing MERN Stack Websites
Overview of testing
What is Test Driven Development?
Test driven development is a process of recording expectations with unit tests for how code/feature should act and then making those expectations a reality. It encompasses unit tests, focused integration tests, and end-to-end integration tests.
Why write tests?
As software scales your ability to make sure everything is up to date shrinks. By writing tests we avoid defects, make our code flexible, maintainable, readable and reusable. If we do not test the code, your users are more likely to find something that unexpectedly breaks and determine the website is unreliable.
What should I test?
Robert C. Martin, the author of Clean code, suggests testing every nook and cranny before you write production code. Though this is ideal, reality is that it is impossible to catch every possible thing that could go wrong. Even just considering a basic four function calculator the list of things you could test are inumerable. Imagine if you tried to write tests for every combination of adding, subtracting, multiplying, and dividing. What about testing using zero, negative numbers, or exponentially large numbers? Others suggest only testing requirements/user stories. Test before:
- Implementation of new functionality
- Refactoring
- Correcting a mistake
What about 100% test coverage?
What makes a test clean?
A clean test runs FIRST to ensure there is no overhead in what is actually happening.
Fast — Make tests run quickly by testing a single concept and reducing expensive calls.
Independent — Tests should not rely on another test to set them up. You can use beforeEach or beforeAll for setup.
Repeatable— Tests should be able to run in any environment with the same result given the same input. Environment means test, staging, and production.
Self-validating — Tests either pass or fail. You should not have to read logs to know if it passed. A clean endpoint should send the status code, data, and query back giving you an idea of what went on.
Timely — Write tests before production code. Tests lose their value when you have already written the code as your opinion in what to test becomes biased and your code is already working.
Simple to understand — Hide irrelevant details through abstraction if it will make what is going on clearer to the reader.
11 Test Driven Development Best Practices — Tests That Think! — MethodPoet
Achieving Quality Code and ROI through Test Automation | by Sphere Software | Medium
Testing tools
Jest
Jest · 🃏 Delightful JavaScript Testing (jestjs.io)
describe — Contain related tests
test — Explain what is to be expected.
expect — contain the data to be checked
matcher — contain the expected result
- toMatchSnapshot — test if code matches result from a previous run of the test
- not — expect not to match
- toBe, toEqual
beforeEach, afterEach — code to run before each tests in scope
Use promises or async await for async code waitfor
React Testing Library
query — methods to find elements on a page
- getByRole, getByLabelText, getByPlaceholderText, getByText, getByDisplayValue, getByAltText, getByTitle, getByTestId
action — trigger an event using fireEvent.[eventName]
render — renders the item
screen — the dom
React Testing Library | Testing Library (testing-library.com)
The Best 10+ React JS Unit Testing Tools in 2023 — ThemeSelection
msw
setupServer — A function that sets up a request interception layer in NodeJS environment.
request.[http verb].expect()
MSW — Seamless API mocking library for browser and Node | Mock Service Worker (mswjs.io)
supertest
nodejs library to testing APIs with one default export. You can test status code, headers, properties, and responses.
mongodb-memory-server, mongoose
create — creates and starts a fresh MongoDB server on some free port so as to be able to reuse tests and not effect the production or development servers.
getUri — get online resource
mongoose.connect(uri) — allows you to use mongoose commands while testing the api.
Categories of testing
Functional
Tests the code meets its functional requirements such as should handle bad arguments. It validated what the user does. like white box testing.
Non-functional
Tests the usability, reliability, and performance of the system seeing it from the perspective of the user such as should load within two seconds. Black box testing.
Automated Testing
Tests that are written for you by a piece of software for non-functional tests.
Regression Testing
Verifies that a test does not fail after it is made. Other kinds of tests can also be regression tests. Unit tests using jest are regression tests.
Manual Testing
A person going through the interface like a user.
Levels of testing
Unit Testing
Testing the smallest part of a code that can be logically isolated such as a function prop or component. Usually, the programmer who wrote the code also writes the unit test for that code.
In React, a unit is usually the same as a component.
One issue with testing the front end in this way is that we are not directly testing production. We are testing a concept such as the JSX sample in the below image.
If you do not like testing the front end in this way the alternative is testing each unit manually, running it in the browser and trying to find a way to break it. (See CSS testing in the other types of testing section.)
Backend unit test
TDD on the Front End — GeePawHill.org
Smoke Testing
Verifies the most crucial functions of a system but does not dive into the finer details.
When should I use smoke testing?
Smoke Testing a Node.js Web Server | Let’s Code JavaScript (letscodejavascript.com)
Integration Testing
Verifies modules work when combined. Tests for:
- Passing invalid or incorrectly ordered arguments
- Broken database schema
- Invalid cache integration
- Flaws in business logic or errors in data flow
System Testing/End to end
Verifies entire system of modules work together. Automation tools usually cover this kind of testing.
System testing is usually considered appropriate for assessing the non-functional system requirements — such as security, speed, accuracy, and reliability. (1)
When should I use system testing?
What Is End-to-End Testing? (With How-To and Example) | Indeed.com
11 Types of Automation Testing With Best Automation Tools (appsero.com)
Performance and Load Testing
Verify speed and reliability under normal and abnormal conditions.
reactjs — How to Performance test react js application? — Stack Overflow
Acceptance tests
Determines whether a system satisfies its acceptance criteria, usually by checking desired system behaviors against the customer’s requirements.
Alpha testing — This testing is referred to as an alpha testing only because it is done early on, near the end of the development of the software, and before Beta Testing. Alpha testing is typically performed by in-house software engineers or QA staff. reference
Beta testing — Beta Testing is performed by real users of the software application in a real environment. reference
Other types of testing
Security testing— Web Application Security Testing — Types, Best Practices, and Checklist — CHARBEL NEMNOM — MVP | MCT | CCSP | CISM — Cloud & CyberSecurity
CSS testing— You can use Blisk to help recognize inconsistencies between the design. visbug can verify distances by pixel for individual pages to ensure it matches the design.
Markup validation — The W3C Markup Validation Service
Renderer — Pull Request Previews | Render
(1) SEBoK Editorial Board. 2022. The Guide to the Systems Engineering Body of Knowledge (SEBoK), v. 2.7, R.J. Cloutier (Editor in Chief). Hoboken, NJ: The Trustees of the Stevens Institute of Technology. Accessed [DATE]. www.sebokwiki.org. BKCASE is managed and maintained by the Stevens Institute of Technology Systems Engineering Research Center, the International Council on Systems Engineering, and the Institute of Electrical and Electronics Engineers Systems Council.