{"id":632,"date":"2016-07-26T13:04:30","date_gmt":"2016-07-26T11:04:30","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=632"},"modified":"2023-06-07T15:09:06","modified_gmt":"2023-06-07T13:09:06","slug":"test-driven-development-part-iii","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/26\/test-driven-development-part-iii\/","title":{"rendered":"Test Driven Development Part III"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/tdd-iii-header.jpg\" alt=\"head\"><br \/>\n<em>[written by Roman Kollatschny and Matthias Schmidt]<\/em><\/p>\n<p>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 as tools.<\/p>\n<p><!--more--><\/p>\n<p>You can take a look at our <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/05\/27\/test-driven-development-with-node-js\/\">first<\/a> and <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/06\/10\/test-driven-development-part-ii\/\">second<\/a> article to read some introduction if you missed it.<\/p>\n<h1>Mocha extended<\/h1>\n<p>In the last article, we let all of our test run synchronous, but Mocha.js allows us to run the test also asynchronously. To do this, we have to add a simple callback to our <code class=\"\" data-line=\"\">it()<\/code> function as shown in the following example:<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">describe('an example testsuite', function() {\n  it('is a exapmle testcase', function(done) {\n   anAsyncFunction(done)\n  });\n});\n<\/pre>\n<p>With hooks it\u2019s possible to execute commands before or after some test cases to prepare or clean up. Especially in combination with database tests it can be helpful to get always the same conditions. <code class=\"\" data-line=\"\">before<\/code> and <code class=\"\" data-line=\"\">after<\/code> run only once, <code class=\"\" data-line=\"\">beforeEach<\/code> and <code class=\"\" data-line=\"\">afterEach<\/code> run every time before or after each single test case. They are not only usable for database access but also for every other repeating task.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">describe('a testsuite for hooks', function() {\n  beforeEach(\u2018testcase\u2019, function() {\n    return doSomething();\n  });  \n});\n<\/pre>\n<p>Mocha also supports various output styles, from which you can choose. There are e.g. spec, list, nyan, progress, markdown and html reporters available. The default reporter is spec. You can a other report style by calling <code class=\"\" data-line=\"\">mocha -R &lt;style&gt;<\/code>.<br \/>\nThe following image shows the default, list, dot and json reporter with our application of the last article.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/tdd-iii-reporter.jpg\" alt=\"reporters\"><\/p>\n<h1>Database access<\/h1>\n<p>If we want to use mongodb and mongoose as our database model in our application, we can also write tests for that.<br \/>\nTherefore we have to specify our mongodb URI and load mongoose packge in our test. In this example we want simply test if our db connection works and if we have the permissions to read and write to it. We create a simple dummy model to test with.<\/p>\n<h2>Preparations for the mongodb tests<\/h2>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">var dbURI = 'mongodb:\/\/localhost\/your-db;   \/\/ Define our database URI\nvar expect = require('chai').expect;        \/\/ Load chai.js with expect style\nvar mongoose = require('mongoose'); \/\/ Load mongoose\n\n\/\/ Creating a simple dummy model \nvar dummy = mongoose.model(\u2018dummy\u2019, new mongoose.Schema(\n  {a: Number}\n);\n<\/pre>\n<h2>Pre and after hooks for connection and db clearing<\/h2>\n<p>In the case of this tests, we can use the hooks to check if we have a connection to the database by using the <code class=\"\" data-line=\"\">beforeEach()<\/code> hook. To clear our database after all tests are done, we can use the <code class=\"\" data-line=\"\">after()<\/code> hook.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">describe(\"DB Check\", function() {\n\n  beforeEach(function(done) {\n    if (mongoose.connection.db) return done();\n\n    mongoose.connect(dbURI, done);\n  });\n\n  after(function(done) {\n    mongoose.connection.collections[\u2018dummy\u2019].drop(done);\n  });\n});\n<\/pre>\n<h2>Writing to the database<\/h2>\n<p>To test our write permisson, we have to add our first test. To do this we create and save a new dataset on the database. Since our database queries are asynchronous, we have to use the <code class=\"\" data-line=\"\">done()<\/code> callback as explained earlier in our save method.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">describe(\"DB Check\", function() {\n\n  \/\/\u2026 hooks\n\n  it(\"saves our data\", function(done) {\n    new dummy({a: 1}).save(done);\n  });\n\n});\n<\/pre>\n<h2>Reading from the database<\/h2>\n<p>After we checked for writing permission, we also have to check for our reading permission. So we add a second testcase for that. In this testcase we try to query for documents in the dummy database and check, if the database holds at least one record.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">describe(\"DB Check\", function() {\n\n  \/\/\u2026 hooks and save testcase\n\n  it(\"queries our database\", function(done) {\n    dummy.find({}, (err, docs) =&gt; {\n      if (err) return done(err);\n\n      expect(docs).to.have.length.least(1);\n      done();\n    });\n  });\n\n});\n<\/pre>\n<p>Additional to our simple tests it\u2019s possible to e.g. test if the database model meets the requirements or use existing models.<\/p>\n<h1>HTTP requests<\/h1>\n<h2>Testing HTTP requests<\/h2>\n<p>For testing http requests, we use the <a href=\"https:\/\/www.npmjs.com\/package\/chai-http\">chai-http<\/a> plugin.<\/p>\n<p>To have access to the plugin, we load and register it with chai. This is done by the following code:<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">var chai = require('chai'),\n  chaiHttp = require('chai-http');\n\n  chai.use(chaiHttp);\n<\/pre>\n<p>Before we can define our test cases we have to inform the plugin about our webserver configuration &#8211; either by using our app instance or by passing an URL to it:<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">chai.request(app)\n\/\/ or\nchai.request('http:\/\/localhost:8080')\n<\/pre>\n<p>Depending on the desired request method, we can chain functions like get, post, put with the corresponding path. It\u2019s also possible to chain functions like send (for sending json objects), query (for defining get parameters), attach (for attaching files) or auth (for authentication) for easier or extended requests.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">chai.request(app)\n  .get(\u2018\/website\u2019) \/\/ Website path\n  .query({search: \u2018hdm\u2019}) \/\/ GET request to \/website?search=hdm\n<\/pre>\n<p>After specifying our request, we have to deal with the response. Therefore we use the method .end(). The end method expects two parameters, an <em>error<\/em> and an <em>response<\/em> object which are handled by a callback function.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">chai.request(app)\n  .get(\u2018\/\u2019)\n  .end((err, res) =&gt; {\n    \/\/ Tests here\n  });\n<\/pre>\n<p>The callback function also holds our tests. Here we can test whether our request has failed or we got some response data. The response can be checked eg. on status codes, document types like text, json or html and more.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">chai.request(app)\n  .get(\u2018\/\u2019)\n  .end((err, res) =&gt; {\n    expect(err).to.be.null; \/\/ expect that there\u2019s no error :)\n    expect(res)\n      .to.have.status(200)  \/\/ expect to have a 200 status\n      .and.to.be.html       \/\/ expect to be a html document\n      .and.to.have.cookie('session_id', '1234'); \/\/ expect to have a cookie with defined session-id\n  });\n<\/pre>\n<p>To work with the response data, we have to access the body object of the response. Especially when working with json responses this can be very handy to use.<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">chai.request(app)\n  .get(\u2018\/\u2019)\n  .end((err, res) =&gt; {\n    ...\n    expect(res.body)\n      .to.be.an(\u2018array\u2019)\n      .and.that.has.length.least(1);\n  });\n<\/pre>\n<h1>Final<\/h1>\n<p>In our next and final article we will write a bit about code style and code quality on Node.js. Another topic that also fits good into this series &#8211; keep testing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[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 as tools.<\/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,657],"tags":[25,23],"ppma_author":[666],"class_list":["post-632","post","type-post","status-publish","format-standard","hentry","category-system-designs","category-system-engineering","category-teaching-and-learning","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":632,"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":623,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/06\/10\/test-driven-development-part-ii\/","url_meta":{"origin":632,"position":1},"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":1876,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/03\/03\/building-an-hdm-alexa-skill-part-3\/","url_meta":{"origin":632,"position":2},"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":632,"position":3},"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":1807,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/02\/16\/building-a-hdm-alexa-skill-part-1\/","url_meta":{"origin":632,"position":4},"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":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":632,"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":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\/632","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=632"}],"version-history":[{"count":7,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/632\/revisions"}],"predecessor-version":[{"id":24693,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/632\/revisions\/24693"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=632"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=632"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=632"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=632"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}