{"_id":"learn-tdd","_rev":"9-a54ee634d59f4af6eeff8382dc68a942","name":"learn-tdd","description":"learn test driven development (TDD) using QUnit!","dist-tags":{"latest":"1.0.8"},"versions":{"1.0.2":{"name":"learn-tdd","version":"1.0.2","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"codeclimate":"CODECLIMATE_REPO_TOKEN=7498136cff114e83c81fe6e2839f9538d865f9bdee4eb41d25d2058a9110713c ./node_modules/codeclimate-test-reporter/bin/codeclimate.js < ./coverage/lcov.info","test":"node test.js","coverage":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"codeclimate-test-reporter":"0.1.1","hapi":"^10.0.0","inert":"^3.0.1","istanbul":"^0.3.20","jsdoc":"^3.3.2","nodemon":"^1.5.1","qunit-tap":"^1.5.0","qunitjs":"^1.19.0"},"gitHead":"89ee5f987b6330ba5b8461e730bb878937c1aecf","_id":"learn-tdd@1.0.2","_shasum":"e70a7ae69d12881fff68981a085770e7e06453d2","_from":".","_npmVersion":"2.14.2","_nodeVersion":"4.0.0","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"e70a7ae69d12881fff68981a085770e7e06453d2","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.2.tgz","integrity":"sha512-1zqUd+EDb2f6mRMXyFtipp6ImpTi8QDsrG/z1mpcBeA02Timsp6+0dfoHy/bdljnUFusUz7Nx5oJwuKQYBmqwA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1DUNNhhJ+09cAcg5GvGsp9UXObmKxpxwzF21OAXv5TAiBCucb+ChDmIxYTG7HSvLSOdipmcN5qaEfedZqDRBVE+g=="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}]},"1.0.3":{"name":"learn-tdd","version":"1.0.3","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"codeclimate":"CODECLIMATE_REPO_TOKEN=7498136cff114e83c81fe6e2839f9538d865f9bdee4eb41d25d2058a9110713c ./node_modules/codeclimate-test-reporter/bin/codeclimate.js < ./coverage/lcov.info","test":"node test.js","coverage":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"codeclimate-test-reporter":"^0.1.1","hapi":"^11.0.1","inert":"^3.0.1","istanbul":"^0.4.0","jsdoc":"^3.3.3","nodemon":"^1.7.3","qunit-tap":"^1.5.0","qunitjs":"^1.19.0"},"gitHead":"224462f7af8303a21b01febbb55dbe11ab5b856b","_id":"learn-tdd@1.0.3","_shasum":"5e098c079b69eb3d5e8e7f7a86db7bcd3c2c0420","_from":".","_npmVersion":"2.14.4","_nodeVersion":"4.1.2","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"5e098c079b69eb3d5e8e7f7a86db7bcd3c2c0420","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.3.tgz","integrity":"sha512-SxK4sM2RmZEODRtNOJQCotryzkSBWvw3anwh7M27DqRbKKMoP26sCt28JQWpq1Yt22N3sDLXyA9CoARjKUlb2w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDPsltsRYXD0Vc2yO8yiVl4TwkS9czUrFN0hFDc9KQHSAiAAq4xkIu/Q6q1bZPVj3qWLDE5sAwnF6XVW2LWqKvvggQ=="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}]},"1.0.4":{"name":"learn-tdd","version":"1.0.4","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"test":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"hapi":"^11.0.4","inert":"^3.2.0","istanbul":"^0.4.0","jsdoc":"^3.3.3","nodemon":"^1.8.1","qunit-tap":"^1.5.0","qunitjs":"^1.20.0"},"gitHead":"fb5b7475f2944dbf6e4803e71828621c32b791bb","_id":"learn-tdd@1.0.4","_shasum":"d2e937f5e91259653b78fe39f5c7229e71bfac61","_from":".","_npmVersion":"2.14.4","_nodeVersion":"4.1.2","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"d2e937f5e91259653b78fe39f5c7229e71bfac61","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.4.tgz","integrity":"sha512-qTanhsBN94qOEDhzrR2AoDt4foJOxul32oDGbMLdytfZvMmEDzbRtmZP4Jq7UFtWFMO22EQ4c84OVhBiejW7Ng==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB48BOUXY6gTNwYP1VNL1swem+3SJwmixAFNGWfvPAbXAiEAgiZbPVzOnTs9AJLtskMqj5FsjG5naBX0KhIHuXIYiQA="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}]},"1.0.5":{"name":"learn-tdd","version":"1.0.5","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"test":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"hapi":"^11.1.3","inert":"^3.2.0","istanbul":"^0.4.1","jsdoc":"^3.4.0","nodemon":"^1.8.1","qunit-tap":"^1.5.0","qunitjs":"^1.20.0"},"gitHead":"e0908a293cfd6ae4b444164bc49a76c195f79566","_id":"learn-tdd@1.0.5","_shasum":"a1782986445935a6a6bfb90782d8cbc2764ca942","_from":".","_npmVersion":"2.14.7","_nodeVersion":"4.2.3","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"a1782986445935a6a6bfb90782d8cbc2764ca942","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.5.tgz","integrity":"sha512-Iq8PO0Hcysh2KWFAsiBKdpeewx97RbF4QBSZaTPei6qptpXIMSK6nfJ0vMHHnzIOfMY4EAyPKy+L4xj/DE9Rsw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFscHrTku7FbOZSDmKEKxqAiIGqal8NX3b6miKFc3UvgAiBGPEEhbaJHJxizWiA/yGNPnyw4SKPAVqOGDkrzU5B4ew=="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}]},"1.0.6":{"name":"learn-tdd","version":"1.0.6","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"test":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"hapi":"^12.1.0","inert":"^3.2.0","istanbul":"^0.4.1","jsdoc":"^3.4.0","nodemon":"^1.8.1","qunit-tap":"^1.5.0","qunitjs":"^1.20.0"},"gitHead":"6614b4c8a101ab47ec060ef7baa4099b794e9e82","_id":"learn-tdd@1.0.6","_shasum":"73f444b3cd84b1707c10e91d672888b987850436","_from":".","_npmVersion":"2.14.7","_nodeVersion":"4.2.3","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"73f444b3cd84b1707c10e91d672888b987850436","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.6.tgz","integrity":"sha512-hsO5iU7OJqR5OT8q24DAcdY9hZ4hKZK7HgtN/uLrKvFhW4BNrQZFE1dvXL6sDynegnGNJu3LDI0NHS4nqQkgiw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICgR38tzCSO3k/P0rK9ln2wTWt2V1LuRF/BzfQqqhZwZAiEAgWt2oy9E90gve28kiylU1ri7tR9f6skf+g2uiKa3sBQ="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}]},"1.0.7":{"name":"learn-tdd","version":"1.0.7","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"test":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"hapi":"^13.4.0","inert":"^4.0.0","istanbul":"^0.4.3","jsdoc":"^3.4.0","nodemon":"^1.9.2","qunit-tap":"^1.5.0","qunitjs":"^2.0.0-rc1"},"gitHead":"3e8d274717c8c5d08a52d2b72bba385b8f38e7a8","_id":"learn-tdd@1.0.7","_shasum":"876bd648a8b39d5e09598b8b07e81148e7b40195","_from":".","_npmVersion":"2.15.1","_nodeVersion":"4.4.3","_npmUser":{"name":"nelsonic","email":"contact.nelsonic@gmail.com"},"dist":{"shasum":"876bd648a8b39d5e09598b8b07e81148e7b40195","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.7.tgz","integrity":"sha512-0BVHiKHhO/4D7JzAP3zT3vg5RoS4f8ZPEy2c6dYuzs0c6lw6KrSboDTHxW1VzscfeZxblZGWzgu6tRgbC9/QvQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOxJjZJGaGMLnE2YxSQ8RXlBrnuSEGU3kiG8zQu4aaxgIgMBM/pt9blMWgIpl753aZfZQtgsXQkdXlv8nl7sQQH50="}]},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/learn-tdd-1.0.7.tgz_1463704887919_0.7481342295650393"}},"1.0.8":{"name":"learn-tdd","version":"1.0.8","description":"learn test driven development (TDD) using QUnit!","main":"index.html","scripts":{"test":"istanbul cover test.js","open-coverage":"open ./coverage/lcov-report/index.html","start":"nodemon static-server.js","docs":"./node_modules/jsdoc/jsdoc.js change.js","open-docs":"open ./out/global.html#getChange"},"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"keywords":["learn","tdd","testing","tutorial","beginner"],"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"license":"ISC","bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"homepage":"https://github.com/dwyl/learn-tdd","devDependencies":{"hapi":"^13.4.0","inert":"^4.0.0","istanbul":"^0.4.3","jsdoc":"^3.4.0","nodemon":"^1.9.2","qunit-tap":"^1.5.0","qunitjs":"^2.0.0-rc1"},"gitHead":"e13894ef674bce62c1df73b5ec5f4b7b4f1c45d7","_id":"learn-tdd@1.0.8","_shasum":"62651f6ff7633f56d010529953b39afde67a0e98","_from":".","_npmVersion":"2.14.12","_nodeVersion":"4.3.2","_npmUser":{"name":"nelsonic","email":"nodecoder@gmail.com"},"maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}],"dist":{"shasum":"62651f6ff7633f56d010529953b39afde67a0e98","tarball":"https://registry.npmjs.org/learn-tdd/-/learn-tdd-1.0.8.tgz","integrity":"sha512-5SXxEoLZrFQji1ESuTSjTw5aESh0LjepamW4hnGH999PMKcC19u6yyWEsLBgPdRsvlLIWO9w+AR8gJWUxCvxmg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHz2IQc9ow8VEwsXdoCILPQL2gM5Sz42UQvRiVcnpB2BAiAXDmUnTqCy9dwc6ivM/nWOg4U1IXb9jjpTrU2hvv2diQ=="}]},"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/learn-tdd-1.0.8.tgz_1464034722314_0.02153093833476305"}}},"readme":"# Learn **T**est **D**riven **D**evelopment (**TDD**)\n\nA brief introduction to **T**est **D**riven **D**evelopment (**TDD**)\nin JavaScript for people who want to write _**more reliable code**_.\n\n[![Build Status](https://travis-ci.org/dwyl/learn-tdd.svg)](https://travis-ci.org/dwyl/learn-tdd)\n[![codecov.io](https://codecov.io/github/dwyl/learn-tdd/coverage.svg?branch=master)](https://codecov.io/github/dwyl/learn-tdd?branch=master)\n[![Code Climate](https://codeclimate.com/github/dwyl/learn-tdd/badges/gpa.svg)](https://codeclimate.com/github/dwyl/learn-tdd)\n[![Dependency Status](https://david-dm.org/dwyl/learn-tdd.svg)](https://david-dm.org/dwyl/learn-tdd)\n[![devDependency Status](https://david-dm.org/dwyl/learn-tdd/dev-status.svg)](https://david-dm.org/dwyl/learn-tdd#info=devDependencies)\n[![bitHound Score](https://www.bithound.io/github/dwyl/learn-tdd/badges/score.svg)](https://www.bithound.io/github/dwyl/learn-tdd)\n\n## Why?\n\n_Project(s) without tests_ often end up looking like they are stuck together with _**duct tape**_ ...\n\n![duct tape car fail](http://i.imgur.com/9cNriGK.jpg)\n\nChange _one_ part and the _other_ stops working? \"_Fixing_\" one bug, creates another?\n\nWouldn't you *prefer* if everything was ***consistent*** and beautifully integrated?  \nWhat if _everyone_ on your team worked _like **clock-work**_ in a disciplined order... like a _**Formula 1 Crew**_ ...\n\n![formula 1 pit stop](http://i.imgur.com/2euxKGA.jpg)\n\nTest Driven Development (TDD) makes your team a well-oiled machine which means you can go _**faster**_.\n\nOnce you have a ***suite*** of tests that run on every change, you will\nbegin to develop a whole other level of ***confidence*** in your codebase\nand will discover a new freedom to be ***creative*** without fear of\n\"*breaking*\" anything else; truly *game-changing*.\n\n\n## What?\n\nThis tutorial will help you get started with **T**est **D**riven **D**evelopment (**TDD**) *today*!  \nIn the next ***30 minutes*** you will learn _everything_<sup>1</sup> you need to know to write tests for your web project!\n\n### Pre-Requisites\n\n+ **A computer** with a web browser\n+ **Internet access** to download the starter files\n+ **30 minutes** of time\n+ **_Basic_ Programming Skills** (HTML & JavaScript)\n+ (_**Optional**_) _**Bonus Levels require**_ you to\n[_install_ **Node.js**](https://nodejs.org/download/)\n\n### What is Software Testing?\n> Software testing is the process of evaluation a software item to detect differences between given input and expected output. Testing assesses the quality of the product. Software testing is a process that should be done during the development process. In other words software testing is a verification and validation process.\n\n*Rehman Zafar at [What is software testing?](http://www.codeproject.com/Tips/351122/What-is-software-testing-What-are-the-different-ty)*\n\n### What is TDD?\n> Test-driven development (TDD) is an evolutionary approach to development which combines test-first development where you write a test before you write just enough production code to fulfill that test and refactoring. In other words, it’s one way to think through your requirements or design before your write your functional code.\n\n*From [Introduction to Test Driven Development (TDD)](http://agiledata.org/essays/tdd.html)*\n\n#### Further resources\n- Software Testing - http://en.wikipedia.org/wiki/Software_testing\n- \"What is Software Testing\" video (from 5:56 onwards) - https://youtu.be/UZy1Dj9JIg4?t=356\n- Video intro to Software Development Lifecycle (from 0:52 onwards): https://youtu.be/qMkV_TDdDeA?t=52\n- How to Write Clean, Testable Code -  http://youtu.be/XcT4yYu_TTs (ignore the Java code focus on the general principals)\n- Practical Full-Stack JavaScript Web Application Test Driven Development - https://github.com/nelsonic/practical-js-tdd\n\n## How?\n\nThe *first* thing you need to *understand* is that writing code following TDD (*discipline*) is a (*slightly*) different approach from simply diving into solving the problem (*without a test*).\n\nWhen reading about TDD you will see the expression: \"***Red, Green, Refactor***\":\n\n![TDD Cycle: Red, Green, Refactor](http://i.imgur.com/RQe2NQT.jpg)\n\nWhat this means is that there's a **3-step process**:\n\n1. ***Write*** a **Failing Test** - Understand the (user) requirements/story well enough to write a test for what you expect. (_the test should **fail** initially - hence it being \"Red\"_)  \n\n2. ***Make*** the (*failing*) **Test Pass** - Write (*only*) the code you need\nto make the (*failing*) test pass, while ensuring your existing/previous tests\nall still pass (*no regressions*).\n\n3. ***Refactor*** the code *you* wrote - if you have time to tidy up the code\n*you* wrote to make it simpler (*for your future self or colleagues to understand*) before you need to ship the current feature, do it.\n\nTo develop the *habit(s)* you will need to be successful with TDD (*and software engineering in general*)\nwe need to ***write*** a ***test first*** (*and watch it fail*) and *then* write the code required to make the test pass.\n\nWriting a _**failing test**_, before writing the code may seem *counter-intuitive*, *time consuming* or even \"*tedious*\" at _**first**_. But we _urge_ you to think of it this way:\n\n> The ***test*** is the ***question*** you are asking  \n> your code is the ***answer*** to the question.  \n> By having a _clear_ question, you can always check\n> that your code is working,  \n> because it _**consistently**_\n> gives you the same answer(s) ... _no surprises_, even when you're working with a large, inter-dependent code base!\n\n## Practical\n\n### Scenario: Vending Machine _Change Calculator_ Micro-Project\n\n![vending machine](http://i.imgur.com/HbwMqDa.jpg)\n\nImagine you are building a **Vending Machine** that allows people to buy any item.\nThe machine accepts coins and calculates the change\nto be returned to the customer given the **price**\nof the Item and the **cash** received.\n\n### Single *File* App\n\nWe can build the _entire_ \"project\" in a _**single file**_: `index.html`\n\n> _**note**: in practice you want to split your JavaScript, CSS and HTML (Templates) into **separate** files,\nbut for this example we are keeping everything in `index.html` for simplicity.\nIf you make it to the \"Bonus Levels\" you will split things out!_\n\nCreate a directory on your computer called **vending-machine**:\n\nIn your **terminal** type this command:\n```sh\nmkdir vending-machine && cd vending-machine\n```\n(_this will create the directory and move you into it_)\n\nNext create a file called **index.html** e.g: `atom index.html` (which creates and opens the file in the [Atom text editor](https://atom.io/) if you have it installed)\n\n(_the \"atom\" command is not installed by default. In the Atom menu bar there is a command named “Install Shell Commands” which installs a new command in your Terminal called atom._)\n\nNow copy-paste the following *sample code* to get started:\n\n```html\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Vending Machine Change Calculator TDD Tutorial</title>\n    <!-- Load the QUnit CSS file from CDN - Require to display our tests attractively -->\n    <link rel=\"stylesheet\" href=\"https://code.jquery.com/qunit/qunit-1.18.0.css\">\n    <!-- Pure CSS is a minimalist CSS file we have included to make things look nicer -->\n    <link rel=\"stylesheet\" href=\"http://yui.yahooapis.com/pure/0.6.0/pure-min.css\">\n  </head>\n  <body style='margin: 0 1em;'>\n    <div id='main'>\n      <h1>Vending Machine <em>Change Calculator</em></h1>\n      <h3>Calculate the change (<em>coins</em>) to return to a customer when they buy something.</h2>\n    </div>\n\n    <div id=\"qunit\"></div>\n    <div id=\"qunit-fixture\"></div>\n    <!-- Load the QUnit Testing Framework from CDN - this is the important bit ... -->\n    <script src=\"https://code.jquery.com/qunit/qunit-1.18.0.js\"></script>\n    <script>\n      // This is what a simple unit test looks like:\n      test('This sample test should always pass!', function(assert) {\n        var result = 1 + 1;\n        assert.equal(result, 2); // just so we know everything loaded ok\n      });\n      // A failing test will be RED:\n      test('This is what a failing test looks like!', function(assert) {\n        var result = [1,2,3].indexOf(1);  // this should be 0\n        assert.equal(result, -1); // we *expect* this to fail\n      });\n    </script>\n  </body>\n</html>\n```\n\n#### Open index.html in your Browser\n\nWhen you ***open*** `index.html` in your ***web browser***\nyou should expect to see something like this: (_without the annotations_)\n\n![learn-tdd-initial-index-html-showing-failing-test](https://cloud.githubusercontent.com/assets/194400/8395737/80716e08-1d7a-11e5-9858-c8f96b8c8ad5.png)\n\n\n\n##### Explanation\n\nThere is quite a lot of code in the **index.html** you just created,\nlet's step through it to understand the parts:\n\nThe first part of **index.html** is a standard HTML head and body:\n\n```html\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Vending Machine Change Calculator TDD</title>\n    <!-- Load the QUnit CSS file from CDN - Require to display our tests attractively -->\n    <link rel=\"stylesheet\" href=\"https://code.jquery.com/qunit/qunit-1.18.0.css\">\n    <!-- Pure CSS is a minimalist CSS file we have included to make things look nicer -->\n    <link rel=\"stylesheet\" href=\"http://yui.yahooapis.com/pure/0.6.0/pure-min.css\">\n  </head>\n  <body>\n    <div id='main'>\n      <h1>Vending Machine Change Calculator</h1>\n      <h2>Calculate the Change for a Given Price and Cash Received</h2>\n    </div>\n```\nNothing special here, we are simply setting up the page and loading the CSS files.\n\nNext we see the **qunit divs** (_where the **test results** will be **displayed**_)\nand load JQuery and the QUnit Library from CDN:\n\n```html\n    <div id=\"qunit\"></div>\n    <div id=\"qunit-fixture\"></div>\n    <!-- Load the QUnit Library from CDN - this is the important bit ... -->\n    <script src=\"https://code.jquery.com/qunit/qunit-1.18.0.js\"></script>\n```\n\nFinally we see our test(s) - the interesting part of the file:\n\n```html\n    <script>\n      // This is what a simple unit test looks like:\n      test('This sample test should always pass!', function(assert) {\n        var result = 1 + 1;\n        assert.equal(result, 2);\n      });\n\n      // A failing test will be RED:\n      test('This is what a failing test looks like!', function(assert) {\n        var result = [1,2,3].indexOf(1);  // this should be 1\n        assert.equal(result, -1); // we *expect* this to fail\n      });\n\n    </script>\n  </body>\n</html>\n```\n\nIf you are completely new to writing ***test assertions***, don't worry,\nthey are really simple, there are **3 parts**:\n\n1. **Description** - usually the *first* parameter to QUnit's test() method.\n2. **Computation** - execute a function/method (*exercising the method you will write to solve your test*)\n3. **Assertion** - check that the result of your calculation is what you ***expect*** it to be.\n\n![anatomy-of-a-unit-test](https://cloud.githubusercontent.com/assets/194400/8395876/946d5364-1d83-11e5-8e65-365a8884a194.png)\n\nIn the above screenshot, the assertion is `assert.equal(result, 2)`  \nWe are giving the `equal` method two arguments; the `result` of our computation\nand our expected value in this case **2**. _That's it_.\n\n##### Further Reading:\n\n+ Test assertion: https://en.wikipedia.org/wiki/Test_assertion\n+ What are Test Assertions and how do they work:\nhttp://www.thoughtworks.com/insights/blog/test-assertions-how-do-they-work\n\n\n## Requirements\n\n> Given a **Price** and amount of **Cash** from Customer\n> Return: **Change** to customer (*in notes and coins*).\n\nEssentially we are building a *simple* **calculator** that *only does* **subtraction**\n(Price - Cash = Change), but also splits the **result** into the various **coins**.\n\n\n### Understand what is needed\n\n+ Create a `function` called `getChange` that accepts _**two parameters**_: `totalPayable` and `cashPaid`\n+ For a given `totalPayable` (the total amount an item in the vending machine costs) and `cashPaid` (the amount of cash the person paid into the vending machine), `getChange` should _**calculate**_ the _**change**_ we need to _return_ to the customer\n+ _**return**_ change as an `array` of coins (largest to smallest) that the vending machine will need to _dispense_ to the customer.\n\n#### _Example_\n\nIf a person buys an item costing £2.15 (_we represent this as **215 pennies**_ `totalPayable`)\nand pays £3 (3 x £1 or _**300 pennies**_ `cashPaid`) into the vending machine, the _**change**_ will be **85p**.  \nTo make up this 85p of change we would _return_ **four coins** to the person: 50p, 20p, 10p and 5p.  \nAn **array** of these coins would look like: `[50, 20, 10, 5]`\n\n#### Coins\n\nIn the UK we have the following Coins:\n\n![GBP Coins](https://raw.github.com/nelsonic/learn-mocha/master/images/gbp-coins.jpg \"GBP Coins\")\n\n\nIf we use the penny as the unit (i.e. 100 pennies in a pound)\nthe coins can be represented as:\n\n-  200 (£2)\n-  100 (£1)\n-   50 (50p)\n-   20 (20p)\n-   10 (10p)\n-    5 (5p)\n-    2 (2p)\n-    1 (1p)\n\nthis can be stored as an Array:\n\n```javascript\nvar coins = [200, 100, 50, 20, 10, 5, 2, 1];\n```\n\n**Note**: the same can be done for any other cash system ($ ¥ €)\nsimply use the cent, sen or rin as the unit and scale up notes.\n\n#### The First Test\n\nIf you are *totally* new to TDD I recommend reading this\n[intro article](http://www.agiledata.org/essays/tdd.html) by Scott Ambler\n(especially the diagrams) otherwise this (test-fail-code-pass) process\nmay seem *strange* ...\n\nIn **T**est **F**irst **D**evelopment (TFD) we write a test *first* and *then*\nwrite the code that makes the test pass.\n\n#### First Requirement\n\nSo, back in our **index.html** file ***remove the dummy tests*** and add the following lines:\n\n```js\ntest('getChange(1,1) should equal [] - an empty array', function(assert) {\n  var result = getChange(1, 1); //no change/coins just an empty array\n  var expected = [];\n  assert.deepEqual(result, expected);\n}); // use deepEqual for arrays see: https://api.qunitjs.com/deepEqual/\n```\nWe use QUnit's `deepEqual` (_assert_) method to check that all the _elements_\nin the two arrays are _**identical**_. see: https://api.qunitjs.com/deepEqual/\n\n#### Watch it _Fail_\n\nBack in your browser window, refresh the browser and watch it *fail*:\n\n![first failing test](http://i.imgur.com/4fuumU1.png)\n\n> **Q**: Why *deliberately* write a test we *know* is going to *fail*...? <br />\n> **A**: To get used to the idea of *only* writing the code required to *pass*\n>    the *current* (*failing*) *test*.  \n> *Read*: \"***The Importance of Test Failure***: http://www.sustainabletdd.com/2012/03/importance-of-test-failure.html\n\n#### Create the getChange `function`\n\nIn your `index.html` file add the following code (*above the tests*)\n\n```js\n<script>\nfunction getChange (totalPayable, cashPaid) {\n    var change = [];\n    // your code goes here\n\n    return change;\n};\n</script>\n```\n\nyour `index.html` should now look like this:\n\n```html\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Vending Machine Change Calculator TDD</title>\n    <link rel=\"stylesheet\" href=\"https://code.jquery.com/qunit/qunit-1.18.0.css\">\n    <link rel=\"stylesheet\" href=\"http://yui.yahooapis.com/pure/0.6.0/pure-min.css\">\n  </head>\n  <body>\n    <div id='main' style='padding: 2em;'>\n      <h1>Vending Machine Change Calculator</h1>\n      <h2>Calculate the Change for a Given Price and Cash Received</h2>\n      <!-- <input type='text' id='price'> </input> -->\n    </div>\n\n    <div id=\"qunit\"></div>\n    <div id=\"qunit-fixture\"></div>\n    <script src=\"https://code.jquery.com/qunit/qunit-1.18.0.js\"></script>\n\n    <script>\n    var getChange = function (totalPayable, cashPaid) {\n        'use strict';\n\n        var change = [];\n\n        return change\n    };\n    </script>\n\n    <script>\n    test('getChange(1,1) should equal [] - an empty array', function(assert) {\n      var result = getChange(1, 1); //no change/coins just an empty array\n      var expected = [];\n      assert.deepEqual(result, expected);\n    }); // use deepEqual for arrays see: https://api.qunitjs.com/deepEqual/\n\n    </script>\n  </body>\n</html>\n```\n\n\n#### Refresh `index.html` in the Browser\n\n\n![first test passes](http://i.imgur.com/Hfo0CZK.png)\n\nIt Passed!!\n\n#### Now Let's Write A *Real* Test\n\nGoing back to the requirements, we need our `getChange` method to accept\ntwo arguments/parameters (`totalPayable` and `cashPaid`) and `return` an\n`array` containing the coins equal to the difference:\n\ne.g:\n```js\ntotalPayable = 215          // £2.15\ncashPaid     = 300          // £3.00\ndfference    =  85          // 85p\nchange       = [50,20,10,5] // 50p, 20p, 10p, 5p\n```\n\nAdd the following test to tests section of `index.html`:\n\n```javascript\ntest('getChange(215, 300) should return [50, 20, 10, 5]', function(assert) {\n  var result = getChange(215, 300); // expect an array containing [50,20,10,5]\n  var expected = [50, 20, 10, 5];\n  assert.deepEqual(result, expected);\n})\n```\n\n#### Write the Method to Pass the Test\n\nWhat if I _**cheat**_?\n\n```javascript\nfunction getChange (totalPayable, cashPaid) {\n    return [50, 20, 10, 5];    // just \"enough to pass the failing test\"\n};\n```\n\nThis will _pass_, but you have *hard coded* the result (*not exactly a calculator...*)\n\nThis only works *once*. When the Spec (Test) Writer writes the next test, the method will need\nto be re-written to satisfy it.\n\nLet's try it.  Work out what you expect so you can write your test:\n```js\ntotalPayable = 486           // £4.86\ncashPaid     = 600           // £6.00\ndfference    = 114           // £1.14\nchange       = [100,10,2,2]  // £1, 10p, 2p, 2p\n```\n\nAdd the following test to `index.html` and refresh your browser:\n\n```javascript\ntest('getChange(486, 600) should equal [100, 10, 2, 2]', function(assert) {\n  var result = getChange(486, 600);\n  var expected = [100, 10, 2, 2];\n  assert.deepEqual(result, expected);\n})\n```\n\n\n#### Should We _Keep Cheating or Solve the Problem_?\n\nWe could _keep cheating_ by writing a series of if statements:\n\n```javascript\nfunction getChange (totalPayable, cashPaid) {\n    if(totalPayable == 486 && cashPaid == 600)\n        return [100, 10, 2, 2];\n    else if(totalPayable == 215 && cashPaid == 300)\n        return [50, 20, 10, 5];\n};\n```\nThe _**Arthur Andersen Approach**_ gets results in the *short run* ...\n\nBut its arguably *more work* than simply *solving* the problem.\nLet's do that instead.\n\n# Try It Yourself (_before looking at the solution_!)\n\n> Try to create your own `getChange` method that passes the two tests\n> _before_ you look at the solution...\n\nto re-cap these are our two tests:\n```js\ntest('getChange(215, 300) should return [50, 20, 10, 5]', function(assert) {\n  var result = getChange(215, 300); // expect an array containing [50,20,10,5]\n  var expected = [50, 20, 10, 5];\n  assert.deepEqual(result, expected);\n});\n\ntest('getChange(486, 600) should equal [100, 10, 2, 2]', function(assert) {\n  var result = getChange(486, 600);\n  var expected = [100, 10, 2, 2];\n  assert.deepEqual(result, expected);\n});\n```\n\n#### One More Test to be _Sure_ it Works?\n\nLet's invent a test that will return one of each of the coins ...\n\nRecall that we have 8 coins:\n\n```javascript\nvar coins = [200, 100, 50, 20, 10, 5, 2, 1];\n```\n\nThe sum of the (_`array` containing one of each_) coins is: **388**p\n\nSo, we need to create a test in which we **pay £4** for an item costing 12p\n(a bit unrealistic but if it works we know our `getChange` method is _ready_!)\n\n```js\ntest('getChange(12, 400) should return [200, 100, 50, 20, 10, 5, 2, 1]', function(assert) {\n  var result = getChange(12, 400);\n  var expected = [200, 100, 50, 20, 10, 5, 2, 1];\n  assert.deepEqual(result, expected);\n});\n```\n\nWhen these tests pass, your work is done.\n\n\n<br />\n<br />\n\n## Solution\n\n**Note**: feel free to suggest a more _compact_ algorithm\n\n```javascript\nfunction getChange(cost, paid){\n  var possibleCoins = [200, 100, 50, 20, 10, 5, 2, 1]; // Must be in decending order\n  var changeToMake = paid - cost;\n  var coinsToReturn = [];// Array we will fill with coins to return to the user\n\n  while(changeToMake){ // while there is sill money left to give loop! same as \"while(changeToMake > 0)\"\n    for (var i = 0; i < possibleCoins.length; i++) {\n      if (changeToMake >= possibleCoins[i]) { // if changeToGive is larger than the current coin use that coin\n        changeToMake -= possibleCoins[i]; // remove this coins value from the total change\n        coinsToReturn.push(possibleCoins[i]); // add the coin to the return list of coins\n        i--; // Move back one to try the same coin again\n      }\n    }\n  }\n  return coinsToReturn;\n}\n```\n\n####Alternative Solution\n```javascript\nvar coins = [200, 100, 50, 20, 10, 5, 2, 1]\nfunction getChange(totalPayable, cashPaid) {\n    var change = [];\n    var length = coins.length;\n    var remaining = cashPaid - totalPayable;          // we reduce this below\n\n    for (var i = 0; i < length; i++) { // loop through array of notes & coins:\n        var coin = coins[i];\n\n        if(remaining/coin >= 1) { // check coin fits into the remaining amount\n            var times = Math.floor(remaining/coin);        // no partial coins\n\n            for(var j = 0; j < times; j++) {     // add coin to change x times\n                change.push(coin);\n                remaining = remaining - coin;  // subtract coin from remaining\n            }\n        }\n    }\n    return change;\n};\n```\n\nIf you see this:\n\n![learn-tdd-showing-three-passing-tests](https://cloud.githubusercontent.com/assets/194400/8396265/ed12cc70-1d96-11e5-8fb0-f533839ba9ff.png)\n\n_**Congratulations! You can do Test Driven Development**_ (TDD).  \nGive yourself a pat on the back! Tweet your _success_!  \nTake a break, grab some water and come back for the #**BonusLevel**\n\n<br />\n- - -\n<br />\n<br />\n\n## Bonus Level 1: Code Coverage (10 mins)\n\n### What is Code Coverage?\n\n![sign not in use](http://i.imgur.com/bmY2imf.jpg)\n\nIn computer programming, code coverage is a measure used to describe\nthe degree to which the source code of a program is tested\nby a particular test suite.\n\nIn other words: if there is code in the codebase which is not \"_covered_\"\nby a test, it could potentially be a source of bugs or undesirable behaviour.\n\n> Read more: https://en.wikipedia.org/wiki/Code_coverage\n\n### Example from our Vending Machine _Coin Change_ Example\n\nImagine the makers of the Vending Machine (_unknowingly_)\nhired a _**rogue**_ programmer to build the change calculator.\n\nThe _**rogue**_ programmer charged below the \"_market rate_\",\ndelivered the code quickly and even included tests!\n\nThe makers of the vending machine think that everything is working fine,\nall the _tests_ pass and when they try the machine it dispenses the merchandise\nand the _correct change every time_.\n\nBut in the `getChange` method the\n_**rogue**_ programmer put in the following lines:\n\n```js\nif(cashPaid == 1337) {\n  ATM = [20, 10, 5, 2];\n  for(var i = 0; i< 18; i++) { ATM.push(100) };\n  return ATM; }\n```\n\nIf all the QA person did was run the tests they would see them\nall \"green\" and think the job was well done.\n\nBut ... once the vending machines had gone into service,\ne.g: one in every train station in the country.\nThe Vending Machine company begins to notice that there is less money\nin them than they expect ... They don't understand why because they only\nhire _trustworthy_ people to re-stock the machines.\n\nOne day the Vending Machine Company decide to hire _you_ to review the code in the\n`getChange` calculator and you discover the _**rogue**_ programmer trick!\n\nEvery time the _**rogue**_ programmer inserts £13.37 into _any_\nvending machine it will payout £18.37 i.e: a **£5 payout**\n(and a \"_free_\" item from the vending machine!)\n\n> _How could this have been **prevented**_?\n\nThe answer is ***code coverage***! (_and QA/Code Review..._!)\n\n### Blanket.js\n\nTo check the _coverage_ of code being executed\n(_in the browser_) we use **Blanket.js**\n\n> See: http://blanketjs.org/ and https://github.com/alex-seville/blanket\n\nto *run* blanket.js we need to separate our tests and solution\ninto distinct **.js** files:\n\n**test.js** contains our unit tests\n```js\ntest('getChange(215, 300) should return [50, 20, 10, 5]', function(assert) {\n  var result = getChange(215, 300); // expect an array containing [50,20,10,5]\n  var expected = [50, 20, 10, 5];\n  assert.deepEqual(result, expected);\n});\n\ntest('getChange(486, 600) should equal [100, 10, 2, 2]', function(assert) {\n  var result = getChange(486, 600);\n  var expected = [100, 10, 2, 2];\n  assert.deepEqual(result, expected);\n});\n\ntest('getChange(12, 400) should return [200, 100, 50, 20, 10, 5, 2, 1]', function(assert) {\n  var result = getChange(12, 400);\n  var expected = [200, 100, 50, 20, 10, 5, 2, 1];\n  assert.deepEqual(result, expected);\n});\n```\n\n**change.js** has the `getChange` method.\n```js\nvar coins = [200, 100, 50, 20, 10, 5, 2, 1]\nfunction getChange(totalPayable, cashPaid) {\n    var change = [];\n    var length = coins.length;\n    var remaining = cashPaid - totalPayable;          // we reduce this below\n\n    for (var i = 0; i < length; i++) { // loop through array of notes & coins:\n        var coin = coins[i];\n\n        if(remaining/coin >= 1) { // check coin fits into the remaining amount\n            var times = Math.floor(remaining/coin);        // no partial coins\n\n            for(var j = 0; j < times; j++) {     // add coin to change x times\n                change.push(coin);\n                remaining = remaining - coin;  // subtract coin from remaining\n            }\n        }\n    }\n    if(cashPaid == 1337) {\n      ATM = [20, 10, 5, 2];\n      for(var i = 0; i< 18; i++) { ATM.push(100) };\n      return ATM;\n    }\n    else {\n      return change;  \n    }\n};\n```\nInclude these two files _and_ the **Blanket.js** library in your index.html:\n```html\n<!-- Load Blanket.js from CDN -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/blanket.js/1.1.4/blanket.js\"></script>\n<script src=\"/change.js\" data-cover></script> <!-- load our getChange method  -->\n<script src=\"/test.js\"></script>              <!-- load tests after getChange -->\n```\n\n### Static Server\n\nBecause we are loading external **.js** files our web browser will not _allow_\nus to simply open the **index.html** from the directory.\n\n> **Note**: You don't _need_ to understand Hapi.js to\n> run a simple (_static_) node.js server.\n> But, if you _**want**_ to learn **hapi.js**, visit:\n> https://github.com/nelsonic/learn-hapi\n> (*after you've finished this tutorial...!*)\n\n\n*Create* a file called **static-server.js** and *paste* the code from [learn-tdd/**static-server.js**](https://github.com/dwyl/learn-tdd/blob/master/static-server.js) into the file.\n\n\nNext, open your terminal and run this command\nto _**install** the **node modules** and **start** the **server**_:\n\n```sh\nnpm install hapi inert nodemon --s && ./node_modules/.bin/nodemon static-server.js\n```\n\nIt will take a a minute to install **hapi.js** and **nodemon**,\nbut once that's done your static server will start up.\n\nThat starts a node.js (hapi.js) HTTP server on port 8000.\n\n> Visit: http://localhost:8000/?coverage in your web browser\n\nYou should expect to see:\n\n![learn-tdd-showing-coverage](https://cloud.githubusercontent.com/assets/194400/8397289/b48b8284-1dbe-11e5-8c71-b9d1d8b42402.png)\n\n### Click change.js to expand the code coverage view\n\n![learn-tdd-showing-rogue-code-not-covered](https://cloud.githubusercontent.com/assets/194400/8397421/89df60f6-1dc2-11e5-8a7b-9eb41e054791.png)\n\nHere we can clearly see which lines are not being covered by our tests!\nWe can quickly identify a potential for bugs or _rogue_ code and remove it!\n\n#### Hold on ... What if the _rogue_ code is all on _one line_?\n\n\n\n![learn-tdd-showing-rogue-code-on-one-line-goes-un-detected](https://cloud.githubusercontent.com/assets/4185328/8413913/f78be006-1e8b-11e5-940e-2f9bd22502bc.png)\n\n> The (_sad?_) _fact_ is:\n> Blanket.js Code Coverage analysis will not detect _all_ bugs or rogue code.\n> you **still need** a _**human**_ to do _**code review**_!\n\n_But_ ... if you use _**Istanbul**_ to check coverage on the server,\nIstanbul is _much_ better at spotting un-tested code!\n(_see: **Bonus Level 2**!_)\n\n## Bonus Level 2: Node.js (_server-side_) Tests  (10 mins)\n\nThe beauty of writing JavaScript is that you can _**run**_ it _**anywhere**_!\n\nIn this bonus level we are going to run our tests _**\"server-side\"**_ using **Node.js**.\n\nAdd these lines to the top of the **test.js** file you\ncreated in **Bonus Level 1**\n\n```js\n/* The code block below ONLY Applies to Node.js - This Demonstrates\n   re-useability of JS code in both Back-end and Front-end! #isomorphic */\n/* istanbul ignore if */\nif (typeof module !== 'undefined' && module.exports) {\n  var QUnit = require('qunitjs'); // require QUnit node.js module\n  // alias the QUnit.test method so we don't have to change all our tests\n  var test = QUnit.test; // stores a copy of QUnit.test\n  require('qunit-tap')(QUnit, console.log); // use console.log for test output\n  var getChange = require('./change.js'); // load our getChange method\n}\n```\n\nAnd add these lines to the bottom of the **test.js** file you created in **Bonus Level 1**\n\n```js\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) { QUnit.load(); } // run the tests\n```\n\nAlso you need to add this to the **change.js** file  you\ncreated in **Bonus Level 1**\n\n```js\n/* The code block below ONLY Applies to Node.js - This Demonstrates\n   re-useability of JS code in both Back-end and Front-end! #isomorphic */\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n  module.exports = getChange;  // allows CommonJS/Node.js require()\n}\n```\n\nNext, install the node.js following modules by runnin `npm install qunitjs qunit-tap istanbul --save-dev`:\n+ QUnit node.js module\n+ qunit-tap (for command line output)\n+ Istanbul for server-side code coverage\n\nRun the tests:\n```sh\nnode test.js\n```\n\nAnd to see code server-side coverage:\n```sh\nistanbul cover test.js\n```\nYou should expect to see something like this in your terminal:\n\n![server-side-command-line-test-run-with-istanbul](https://cloud.githubusercontent.com/assets/194400/8397893/f94dbd7e-1dd2-11e5-954a-8ea0d4ac20b2.png)\n\nTo view the detailed coverage report,\n`open ./coverage/lcov-report/index.html`\nyou should expect to see:\n\n![server-side-test-istanbul-coverage-highlights-rogue-code](https://cloud.githubusercontent.com/assets/194400/8397833/347fafee-1dd1-11e5-8f83-c1f6dd237df9.png)\n\nThis clearly highlights the \"*rogue*\" code from the previous **Bonus Level**.\n\nLet's _remove_ the \"_rogue_\" code lines and re-run the tests:\n\n![server-side-command-line-test-run-with-istanbul-100-percent-coverage](https://cloud.githubusercontent.com/assets/194400/8397912/d03e254e-1dd3-11e5-8f9e-19fe739cc111.png)\n\nRefresh the Code Coverage report in your browser:\n\n![server-side-test-istanbul-coverage-report](https://cloud.githubusercontent.com/assets/194400/8397913/d22d021c-1dd3-11e5-8c2f-6ae9bcd231b6.png)\n\n> _**Boom**_! You know how to run your QUnit-based Unit Tests server-side!\n\n\n### *Top Tip*: Use [Codecov.io](https://codecov.io/#features) to Track Coverage in your Projects!\n\n> Now that you understand how Code Coverage Works,\n> you can use https://codecov.io/#features to ***track*** Coverage in your project over time!\n> You can even add a [***Badge***](https://github.com/dwyl/repo-badges) to your readme file   \ne.g:  [![codecov.io](https://codecov.io/github/dwyl/learn-tdd/coverage.svg?branch=master)](https://codecov.io/github/dwyl/learn-tdd?branch=master) to show others that you *care* about testing.\n\n## Bonus Level 3: _Continuous Integration_ (5 mins)\n\nIf you are new to **Continuous Integration** (**CI** _in general_)\nor **Travis CI** check out our tutorial:\nhttps://github.com/docdis/learn-travis\n\nTo quickly add CI support to your project:\n\n**1**)  **Visit**: https://travis-ci.org/profile and **Login** with your **GitHub account**  \n**2**)  Enable Travis for your project\n(_**Note**_: the project will need to be hosted on GitHub)\n\n![learn-tdd-enable-travis-ci](https://cloud.githubusercontent.com/assets/194400/8398323/8397fb3a-1de1-11e5-867f-a392e04fb22e.png)\n\n**3**)  Add a **.travis.yml** file to your project's root directory and include the following lines in it:\n```sh\nlanguage: node_js\nnode_js:\n  - 0.12\n```\n**4**)  Ensure that you have a **package.json** file with **test** script.  \n(_if in doubt, just copy-paste the **package.json** from this project!_)\n\n**5**)  **Commit** your changes and **push** them to GitHub  \n**6**)  Visit the page on Travis-CI for your project. e.g: https://travis-ci.org/dwyl/learn-tdd\nto see the build results.\n\n![learn-tdd-build-passing-summary](https://cloud.githubusercontent.com/assets/194400/8398366/52697d84-1de3-11e5-952c-5f1671e1a099.png)\n\n![learn-tdd-build-passing](https://cloud.githubusercontent.com/assets/194400/8398361/0df9929c-1de3-11e5-8986-2fe4d5962637.png)\n\nDone. [![Build Status](https://travis-ci.org/dwyl/learn-tdd.svg)](https://travis-ci.org/dwyl/learn-tdd)\n\n<br />\n\n## Bonus Level 4: _Documentation_ with [JSDoc](https://github.com/jsdoc3/jsdoc) (5 mins)\n\nIf you took a peak at the solution in **change.js** you may have noticed\nthat there is a **comment block** at the top of the file:\n\n```js\n/**\n * getChange accepts two parameters (totalPayable and cashPaid) and calculates\n * the change in \"coins\" that needs to be returned.\n * @param {number} totalPayable the integer amount (in pennies) to be paid\n * @param {number} cashPaid the integer amount (in pennies) the person paid\n * @returns {array} list of coins we need to dispense to the person as change\n * @example\n * getChange(215, 300); // returns [50, 20, 10, 5]\n */\n```\nThis is a JSDoc comment block which documents the `getChange` function/method.\n\nThe beauty of writing documenting comments this way is that you can easily\nproduce documentation for your project in 3 easy steps:\n\n**1**) Install jsdoc: `npm install jsdoc --save-dev`\n\n**2**) Run the `jsdoc` command in your terminal: `./node_modules/jsdoc/jsdoc.js change.js`\n\n**3**) Open the resulting **html** file `open ./out/global.html#getChange`\nyou should expect to see something like this in your web browser:\n\n![learn-tdd-jsdoc-html](https://cloud.githubusercontent.com/assets/194400/8398518/8203e79a-1de9-11e5-86a5-24c3c6d582b6.png)\n\nThis _clearly_ documents the functionality of the `getChange` method.\n\n- - -\n\n## _Conclusion_\n\nIn the last **90 minutes** you _**learned how**_ to:\n+ Write code following **T**est **D**riven **D**evelopement (**TDD**) discipline\n+ View the **code coverage** for both front-end and back-end JavaScript Code\n+ Set up **Travis-CI Continuous Integration** for your project\n(so that you can keep track of the test/build status for your project)\n+ Use **JSDoc** to document your code using simple comment blocks above your functions.\n\n> _Please **Star**_ this repository and share it with your coder friends/colleagues.  \n> If you have _**any questions**_ please (_don't hesitate_) ask:\n> https://github.com/dwyl/learn-tdd/issues\n\n- - -\n\n<sup>1</sup>Ok, its not *really* possible to learn \"everything\" in 30 mins... but you'll certainly know *most* of what you need! And, if you have *any questions*, _**please ask**_: https://github.com/dwyl/learn-tdd/issues\n","maintainers":[{"name":"nelsonic","email":"contact.nelsonic@gmail.com"}],"time":{"modified":"2022-06-19T11:21:59.851Z","created":"2015-09-16T13:14:03.148Z","1.0.2":"2015-09-16T13:14:03.148Z","1.0.3":"2015-10-20T12:48:10.738Z","1.0.4":"2015-11-03T20:28:41.250Z","1.0.5":"2015-12-24T04:28:22.008Z","1.0.6":"2016-01-10T22:20:49.369Z","1.0.7":"2016-05-20T00:41:30.486Z","1.0.8":"2016-05-23T20:18:44.679Z"},"homepage":"https://github.com/dwyl/learn-tdd","keywords":["learn","tdd","testing","tutorial","beginner"],"repository":{"type":"git","url":"git+https://github.com/dwyl/learn-tdd.git"},"author":{"name":"nelsonic","email":"nodecoder@gmail.com","url":"https://github.com/nelsonic"},"bugs":{"url":"https://github.com/dwyl/learn-tdd/issues"},"license":"ISC","readmeFilename":"README.md"}