This project implements a back-end for a simple web-based Todo app. The primary goal of the project is to explore various ways of improving the testability of code.
Some common problems when testing back-end applications are:
- Invoking application's operations: back-end applications are often accessible via network calls, which implies that the app server should be running in order to be tested.
- Invoking external services: many applications are dependent on external services, which implies that such external services must be running along with the application in order to test the app.
- Application state: although application state is often implemented using external services, the application state can be considered a separate concern, as it is private to the application. Again, implemented often as an external service implies that these external services must be running in order to test the app.
The application incorporates features which are present in most web apps, such as user authentication, but allows some compromises to be made as it is not supposed to be deployed into production (not yet anyway).
In order to isolate parts of the application for testing, these principles are used when writing the application:
- Write pure functions, as they are predictable and portable – hence easy to test.
- Write small functions that do only one thing. Their edge cases are easy to identify and all branches of execution are easy to test.
- Compose larger and complex functions from small functions. This way parts of the complex functions are already tested by the tests of the smaller functions. Also, functions composed of only pure functions are also pure.
- Write abstractions over external dependencies and inject these abstractions to the actual app. This makes it easy to produce similar implementations for testing purposes only.
- Assign one responsibility for each component and provide domain knowledge of this area only. Any other knowledge should not be a concern of the component.
There are README.md
files spread across the source files explaining testability concerns and design decisions in the folder. For examples of testing the code, take a look at *.test.js
files.
// install npm packages and set up DB
npm run setup
// Clear DB
npm run clean
// Run linter
npm run lint
// Run tests once
npm run test
// Run tests on file changes
npm run test-watch
// Start app with current source files
npm run start
// Start app with a clean DB
npm run start-clean
// start and restart app on file changes
npm run start-watch
MIT