Developing on Staxmanade

Spend the Effort to Make Your Tests Better Documentation

(Comments)

You may be writing tests, but are they describing the behavior well enough to know what business case it's covering a year from now?

Today's lesson or re-lesson. Don't just write your tests, write it so you can understand the intricacies a year from now.

The other day I was pairing on a what we first thought was a bug in our software. I was explaining something we saw.. "oh yea, that's a bug, oh and look at these tests, they look wrong also. Why is this so wrong? How did we not catch this last year? Something is off here... etc..."

While I had some tests to cover a business requirement a year ago when we wrote the software, I had not properly described the business case within the test to document it's purpose.

The subtle, bug-look-a-likes turned out to be proper behavior. If only I had not just documented the expected behavior via a test, but had properly describe WHY this behavior existed within the test, we could have avoided potentially breaking it (by "trying to fix it") and the test could have better communicated the WHY of this strange case.

This is just a reminder to myself to write better tests. Doing tests, great. Well documented, business explanation of the WHY in the tests? Way better!

Happy testing!

(Comments)

JavaScript - Refactoring too many function params

(Comments)

A code smell that can creep into your JavaScript codebase and quickly make the code difficult to follow is when a function has too many parameters.

EX:

myFunction("val1", 1, true, false, false, true);

Looking at the above, we can sort of tell that the first param is some string, maybe we can even tell what it's purpose is, the second a number maybe we even know why if we understand the codebase. But the booleans that follow? What are those representing? How do you know you're providing the right value for the right argument?

One approach is to refactor those parameters into variable names to help give them meaning.

EX:

var firstName = "val1";
var age = 1;
var isCool = true;
var isHungry = false;
var isSleeping = false;
var isHappy = true;
myFunction(firstName, age, isCool, isHungry, isSleeping, isHappy);

Now at least when we look at each parameter we can see it's name and that helps give some context of what it represents.

But as this parameter list grows it can be difficult to maintain. We could argue it's already too long.

What if you have to add a parameter in the middle?

How can you be sure all the callers get updated correctly?

Another approach would be to refactor this list of parameters into an object of properties.

This comes with some benefits like, you can add/remove properties without worrying about parameter ordering, as long as they can be optional and have solid defaults.

One cool thing I found with ES6 destructuring and enhanced object literals is if our function definition AND our caller follow a similar pattern. Meaning the variable names used in the caller are the same as the parameter names within the function.

EX:

function myFunction(firstName, age, isCool, isHungry, isSleeping, isHappy) {}

//**

var firstName = "val1";
var age = 1;
var isCool = true;
var isHungry = false;
var isSleeping = false;
var isHappy = true;
myFunction(firstName, age, isCool, isHungry, isSleeping, isHappy);

To refactor this we can simply have the caller pass an object, and have the function use destructuring of that object. It simply becomes.

function myFunction({firstName, age, isCool, isHungry, isSleeping, isHappy}) {}
var firstName = "val1";
var age = 1;
var isCool = true;
var isHungry = false;
var isSleeping = false;
var isHappy = true;
myFunction({firstName, age, isCool, isHungry, isSleeping, isHappy});

This is cool because it's simple, requires very little work, and now we can gain the benefits of using an object instead of an ordered set of parameters.

This opens the door to quit a few other organization options.

Happy Cleanup!

(Comments)

Using script=module to Quicky Spike Some Mocha Tests

(Comments)

I'll be honest, I secretly hoped JSPM would win the front end over and become our standard, and while I haven't truly followed it closely in the last year or so I recently tried this out and was blown away at how beautifully simple it is (at least on the surface).

Say I want to quickly run some Mocha test in a browser. Like say I'm spiking something, wanting to use tests in something like jsbin or plunkr and just get code running quickly.

Most browsers now support tye script=module tag which allows you to use import statements withing browser script tags. O_O

So how could I use this to import mocha and write some quick tests? I'm so glad you asked.

  1. Mocha's browser U.I. looks for an element with id=mocha so let's add that.
<!DOCTYPE html>
<html>
<body>
+  <div id="mocha"></div>
</body>
</html>
  1. now let's add some javascript to import mocha
<!DOCTYPE html>
<html>
<body>
  <div id="mocha"></div>
+  <script type="module">
+    import "https://dev.jspm.io/mocha"
+    console.log("Mocha:", Mocha);
+  </script>
</body>
</html>

This package is loaded using the import functionality built into our browsers now and JSPM which allows us to load some npm packages right through the browser. MAGIC!

WARNING: DO NOT do this for a production-type environment. This is just a quick prototype tool leveraging JSPM's dev hosted servers that allow us to use import to load packages via NPM through their servers. Thank you JSPM.

  1. Now we can do some browser-specific steps to get mocha to run.
<!DOCTYPE html>
<html>
<body>
  <div id="mocha"></div>
  <script type="module">
    import "https://dev.jspm.io/mocha"
-    console.log("Mocha:", Mocha);
+    mocha.setup('bdd');
+
+    mocha.run();
  </script>
</body>
</html>
  1. Let's add some tests.
<!DOCTYPE html>
<html>
<body>
  <div id="mocha"></div>
  <script type="module">
    import "https://dev.jspm.io/mocha"
    mocha.setup('bdd');

+    describe("some awesome tests", function () {
+        it("Should pass", function (){
+            console.log("passing test");
+        });
+        it("Should fail", function (){
+            throw new Error("OH NO!!!");
+        });
+    });

    mocha.run();
  </script>
</body>
</html>

THAT'S IT - using almost nothing but our browser's capabilities (and maybe a complicated JSPM back-end tool) we can easily write some in-browser tests to spike something, or just play around.

  1. But wait - this looks like meh

That's true, let's bring in some styles

<!DOCTYPE html>
<html>
<body>
  <div id="mocha"></div>
+  <link rel="stylesheet" href="https://dev.jspm.io/mocha/mocha.css">
  <script type="module">
    import "https://dev.jspm.io/mocha"
    mocha.setup('bdd');

    describe("some awesome tests", function () {
        it("Should pass", function (){
            console.log("passing test");
        });
        it("Should fail", function (){
            throw new Error("OH NO!!!");
        });
    });

    mocha.run();
  </script>
</body>
</html>

NOTE: Prob better to use a CDN version instead of pounding JSPM servers (sorry).

Final


<!DOCTYPE html>
<html>
<body>
  <div id="mocha"></div>
  <link rel="stylesheet" href="https://dev.jspm.io/mocha/mocha.css">
  <script type="module">
    import "https://dev.jspm.io/mocha"
    mocha.setup('bdd');

    describe("some awesome tests", function () {
        it("Should pass", function (){
            console.log("passing test");
        });
        it("Should fail", function (){
            throw new Error("OH NO!!!");
        });
    });

    mocha.run();
  </script>
</body>
</html>

Cake!

I've done this a few times lately, and am almost able to do it without looking up api and syntax O_O. I also don't need webpack, gulp, servers, or anything but a wee-bit of html/js and some luck (that JSPM servers will hang in there).

Happy Testing!

(Comments)

How to JSON.stringify and Order Dictionary Result

(Comments)

The other day I had the desire to serialize a simple Javascript Object and have it's keys ordered in the output.

Sorting before saving the object to a file like in approvals makes it much easier to diff two JSON documents that may not originally be in the same order.

So I threw together this quick little helper. It's far from perfect and won't suit all needs. But if all you're trying to do is sort and serialize an object it seems to be working well for now.

Happy Dictionary Reading!

(Comments)