<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eric Crooks</title>
    <description>The latest articles on DEV Community by Eric Crooks (@crookse_).</description>
    <link>https://dev.to/crookse_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F342543%2F6c30c264-f76d-4199-8564-3f4878dc5ffa.jpg</url>
      <title>DEV Community: Eric Crooks</title>
      <link>https://dev.to/crookse_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crookse_"/>
    <language>en</language>
    <item>
      <title>Why we created Rhum for testing Deno projects</title>
      <dc:creator>Eric Crooks</dc:creator>
      <pubDate>Wed, 24 Jun 2020 12:31:28 +0000</pubDate>
      <link>https://dev.to/crookse_/why-we-created-rhum-for-testing-deno-projects-33mf</link>
      <guid>https://dev.to/crookse_/why-we-created-rhum-for-testing-deno-projects-33mf</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/drashland/rhum"&gt;Rhum&lt;/a&gt; is a lightweight testing framework for Deno. It uses zero dependencies outside of Deno's Standard Modules and works with &lt;code&gt;deno test&lt;/code&gt; under the hood.&lt;/p&gt;

&lt;p&gt;This article dives deeper into the "why" we created Rhum and for what purpose.&lt;/p&gt;

&lt;p&gt;An article written by &lt;a class="mentioned-user" href="https://dev.to/craigmorten"&gt;@craigmorten&lt;/a&gt; dives deeper into using Rhum. Link is here &lt;a href="https://dev.to/craigmorten/how-to-write-spec-tests-in-deno-55e8"&gt;https://dev.to/craigmorten/how-to-write-spec-tests-in-deno-55e8&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The Drash Land team and I noticed that testing Drash was starting to become unwieldy. Drash has many unit tests and the output was something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test parseBodyAsJson: can parse JSON bodies... ok (2ms)
test setHeaders(): attaches headers the request ... ok (2ms)
test getMimeType(): file is not a URL ... ok (3ms)
test getMimeType(): file is a URL ... ok (4ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While testing, we noticed that the output was not as descriptive as we wanted/needed it to be to help us debug failing tests. Failing tests were not easily noticeable through the output. So next we tried to be more descriptive with the tests to get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test http_service_test.ts | parseBodyAsJson: can parse JSON bodies... ok (2ms)
test http_service_test.ts | setHeaders(): attaches headers the request ... ok (2ms)
test http_service_test.ts | getMimeType(): file is not a URL ... ok (3ms)
test http_service_test.ts | getMimeType(): file is a URL ... ok (4ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, a failing test would show us what test file to look in and what test to look for. This worked for a while, but then the output grew and it became a bit hard to read. See the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5CWbM9jM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hdow8gja69kj0u2i5l2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5CWbM9jM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hdow8gja69kj0u2i5l2p.png" alt="Drash - Rhum" width="880" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only that, our tests files became hard to read because we did not have a syntax like &lt;a href="https://mochajs.org/"&gt;Mocha&lt;/a&gt;'s nested &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;it&lt;/code&gt; syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;To make things easier for us, we decided to work on a module (which later became Rhum) to help us write tests like Mocha and Baretest. We also wanted the output to be nice. Our thoughts on the syntax were something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;testPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;the_test_file.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;testSuite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;methodOne()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;testCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;returns true when it does the thing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;testCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;returns false if it can't do the thing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;testSuite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;methodTwo()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;testCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;returns true when it does the thing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;testCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;returns false if it can't do the thing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used &lt;code&gt;testPlan&lt;/code&gt;, &lt;code&gt;testSuite&lt;/code&gt;, and &lt;code&gt;testCase&lt;/code&gt; to follow QA practices. This is testing after all.&lt;/p&gt;

&lt;p&gt;Our thoughts on the resulting output were something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the_test_file.ts
    methodOne()
        returns true when it does the thing
        returns false if it can't do the thing
    methodTwo()
        returns true when it does the thing
        returns false if it can't do the thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With some very helpful guidance from @bartlomieju from the Deno team, we were able to build Rhum and have it work for us in a way that makes writing tests easier and reading output easier.&lt;/p&gt;

&lt;p&gt;Before Rhum, we had the following output in Drash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test services/http_request_service_test.ts | accepts() | Asserting: accepts the single type if it is present in the header ... ok (1ms)
test services/http_request_service_test.ts | accepts() | Asserting: rejects the single type if it is not present in the header ... ok (1ms)
test services/http_request_service_test.ts | accepts() | Asserting: accepts the first of multiple types if it is present in the header ... ok (1ms)
test services/http_request_service_test.ts | accepts() | Asserting: accepts the second of multiple types if it is present in the header ... ok (1ms)
test services/http_request_service_test.ts | accepts() | Asserting: rejects the multiple types if none are present in the header ... ok (0ms)
test services/http_request_service_test.ts | getCookie() | Asserting: Returns the cookie value if it exists ... ok (1ms)
test services/http_request_service_test.ts | getCookie() | Asserting: Returns undefined if the cookie does not exist ... ok (0ms)
test services/http_service_test.ts | Asserting: getMimeType(): file is not a URL ... ok (3ms)
test services/http_service_test.ts | Asserting: getMimeType(): file is a URL ... ok (4ms)

test result: ok. 116 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (839ms)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services/http_request_service_test.ts
    accepts()
        accepts the single type if it is present in the header ... ok (1ms)
        rejects the single type if it is not present in the header ... ok (1ms)
        accepts the first of multiple types if it is present in the header ... ok (1ms)
        accepts the second of multiple types if it is present in the header ... ok (1ms)
        rejects the multiple types if none are present in the header ... ok (1ms)
    getCookie()
        Returns the cookie value if it exists ... ok (1ms)
        Returns undefined if the cookie does not exist ... ok (1ms)

services/http_service_test.ts
    getMimeType()
        file is not a URL ... ok (3ms)
        file is a URL ... ok (3ms)

test result: ok. 116 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (770ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not only that, the test files in Drash are much cleaner with nested test suites and test cases.&lt;/p&gt;

&lt;p&gt;If you are testing your Deno project and running into the issues we came across, I recommend you give Rhum a shot. It may solve your problems as it did for us.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;Eric&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Special Thanks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;@bartlomieju for showing us the following issue to base our development on: &lt;a href="https://github.com/denoland/deno/issues/4092"&gt;https://github.com/denoland/deno/issues/4092&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All who participated in the poll for the name. It was tied between Rhum and Bourbon. We decided to close the poll and have Alexa flip a coin for us. Rhum won.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/melhirech"&gt;@melhirech&lt;/a&gt; for suggesting Rhum in the polls.&lt;/p&gt;

</description>
      <category>deno</category>
      <category>typescript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Drash - A REST microframework for Deno</title>
      <dc:creator>Eric Crooks</dc:creator>
      <pubDate>Thu, 27 Feb 2020 03:40:45 +0000</pubDate>
      <link>https://dev.to/crookse_/drash-a-rest-microframework-for-deno-cib</link>
      <guid>https://dev.to/crookse_/drash-a-rest-microframework-for-deno-cib</guid>
      <description>&lt;p&gt;As Deno's visibility grows, I'm seeing more and more people who are interested in creating Deno HTTP servers so they can build applications. About a year ago I was in the same position and then came Drash. Drash is a REST microframework for Deno. It's loaded with documentation and tutorials and covers many use cases. I recommend (if you're interested) you check it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://drash.land"&gt;https://drash.land&lt;/a&gt;&lt;/p&gt;

</description>
      <category>deno</category>
      <category>drash</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
