{"id":556,"date":"2016-05-27T15:28:27","date_gmt":"2016-05-27T13:28:27","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=556"},"modified":"2023-06-07T11:42:57","modified_gmt":"2023-06-07T09:42:57","slug":"test-driven-development-with-node-js","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/05\/27\/test-driven-development-with-node-js\/","title":{"rendered":"Test Driven Development with Node.js"},"content":{"rendered":"<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/wordcloud.jpg\"><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/wordcloud.jpg\" alt=\"\"><\/a><br \/>\n<em>[written by Roman Kollatschny and Matthias Schmidt]<\/em><\/p>\n<p>This is a series of blog posts which addresses different development topics like test driven development, code style and code quality for the <a href=\"https:\/\/nodejs.org\/\">Node.js<\/a> runtime.<br \/>\nThe series requires some basic knowledge about JavaScript, Node.js and basic webdevelopment techniques in general.<br \/>\nIt will start with this first article about test driven development on Node.js using the tools <a href=\"https:\/\/mochajs.org\/\">Mocha<\/a> and <a href=\"http:\/\/chaijs.com\/\">Chai<\/a>.<\/p>\n<p>Most of us have heard something of test driven development, but only a very few know the methods of this development style and even less do really develop test driven. Since we only have heard the principles of testing in software development but never really were able to use them in practice, we decided to dive into this topic. To give you also a benefit of our diving experience, we want to show you, how to develop test driven.<\/p>\n<p><!--more--><\/p>\n<p>Test driven development or TDD is a process in software development. The process evolved from the test-first programming concept of extreme programming. In comparison to classic development the test cases are defined before the application implementation starts.<\/p>\n<p>The TDD tests are written as grey-box tests. That means, that they contain parts form white and from black-box tests. Black-box tests are written without the knowlege of the inner functions of the system that is tested. It is limited on function-oriented testing, so tests only base on the requirements. The system is treated as a black box where only information which is accessible from the outside influences the test. However white-box tests are definded with the knowlege of how the systems is implemented.<\/p>\n<p>The grey-box and white-box tests share in common, that they are implemented by the same developers, that implement the system later.<\/p>\n<p>Black-box tests are definded whitout awareness of the internal structure of the application to be tested, while a white-box test needs knowlege of the internal structure or even developed by the application developer itself. A grey-box test is written with some knowledge of the internal structure, because the test developer also implements the application following the tests.<\/p>\n<p>If you want to develop test driven you have to follow some process according to the TDD cycle.<\/p>\n<h2>TDD cycle<\/h2>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development#\/media\/File:TDD_Global_Lifecycle.png\"><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/01\/TDD_Global_Lifecycle.png\" alt=\"TDD Cycle\"><\/a><br \/>\nTDD Cycle<\/p>\n<p>The test driven development cycle consists of 5 easy steps:<\/p>\n<ol>\n<li><strong>Add a test<\/strong><br \/>\nWrite a test case to cover the requirements of our application. For the first iteration your test should be as small as possible.<\/li>\n<li><strong>Run the test<\/strong><br \/>\nAfter defining our test we&#8217;re going to execute the test against the application. The test should not pass because the requirement isn&#8217;t implemented yet.<\/li>\n<li><strong>Write the code<\/strong><br \/>\nTo fix this it&#8217;s time to implement the least necessary code in our application. Don&#8217;t do too much! Only the really necessary parts should be implemented.<\/li>\n<li><strong>Run the test again<\/strong><br \/>\nIf we run the previous defined test again the test should pass. Otherwise we have to go over the code again until it passes.<\/li>\n<li><strong>Refactor the code<\/strong><br \/>\nWhen the test passes we should do some code refactoring to keep our code clean and slim.<\/li>\n<\/ol>\n<p><strong>Repeat<\/strong><br \/>\nFor each requirement of our application the previous steps need to be repeated until all functionalities are implemented and all tests pass.<\/p>\n<p>But TDD as a whole is more than only this process. A big and meaningful part is the developers mindset. At the beginning it may sound weird to develop the TDD way, but later it will become more clear why it&#8217;s done that way. If your&#8217;re interested in learning TDD give it a try and stop thinking about the differences for the moment &#8211; we know, this is one of the hardest parts.<\/p>\n<h2>TDD in Node.js<\/h2>\n<p>There are multiple ways to work with TDD in Node.js. You can use the integrated assertion library or choose a framwork like Jasmine. In this article series we want to focus on the test runner Mocha and the assertion library Chai.<\/p>\n<h3>Mocha<\/h3>\n<blockquote><p>\n  Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. &#8211; Mochajs.org<\/p><\/blockquote>\n<p>Mocha can be used with different assertion libraries like should.js, expect.js, better-assert, unexpected or Chai.<\/p>\n<p>Mocha executes our defined tests on the code and reports the results to us. An quick start guide and the documentation can be found on <a href=\"https:\/\/mochajs.org\/#getting-started\">mochajs.org<\/a>.<\/p>\n<h3>Chai<\/h3>\n<blockquote><p>\n  Chai is a BDD \/ TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework. &#8211; Chaijs.org<\/p><\/blockquote>\n<p>Chai.js is a assertion library with different included styles the developer can choose from. This includes assert, should and expect style. Chai can be extended by using some plugins, e.g. for web requests or file system access.<\/p>\n<p>In the following we are using the behaviour driven development (BDD) style &#8216;expect&#8217; where tests are written from a business perspective. A complete overview of the chai api can be found on <a href=\"http:\/\/chaijs.com\/api\/\">chaijs.com<\/a>.<\/p>\n<h3>Testing syntax<\/h3>\n<p>With our test runner Mocha we can specify a test suite and a test case. A test suite is a collection of multiple test cases. For example there is a test suite of a class in an application.<\/p>\n<p>A <strong>test suite<\/strong> can be definded with the <code class=\"\" data-line=\"\">describe<\/code> method of Mocha. The first argument for this method is a string which describes the test suite, e.g. &#8216;database tests&#8217;. The second argument is an simple callback function, which includes the definded test cases.<br \/>\nIt is also possible to nest these blocks to get a more detailed structure.<br \/>\nExample:<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"test\/test.js\">describe('database tests', function() {\n  describe('users table tests', function () {\n    \/\/ Test cases\n  }\n}<\/pre>\n<p>A <strong>test case<\/strong> is one single requirement of the test suite. The test case includes the actual test functions.<br \/>\nTest cases are defined with the <code class=\"\" data-line=\"\">it<\/code> method from Mocha. This method uses also a string argument for its description. The second argument is again an function block which includes the test functions.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"3-5\" data-caption=\"test\/test.js\">describe('database tests', function() {\n  describe('users table tests', function () {\n    it('returns an array', function(){\n      \/\/ test functions\n    });\n  }\n}<\/pre>\n<p>To define the tests, we need an assertion library. As stated, we are going to use Chai. Chai provides three different assertion styles: <strong>should<\/strong>, <strong>expect<\/strong> and <strong>assert<\/strong>. The chainable behaviour driven development style of should and expect provide an expressive language and a more human-readable style. Otherwise the assert style has a more classic approach.<\/p>\n<p>Before defining the test functions, it&#8217;s necessary to import the module via <code class=\"\" data-line=\"\">require<\/code> and choose your preferred assertion style.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"3-5\" data-caption=\"test\/test.js\">let expect = require('chai').expect;<\/pre>\n<p>The expect syntax uses the method <code class=\"\" data-line=\"\">expect<\/code>. It needs an argument on which will be tested. To test the given argument, the test functions can be chained with the following parts:  <code class=\"\" data-line=\"\">to<\/code>, <code class=\"\" data-line=\"\">be<\/code>, <code class=\"\" data-line=\"\">been<\/code>, <code class=\"\" data-line=\"\">is<\/code>, <code class=\"\" data-line=\"\">that<\/code>, <code class=\"\" data-line=\"\">which<\/code>, <code class=\"\" data-line=\"\">and<\/code>, <code class=\"\" data-line=\"\">has<\/code>, <code class=\"\" data-line=\"\">have<\/code>, <code class=\"\" data-line=\"\">with<\/code>, <code class=\"\" data-line=\"\">at<\/code>, <code class=\"\" data-line=\"\">of<\/code>, same. All possible test methods are listed in the <a href=\"http:\/\/chaijs.com\/api\/bdd\/\">chai.js API Reference<\/a>.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"3-5\" data-caption=\"test\/test.js\">expect(users).to.be.an('array')\n  .and.is.not.empty();<\/pre>\n<p>In this example we run our tests synchronously. To run them asynchronously we have to add a callback function (e.g. <code class=\"\" data-line=\"\">done();<\/code> like in <a href=\"https:\/\/mochajs.org\/#asynchronous-code\" title=\"\">Mocha examples<\/a>).<\/p>\n<p>In the <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/06\/10\/test-driven-development-part-ii\/\" title=\"\">next blog article<\/a> we are going to adapt the TDD cylce in an little helloWorld example.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Test-Driven Development with Mocha and Chai in Node.js<\/p>\n","protected":false},"author":24,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[262,651,2],"tags":[25,23],"ppma_author":[695],"class_list":["post-556","post","type-post","status-publish","format-standard","hentry","category-rich-media-systems","category-system-designs","category-system-engineering","tag-nodejs","tag-tdd"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":1190,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/29\/test-driven-development-part-iv\/","url_meta":{"origin":556,"position":0},"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":1876,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/03\/03\/building-an-hdm-alexa-skill-part-3\/","url_meta":{"origin":556,"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":1807,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/02\/16\/building-a-hdm-alexa-skill-part-1\/","url_meta":{"origin":556,"position":2},"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":[]},{"id":632,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/26\/test-driven-development-part-iii\/","url_meta":{"origin":556,"position":3},"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":623,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/06\/10\/test-driven-development-part-ii\/","url_meta":{"origin":556,"position":4},"title":"Test Driven Development Part II","author":"Matthias Schmidt","date":"10. June 2016","format":false,"excerpt":"[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\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":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":556,"position":5},"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":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":695,"user_id":24,"is_guest":0,"slug":"rk056","display_name":"Roman Kollatschny","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/4794e26becfdb5a481ddc2d7566d2a042b6df5d0001da65f191acde983f91c6d?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\/556","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\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=556"}],"version-history":[{"count":24,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/556\/revisions"}],"predecessor-version":[{"id":24667,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/556\/revisions\/24667"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=556"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=556"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=556"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=556"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}