{"id":623,"date":"2016-06-10T09:33:08","date_gmt":"2016-06-10T07:33:08","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=623"},"modified":"2023-06-07T11:45:04","modified_gmt":"2023-06-07T09:45:04","slug":"test-driven-development-part-ii","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/06\/10\/test-driven-development-part-ii\/","title":{"rendered":"Test Driven Development Part II"},"content":{"rendered":"<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/06\/mocha-chai.jpg\"><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/06\/mocha-chai.jpg\" alt=\"\"><\/a><br \/>\n<em>[written by Roman Kollatschny and Matthias Schmidt]<\/em><\/p>\n<p>Welcome back to the second article in our Node.js development series. Today, we are going to adapt the TDD cycle in an helloWorld example application. If you missed our first article about the principles of TDD, you can find it <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/05\/27\/test-driven-development-with-node-js\/\">here<\/a>.<\/p>\n<p>In the last  article, we learnd about the fundamentals of the test driven development process. That involved the five steps of the TDD cycle, which have to be repeated until the completion of the application. We also had a look at our two frameworks <a href=\"https:\/\/mochajs.org\/\">Mocha<\/a> and <a href=\"http:\/\/chaijs.com\/\">Chai<\/a> that we are using in this tutorial.<\/p>\n<p>Let&#8217;s code!<br \/>\n<!--more--><\/p>\n<h2>TDD example coding<\/h2>\n<p>In our tutorial, we want to implement a simple and well known hello World application. Further we want to extend the funcitonality to greet you or others by their name. Before starting with our tutorial, we have to do some initial stuff.<\/p>\n<h3>Create our application structure<\/h3>\n<p>Prerequirements: We need a working <a href=\"https:\/\/nodejs.org\/en\/\">Node.js runtime<\/a> on our system.<br \/>\nFor the structure of the example application it&#8217;s necessary to create some files and folders and then install the required Node-modules. There are a few steps to follow:<\/p>\n<ul>\n<li>creating a folder <code class=\"\" data-line=\"\">node-tdd-tutorial<\/code> and switching into it<\/li>\n<li>executing <code class=\"\" data-line=\"\">npm init<\/code> in the console to create a package.json file\n<ul>\n<li>we can leave all values on default by simply pressing enter<\/li>\n<\/ul>\n<\/li>\n<li>installing mocha globally by executing <code class=\"\" data-line=\"\">npm install -g mocha<\/code><\/li>\n<li>installing chai locally with <code class=\"\" data-line=\"\">npm install -save chai<\/code><\/li>\n<li>creating two folders <em>app<\/em> and <em>test<\/em><\/li>\n<li>creating two empty files <em>app\/app.js<\/em> and <em>test\/test.js<\/em> inside the just created folders<\/li>\n<\/ul>\n<p>As result we should get the following structure.<\/p>\n<pre class=\"prettyprint\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">node-tdd-tutorial:\n\u2502   package.json\n\u2502   \n\u251c\u2500\u2500\u2500app\n\u2502       app.js\n\u2502       \n\u251c\u2500\u2500\u2500node_modules\n\u2502       ...\n\u2502                       \n\u2514\u2500\u2500\u2500test\n        test.js<\/pre>\n<p>Now our application structure is ready and we can start coding. (Take a look at the current state by viewing the <a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/8a134eb6c396f4152274e57e76822622386db3fe\">Github commit<\/a>)<\/p>\n<h3>First iteration<\/h3>\n<p>For every requirement of our application, we have to walk through an interation of the TDD cycle (you may remember from our <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/05\/27\/test-driven-development-with-node-js\/\">first blog post<\/a>).<br \/>\nIn the first iteration, we want to implement the requirement, that our application simply returns the string &#8216;Hello World&#8217;.<\/p>\n<h4>Writing our first test (TDD cylce #1)<\/h4>\n<p>In our first test case we test if our application returns a string which is equal to &#8216;Hello World&#8217;.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"test\/test.js\">'use strict';\n\nlet expect = require('chai').expect;\nlet App = require('.\/..\/app\/app.js');\n\ndescribe('helloWorld app testsuite', function (); {\n\n  it('returns the string \"Hello World\"', function (); {\n\n    expect(App)\n      .to.be.a('string')\n      .and.is.equal('Hello World');\n\n  });\n\n});\n<\/pre>\n<p>The <strong>first step<\/strong> in the first iteration of the TDD cycle is completed. (<a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/da343c13dea36a0e5fcf3b3049f5c6d691eb16c1\">Github commit<\/a>)<\/p>\n<h4>Run our first test (TDD Cycle #2)<\/h4>\n<p>Now we run the test by executing the command <code class=\"\" data-line=\"\">mocha<\/code>. The test fails as it should and we can tick the <strong>second step<\/strong> in the TDD cycle.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/node-tdd-tutorial-fail-test.jpg\" alt=\"Failing first test\"><br \/>\nFailing the first test<\/p>\n<h4>Writing code so the test succeeds (TDD Cycle #3 &#8211; #5)<\/h4>\n<p>To complete the <strong>third cycle step<\/strong> we have to implement our code to fulfill our requirements and pass the failed test.<\/p>\n<p>It&#8217;s time to edit our file app\/app.js. We use the simpliest way to pass the test. This is by assigning the expected string to the <code class=\"\" data-line=\"\">module.exports<\/code>-object. (<a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/4942d86fe56766da969c9f2b3e0afe1aa7324f0d\">Github commit<\/a>)<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"app\/app.js\">'use strict';\n\nmodule.exports = 'Hello World';<\/pre>\n<p>If we now run the test again it should pass. And <strong>step four<\/strong> is done. It&#8217;s significant to mind the importance of the steps two to four in the exactly order.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/node-tdd-tutorial-pass-test.jpg\" alt=\"Passing the first test\"><br \/>\nPassing the first test<\/p>\n<p>At this point we could refactor our code to keep it clean and optimize it. But because we have only a few lines of code there is no need of refactoring and we can skip it this time. <strong>Step five<\/strong>, check.<\/p>\n<h3>Second Iteration<\/h3>\n<p>In the second iteration we want to fulfill another requirement.<\/p>\n<p>We have to repeat the steps one to five until all application requirements are met. In the following steps we will implement the real application instead of a single string return.<\/p>\n<h4>Writing more tests to expand functionality<\/h4>\n<p>Our application returns &#8216;Hello World&#8217; and needs to be extended with the possibility to greet a user by its name.<\/p>\n<p>We define a second test for the requirement that our function returns &#8216;Hello John&#8217;.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"test\/test.js\">it('returns the string \"Hello John\"', function() {\n\n    expect(App)\n      .to.be.a('string')\n      .and.is.equal('Hello John');\n\n});<\/pre>\n<p>(<a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/cd5f08198cfc7d361e5a56e27c928ed76525835c\">Github commit<\/a>)<\/p>\n<p>As expected according to the development cycle our test fails because the returned string didn&#8217;t match our expected string &#8216;Hello John&#8217;.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/node-tdd-tutorial-fail-test_2.jpg\" alt=\"Failing the Tests\"><br \/>\nFailing the tests<\/p>\n<h4>Code again<\/h4>\n<p>To fix this we implement a class with two functions that return either &#8216;Hello World&#8217; or &#8216;Hello John&#8217;.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"app\/app.js\">class Hello {\n\n  helloWorld() {\n    return 'Hello World';\n  }\n\n  helloJohn() {\n    return 'Hello John';\n  }\n}\n\nmodule.exports = Hello;<\/pre>\n<p>The test fails because we have implemented our class but our test cases still expects a single string. We have to update our test case to execute the proper class functions.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"1,7,15\" data-caption=\"test\/test.js\">let hello = new App();\n\ndescribe('helloWorld app testsuite', function() {\n\n  it('returns the string \"Hello World\"', function() {\n\n    expect(hello.helloWorld())\n      .to.be.a('string')\n      .and.is.equal('Hello World');\n\n });\n\n  it('returns the string \"Hello John\"', function() {\n\n    expect(hello.helloJohn())\n      .to.be.a('string')\n      .and.is.equal('Hello John');\n\n  });\n\n});<\/pre>\n<p>If we execut <code class=\"\" data-line=\"\">mocha<\/code> our test passes again. (<a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/09228a00843c6fa44e9308ac62b4f05cbba92ea9\">Github commit<\/a>)<\/p>\n<p>Now we are able to refactor our code to clean and optimize it.<\/p>\n<h4>Refactor<\/h4>\n<p>To remove unnecessary code and keep it clean we try to combine functions if possible. So we removed the helloJohn and helloWorld functions and added the needed functionality to cover the requirements. Instead of separete functions we only have one left (<a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\/commit\/8b20cf6aeb73963e449e5aed347ee43f60e332d0\">Github commit<\/a>).<\/p>\n<p>As result we have an application that is able to greet the world or a person by its name. It meets the previous defined requirements and therefore has gone two times through the TDD cycle. Since we have hard coded the returning name it&#8217;s necessary to do some more work to finish.<br \/>\nStep five, check.<\/p>\n<h3>Last Iteration<\/h3>\n<p>Last but not least we have our third iteration of the TDD cycle.<\/p>\n<h4>Adding the third test and code until it passes<\/h4>\n<p>The last requirement is the possibility to define the returning name. Therefore we have to add one more test case.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"test\/test.js\">it('returns the string \"Hello Joe\" where Joe is passed as a variable', function() {\n\n  expect(hello.hello('Joe'))\n    .to.be.a('string')\n    .and.is.equal('Hello Joe');\n\n});<\/pre>\n<p>As we run the test it fails first. Then we have to extend our application code until the test passes. Now the code should cover all defined requirements and our helloWorld tutorial application is completed.<\/p>\n<p>Congratulations! You may have finished your first application with test driven development! You can take a look at the finished tutorial code on <a href=\"https:\/\/github.com\/RomanKol\/node-tdd-tutorial\">Github<\/a>.<\/p>\n<p>What are your thoughts on this approach? Will you use TDD again? You may put your thoughts into the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[written by Roman Kollatschny and Matthias Schmidt] Welcome back to the second article in our Node.js development series. Today, we are going to adapt the TDD cycle in an helloWorld example application. If you missed our first article about the principles of TDD, you can find it here. In the last article, we learnd about [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[651,2],"tags":[25,23],"ppma_author":[666],"class_list":["post-623","post","type-post","status-publish","format-standard","hentry","category-system-designs","category-system-engineering","tag-nodejs","tag-tdd"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":556,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/05\/27\/test-driven-development-with-node-js\/","url_meta":{"origin":623,"position":0},"title":"Test Driven Development with Node.js","author":"Roman Kollatschny","date":"27. May 2016","format":false,"excerpt":"Test-Driven Development with Mocha and Chai in Node.js","rel":"","context":"In &quot;Rich Media Systems&quot;","block_context":{"text":"Rich Media Systems","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/rich-media-systems\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1876,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/03\/03\/building-an-hdm-alexa-skill-part-3\/","url_meta":{"origin":623,"position":1},"title":"Building an HdM Alexa Skill \u2013 Part 3","author":"je052","date":"3. March 2017","format":false,"excerpt":"We present our own HdM Alexa Skill and share the experience we gained throughout this project. This time: Developing the skill using Test-driven Development.","rel":"","context":"In &quot;Student Projects&quot;","block_context":{"text":"Student Projects","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/student-projects\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/test_coverage.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/test_coverage.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/test_coverage.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/test_coverage.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/test_coverage.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":1190,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/29\/test-driven-development-part-iv\/","url_meta":{"origin":623,"position":2},"title":"Test Driven Development Part IV","author":"Matthias Schmidt","date":"29. July 2016","format":false,"excerpt":"[written by Roman Kollatschny and Matthias Schmidt] Welcome back to our fourth and final post in our series. This time we want to deal with code style and code quality to optimize coding on additional ways. You\u2019re new? Hop to the first, second or third post so you don\u2019t miss\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1740,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/12\/09\/snakes-exploring-pipelines-a-system-engineering-and-management-project-3\/","url_meta":{"origin":623,"position":3},"title":"Snakes exploring Pipelines &#8211; A \u201cSystem Engineering and Management\u201d Project","author":"Yann Loic Philippczyk","date":"9. December 2016","format":false,"excerpt":"Part 2: Initial Coding This series of blog entries describes a student project focused on developing an application by using methods like pair programming, test driven development and deployment pipelines. Onwards to the fun part: The actual coding! In this blog entry, we will focus on test-driven development. Like we\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"A snake looking forward towards the next task, after having performed several incremental test-driven programming iterations Source: http:\/\/cdn1.arkive.org\/media\/0F\/0F35A02E-58A1-408B-B259-88C1E319B1C3\/Presentation.Large\/Curl-snake-coiled.jpg","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/12\/entry2-snake.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/12\/entry2-snake.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/12\/entry2-snake.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":632,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/26\/test-driven-development-part-iii\/","url_meta":{"origin":623,"position":4},"title":"Test Driven Development Part III","author":"Matthias Schmidt","date":"26. July 2016","format":false,"excerpt":"[written by Roman Kollatschny and Matthias Schmidt] Uhwe, hello and welcome back to the third of our posts in this series. Today we want to show you additional features and tipps on developing a node.js web application test driven. As stated in the last article we use Mocha.js and Chai.js\u2026","rel":"","context":"In &quot;System Designs&quot;","block_context":{"text":"System Designs","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1807,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/02\/16\/building-a-hdm-alexa-skill-part-1\/","url_meta":{"origin":623,"position":5},"title":"Building a HdM Alexa Skill &#8211; Part 1","author":"Eric Schmidt","date":"16. February 2017","format":false,"excerpt":"We present our own HdM Alexa Skill and share the experience we gained throughout this project.","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/chatbot.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/chatbot.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/chatbot.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/chatbot.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/chatbot.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":666,"user_id":21,"is_guest":0,"slug":"ms435","display_name":"Matthias Schmidt","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/06dcaaca4cf8e3dca153ac8a8454e5a5b76fb2a980d15e094b9b11bf5639ce53?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=623"}],"version-history":[{"count":6,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/623\/revisions"}],"predecessor-version":[{"id":24669,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/623\/revisions\/24669"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=623"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}