Monday, 23 July 2012

Breaking JavaScript code down into components

Following on from my original post of learning how to put JavaScript together it's been a really productive week. Have I managed to write JavaScript that's easy to test? No, but I've wrapped up some reasonably complex logic into a component that can have some of it's functionality tested!

At the moment I've settled on QUnit as my JS unit testing framework and have a couple of tests verifying the default values of exposed properties - these are currently exposed as functions as I've wrapped up the variables in a closure to make them read only. Not sure if JavaScript even has the concept of a read only property in a form similar to C#. When calling the component in test conditions I've also been overwriting functions on the injected underscore library that failed due to a null/undefined reference - so not really mocking yet. The first issue I ran into was that I was pre-compiling the templates and these were defined inside script blocks of the calling ASP.NET view. In C# code you don't verify the view engine running when unit testing calls to the controller actions, so that indicates having a call to the template inside the main component is probably a suitable refactor. Applying this logic it has become apparent that my biggest problem is that my current JavaScript components are just one big black box. Using JQuery, Underscore and JSON/templating has made things cleaner but not really that much more testable!

The next step will be learning how to break the large big black boxes down into more focused components that can be easily tested in isolation to each other; and mocked/replaced when used inside of the calling component. This is much better and already feels closer to the comparable process in .NET. The code I am currently working on has a dialog box, which can be updated - that can be split out into it's own component. That includes initialisation, display updates and some button context functionality (once the processing is complete the text on the button changes from "Cancel" to "Close" but the functionality stays the same. These things become easier to test and wrap up a few of the JQuery/Templating calls quite nicely (making them easier to "Mock"). Another area of functionality which could be split out into it's own component is the AJAX calls. Similarly the "timer" based eventing system could be wrapped up as I noticed that there were several "clearInterval(...)" calls spread through out the code

After all the above refactors have been completed I'm hoping to end up with a single "controller" type object that orchestrates all the newly created components. This should make it far easier to test this controller object and possibly look to finally extract some of the business logic into smaller components too.

It seems strange to say, but it would appear right now that the biggest thing that was holding my JavaScript coding back was a fear of creating too many objects, preferring a single component that tried to contain and wrap everything up.....something that I left behind in the C# world many years ago! This was something of a surprise, up until recently I thought my biggest stumbling block was a lack of knowledge / understanding of JavaScript itself!

Thursday, 19 July 2012

Create & inserting GUIDs in Visual Studio

If you're using WIX and you're adding components to the product file by hand then you've probably found yourself creating and cutting/pasting a lot of GUIDs which can be a real pain and productivity killer. There is the "Create GUID" menu option under tools but that still requires calling and then cutting / pasting. The other day one of other members on our team came up with these steps to create a macro that will create and insert a new GUID and can be bound to a key board short cut.

  1. Go to Tools – Macros – Macro Explorer and paste the following into a module:
  2. Sub InsertGuid()
    Dim objTextSelection As TextSelection
    objTextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
    objTextSelection.Text = System.Guid.NewGuid.ToString("D").ToUpperInvariant
    End Sub

  3. Then assign it a keyboard shortcut through Tools – Environment/Keyboard, you can generate a GUID in-place with a simple keyboard shortcut.

No more copy/paste

Tuesday, 17 July 2012

Learning how to put JavaScript together properly

After many years of trial and error / practise I feel fairly happy that I can write clean, testable .NET / C# code, which is free of any external dependencies which traditionally make unit testing harder. It's fair to say that I'm convert to TDD; having implemented it on two separate commercial projects and seen the benefits of the improved maintainability of the code base over time.

But what about Javascript? Thanks to Selenium and Specflow the functionality of those websites is pretty well tested and by default that includes any JavaScript that may be referenced in the UI tests that are run. But that's not the same as having clean testable JavaScript. Those websites have typically included a mixture of JavaScript defined in-line as well as held separately within JS files. Most functionality has been provided by individual functions attached to events and any communication introduced by coupling of functions and/or attaching attributes to FORM elements. AJAX calls and DOM updates are mixed within the application logic making isolated testing pretty much impossible, basically everything we've spent the past years learning how to avoid in our .NET code bases.

But why does this happen? Experience and reading around on the web has highlighted that the above scenario is probably still the norm, rather than the exception. Is it really that difficult to write testable JavaScript? Is JavaScript such a difficult language to learn, or does it lend itself to writing messy code? I've met some very good .NET developers who openly admit that their JavaScript code doesn't live up to their own standards.

As part of the project that I'm now working on, I decided that I'd make sure that this time would be different. I wouldn't settle for writing inline JavaScript, nor would I settle for a mishmash of unrelated functions in the global namespace all somehow working together (and when they didn't I wouldn't just use alert's and console writes to debug what was happening!). This time I was going to write testable, modular JavaScript that was easy to unit test.

As part of this experiment I'll try keeping this blog updated with our findings, including patterns and practises we find that help. An initial search of the web came up with this article (by Ben Cherry) which details his findings when he joined Twitter: Writing testable Javascript. Interestingly this article highlights a few modifications people might want to consider to some currently recommended Javascript best practises to make your code more testable, namely staying away from singletons and not enclosing too much business logic - both valid suggestions that we stay away from in our .NET code for exactly the same reasons!