├── calculator.js ├── package.json ├── calculator-test.js ├── README.md └── test.js /calculator.js: -------------------------------------------------------------------------------- 1 | const add = (a, b) => a + b 2 | 3 | const subtract = (a, b) => a - b 4 | 5 | module.exports = { 6 | add, 7 | subtract 8 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-test-without-library", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js ./*-test.js" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } -------------------------------------------------------------------------------- /calculator-test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const { add, subtract } = require('./calculator') 3 | 4 | test('should add two numbers', () => { 5 | assert.equal(add(1, 2), 3) 6 | }) 7 | 8 | test('should subtract two numbers', () => { 9 | assert.equal(subtract(3, 2), 1) 10 | }) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Testing Without Libraries 2 | 3 | This is a sample project demonstrating how to write, and run tests for Node.js without using an external library. 4 | 5 | For the complete explanation, you can see my [blog post](https://www.sohamkamani.com/blog/javascript/making-a-node-js-test-runner/). 6 | 7 | To run the tests, clone this repo and run: 8 | 9 | ``` 10 | npm test 11 | ``` 12 | 13 | You can change one of the tests in `calculator-test.js` and run `npm test` again to see the test failure message. -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | // `tests` is a singleton variable that will contain all our tests 2 | let tests = [] 3 | 4 | 5 | // The test function accepts a name and a function 6 | function test(name, fn) { 7 | // it pushes the name and function as an object to 8 | // the `tests` array 9 | tests.push({ name, fn }) 10 | } 11 | 12 | function run() { 13 | // `run` runs all the tests in the `tests` array 14 | tests.forEach(t => { 15 | // For each test, we try to execute the 16 | // provided function. 17 | try { 18 | t.fn() 19 | // If there is no exception 20 | // that means it ran correctly 21 | console.log('✅', t.name) 22 | } catch (e) { 23 | // Exceptions, if any, are caught 24 | // and the test is considered failed 25 | console.log('❌', t.name) 26 | // log the stack of the error 27 | console.log(e.stack) 28 | } 29 | }) 30 | } 31 | 32 | // Get the list of files from the command line 33 | // arguments 34 | const files = process.argv.slice(2) 35 | 36 | // expose the test function as a global variable 37 | global.test = test 38 | 39 | // Load each file using `require` 40 | files.forEach(file => { 41 | // Once a file is loaded, it's tests are 42 | // added to the `tests` singleton variable 43 | require(file) 44 | }) 45 | 46 | // Now that all the tests from all the files are 47 | // added, run them one after the other 48 | run() --------------------------------------------------------------------------------