├── .gitignore ├── .travis.yml ├── README.md ├── package.json ├── server.js └── test └── server-test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.12 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Node TDD 2 | 3 | This is an introduction to Test Driven Development for Node.js. This guide includes details on installing Tape, setting up a testing environment, writing a basic server test, and installing pre-commit hooks with Travis and Code Climate. 4 | 5 | ## Why TDD? 6 | 7 | Test Driven Development is an important part of writing consistent, collaborative and reliable code. If you're a newcomer to TDD entirely, [this tutorial from DWYL](https://github.com/dwyl/learn-tdd) is a great introduction to the very basic WHY and HOW of testing. 8 | 9 | ## What is Tape? 10 | 11 | Tape is an npm module for testing. It's one of many popular frameworks for testing Node.js (you might also want to look at Lab, Shot, Mocha or Jasmine). As one of the simplest and easiest testing frameworks to master, we'll be using it for this tutorial. 12 | 13 | ## Installing Tape 14 | 15 | To install Tape, run this command whilst inside the folder for your repository. 16 | 17 | ```npm install tape --save-dev``` 18 | 19 | The `--save-dev` tail to the command makes sure it is listed as a development dependency in your `package.json` file. This means that anybody else working on your project can easily find out what needs to be installed for the codebase to run. Anybody else can now install Tape simply by running `npm install`. 20 | 21 | ## Folder Structure 22 | 23 | You will need to create a folder in your project called `/test/`. This is where all your tests will live. You can structure your tests however you see fit within this folder. 24 | 25 | Create a file called something like `tests.js`. Although in the future you might like to modularise your tests (eg. `api-tests.js`, `db-tests.js`). 26 | 27 | ## Adding a Package.json Script 28 | 29 | You have to set up a command in your `package.json` file in order to run the tests in the command line. This goes in the `scripts` section of the `package.json`. If this section doesn't already exist, add it (Note: you will need to use JSON structure). A script will look something like this: 30 | 31 | ```node 32 | "scripts": { 33 | "test": "./node_modules/.bin/tape ./test/*" 34 | }, 35 | ``` 36 | 37 | Now you can run your tests simply by using the command `npm run test`. 38 | 39 | ## Setting up your Test File 40 | 41 | Start by requiring Tape at the top of your `tests.js` file: 42 | 43 | `var test = require('tape');` 44 | 45 | Also make sure you require any relevant files, so you have access to what you need to test. If you're testing the server, require the files where you set that up. 46 | 47 | `var server = require('../server.js');` 48 | 49 | ## Writing Tests with Tape 50 | 51 | Now it's time to actually write some tests. You can find the full documentation for writing tests with Tape [here](https://github.com/substack/tape), but a basic test with Tape is structured like this: 52 | 53 | ```javascript 54 | test("check 1 is equal to 1", function (t) { 55 | t.equal(1, 1, "success!"); 56 | t.end(); 57 | }); 58 | ``` 59 | 60 | ### Check the Server is Running 61 | 62 | After you've made this pass, you'll want to start by checking that your server is running. A good, basic test is to check that when visiting your homepage, the status code from the server is 200. 63 | 64 | To write this test, you'll need to simulate an HTTP request to the server. Intense. But thankfully there's an npm module to help you out with that. Take a look at [Shot](https://www.npmjs.com/package/shot). You will need to install the module, save it to dev dependencies, and require it in your test file as a variable (if you don't remember how to do this, look above). 65 | 66 | Within a Tape test, you will need to call the method `Shot.inject` with three parameters: the handler function from your server, the server route object for reaching the homepage (it'll be a GET request), and a callback function taking the parameter `res`. Log `res` to the console, and see if you can find the status code in the response. 67 | 68 | Have fun... 69 | 70 | ## Stretch Goals 71 | 72 | ### Badges! 73 | 74 | Once you get your test suite up and running, you'll want to let the world know. That's why we have pretty badges for our repos. The most useful ones are Travis and Code Climate. Check out [this rundown from DWYL](https://github.com/dwyl/repo-badges), then check out [Learn Travis](https://github.com/dwyl/learn-travis) and [Learn Code Climate](https://github.com/docdis/learn-codeclimate). 75 | 76 | ### Pre-commit Hooks! 77 | 78 | You can set up scripts in your `package.json` to run your tests before you commit anything to GitHub. These are called "pre-commit hooks", and they're useful for guaranteeing code quality within your team. Look at an npm package called [Pre-commit](https://www.npmjs.com/package/pre-commit). 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learn-node-tdd", 3 | "version": "1.0.0", 4 | "description": "Learn TDD with node.js", 5 | "main": "server.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "./node_modules/.bin/tape ./test/*" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/nofootnotes/learn-node-tdd.git" 15 | }, 16 | "keywords": [ 17 | "tdd", 18 | "node", 19 | "tape" 20 | ], 21 | "author": "nofootnotes, msmichellegar", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/nofootnotes/learn-node-tdd/issues" 25 | }, 26 | "homepage": "https://github.com/nofootnotes/learn-node-tdd", 27 | "devDependencies": { 28 | "shot": "^1.6.1", 29 | "tape": "^4.2.0" 30 | }, 31 | "dependencies": { 32 | "http": "0.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var port = process.env.PORT || 8000; 3 | 4 | function handler(request, response) { 5 | var url = request.url; 6 | if (url.length === 1) { 7 | response.writeHead(200, {"Content-Type": "text/html"}); 8 | response.end("HELLO WORLD!"); 9 | } 10 | } 11 | 12 | http.createServer(handler).listen(port); 13 | 14 | console.log('node http server listening on http://localhost:' + port); 15 | 16 | module.exports = handler; -------------------------------------------------------------------------------- /test/server-test.js: -------------------------------------------------------------------------------- 1 | var test = require('tape'); 2 | var Shot = require('shot'); 3 | var server = require('../server.js'); 4 | 5 | test('server is running', function (t) { 6 | Shot.inject(server, {method: 'GET', url: "/"}, function (res) { 7 | t.equal(res.statusCode, 200, "Congrats, server is running"); 8 | t.end(); 9 | }); 10 | }); --------------------------------------------------------------------------------