Thursday 9 June 2011

Javascript tests in Continuous Integrated builds

We implemented this approach to incorporate QUnit in our regular CI builds a while back and I think it's worth sharing. Since QUnit runs in a browser, it's typically only viewed when someone can be bothered to run the tests manually. Possible options include launching the QUnit page as a post-build step, but that still requires eye balling the results, which means people can ignore it.

If we treat the JavaScript in our web applications with the respect it deserves since it's critical code, we must incorporate the results of the QUnit tests in out CI build result. We took the following approach to failing a build if a QUnit test fails.

Using a normal (NUnit) unit test, we load the QUnit page with WatiN. Once loaded, the JavaScript is executed and we parse the DOM to find tests and test failures. QUnit markup could be more helpful in this respect, but it's certainly far from impossible. Any failing tests are output to the console so that they appear in the CI build log. If any QUnit test has failed, the [NUnit] unit test Asserts a failure to ensure that the overall build is failed.

The thing I dislike most about this approach is that it's an integration test rather than a true unit test, with the parsing of the QUnit results tightly bound with the QUnit output DOM. But since we use a local copy of QUnit, we at least won't be stung by an update of QUnit that we weren't aware of.

A few things I like very much about this technique are:

  • The ability to run the tests as part of the CI build. Any commit of code verifies the tests still pass.
  • The ability to run the tests through a number of different browsers thanks to WatiN.
  • The treatment of JavaScript code as equally important and "grown-up" as our server side (C#) code.

I could probably improve matters by changing the testPageUrl. The code below assumes a local virtual directory called "Tests" has been set up and configured for my project. Without further ado, here's the code:

 [TestFixture]
 public class JavaScriptTests
 {
  [Test]
  public void LoadJavaScriptTestPage()
  {
   const string testPageUrl = "http://localhost/Tests/JavaScript%20Tests.htm";
   string jsTestResults;
   string jsFailedTestResults;
   using (var browser = new IE(testPageUrl))
   {
    browser.ClearCache();
    ParseQUnitTestResults(browser, out jsTestResults, out jsFailedTestResults);
   }
   Trace.WriteLine(string.Format("{0}:{1}", testPageUrl, jsTestResults));
   if (jsTestResults.IndexOf('F') >= 0)
   {
    Assert.Fail(jsFailedTestResults);
   }
  }

  private void ParseQUnitTestResults(IElementContainer browser, out string jsTestResults, out string jsFailResults)
  {
   var testResults = new StringBuilder();
   var failResults = new StringBuilder();
   foreach (var element in browser.ElementsWithTag("li").Where(element => element.Parent != null && element.Parent.Id != null && element.Parent.Id.Equals("qunit-tests")))
   {
    if (element.ClassName.Equals("fail", StringComparison.InvariantCultureIgnoreCase))
    {
     testResults.Append("F");
     failResults.AppendLine(element.Text);
    }
    else
    {
     testResults.Append(".");
    }
   }
   jsTestResults = testResults.ToString();
   jsFailResults = failResults.ToString();
  }
 }

Thursday 2 June 2011

PhoneGap Experiences

My first encounter and use of PhoneGap was an eye opener. The ability to produce a native app for my Android phone, AND other devices, just blew me away. Best of all, I didn't need to learn Objective-C, Java, or any other new language to produce these apps.

The apps are web apps. I'm not going to pretend you can do everything as easily in a web app as you can in native code; it certainly has a few down sides. But there is a lot that comes built in with web browsers, and you can lean on that functionality to build apps very quickly indeed.

I first started building these apps using the combination of Eclipse, JDK and ADK. Not having used any of these tools before, it was a learning curve, but not at all steep. See my post on Setting up PhoneGap for Android on Windows 7. The installation is the most arduous part of the development process.

Then along came PhoneGap Build which I loved from the start and I blogged about it in PhoneGap Build is amazing. Since then there have been a few things that have niggled me (hey, it's still in Beta you know!) and I've considered going back to my Eclipse builds.

One thing that might not be immediately obvious, is that you don't need to use PhoneGap (the library) to use their build server. Their build service simply builds your app regardless of which libraries you use. And for some (simple) apps, there is no need for PhoneGap. If your app doesn't need any device interaction, you can get by with a plain web page and JS functionality. This was a surprising realisation on my part when I wrote a simple lock game that only used a little JavaScript and some CSS animations.

The few things that niggle me with PhoneGap build are as follows (in no particular order):

  • Seems to ignore which devices you want to build for and builds them all anyway. (The one I want is not first, so it bugs me.)
  • The builds are quick, but not knowing how long they'll take, or when they'll start when they're queued is a little frustrating.
  • There doesn't seem to be a way of defining a splash screen image. (Edit: it's actually very easy to define a splash screen in the configuration XML file.) There is a way to add a splash page when building with Eclipse.
  • I've not found good documentation on the options and schema of the configuration XML file. Maybe I've not looked hard enough.

But I can ignore all of the above because of the reasons I explained in my post on how amazing it is. There's certainly a pleasure in knowing all you need is a web browser and internet access to get an app created and built. It does help to have Git installed locally and edit and test the files locally before pushing changes and rebuilding, but that's a simple install and low entry bar for what we can achieve with it.

One of the most desirable gaps that PhoneGap wasn't bridging for me personally, was the menu device button on Android. The latest release now includes support for all the device buttons. There were a few posts floating around the Internet on how to hack it into your app yourself (if you were on the Eclipse build path, no luck if you used PhoneGap build). But now that it's in the PhoneGap library, I think it has everything I need.

"I can wholeheartedly recommend PhoneGap as a library to bridge the device-JavaScript gaps."

I think PhoneGap is my library of choice for mobile apps. I have to admit that I've not tried any others - why would I? PhoneGap bridges all the device features I want and need, and then quite a few that I don't. I can wholeheartedly recommend it as a library to bridge the device-JavaScript gaps.

In terms of developing JavaScript web apps as native apps, there are issues that I've found troublesome but can be overcome. These are not as a result of using PhoneGap; they're a result of creating apps as browser based apps. Most commonly this boils down to layout issues, screen size limitations, and differences between the phone's browser and the Chrome browser I use on my desktop for development.

Thursday 19 May 2011

TFS woes

It's the little things that niggle me about Visual Studio (VS) and Team Foundation server (TFS) that make my daily use of them frustrating. I've used Visual Studio almost every working day of my life for the past 10+ years so I've seen it grow from a decent IDE to a bit of a monster in terms of functionality and size. Here's a small collection of things that still bug me today.

I've just defined my sprint in TFS. Now I want to check that the burndown report is there and the values are correct. Too bad - TFS reports run off the warehouse so it'll be a while before that's updated. How long is the "while" you ask? The answer appears to be "Never mind, none of your business. Just try again later." This affects every single report that you want to review after a change to a work item. It's a serious pain in the arse. TFS should install by default without a warehouse database but allow larger installations to opt into the warehouse replication if it suits their needs.

Today, I had to update the end date of my sprint. I know that's not normal, and it's not scrum and I should never do this, but hey, here in the real world, people are breaking the rules all the time. I updated the sprint work item at 8:50:59. I've requested an update of the burndown at 9:44, which shows me the same one it generated at 9:41:41 which claims that the "Data Updated" was at 9:25:02. Maybe it's my lack of training with the tools, but if I edit the sprint, I expect the burndown to change. I expect that change to be immediate. It's 2011 people; the days of waiting for your JCL to run overnight in an underground bunker should be over.

You're looking at your pending changes in TFS 2010 with Visual Studio 2010 Ultimate (yes, you're using Microsoft's state of the art development tools). The Undo menu option is directly below the compare menu option. Woopsie if you nudged the mouse before clicking eh? But no worries, there's a prompt for the undo; only trouble is, the default button is to confirm the undo. There is no undo of the undo silly; your work is toast, get over it.

You want to edit a file so you press Enter. Visual Studio now asks TFS to check out the file. But the TFS client asks the server to check it out. This is a synchronous call. You sit and wait for a response from the server before you can type. If the server's down or just having a bad day; guess what, so are you.

You open a solution file in VS but you're not connected to the network right now because you took your laptop to a meeting room and you didn't bother logging into the corporate WiFi. Well tough luck son, you're now working offline. No, connecting a cable at this point is futile; there is no retry, no abort/cancel, no option other than OK. You are already offline, even if you kill the process. You're screwed. It gets better. There will be no test by VS at intervals later to see if TFS is reachable and prompt you to go online. You'll suddenly realise, after a day of work that the files you've been editing (you should have noticed there was no checkout delay when you edited them) are now edited locally but not checked out. You say a silent prayer to any god who might be listening that nobody else has changed those files in the mean time or you'll have the devils own job merging their changes and yours. All because you opened a solution file whilst offline; you idiot!

You open the properties of a project file (this will open in a pane). The only "pane" in your mind is spelt PAIN as you try resize a pane whilst the properties are being loaded. Why? Because it won't work. The entire VS user interface is locked until that pane loads. I wonder sometimes, whether they did that on purpose to avoid unforeseen issues, and how much effort it took to make the ultimate user experience from hell.

Very often you do something and you're not sure if you really clicked the right thing because there's no feedback. The mouse cursor doesn't even change to a sand clock. That's the easiest thing in the world to do in Windows and they neglected to do it. Unforgivable.

Ever been to an MSDN presentation or road show? Ever notice how many people are asking what sort of laptop the presenter has? They want one that responds like that. We're all living out in the real world with significantly lower spec machines and we feel a pain they don't.

It's not that the little half seconds total up to huge amounts of time over the period of a week or a sprint (though of course they do). It's the constant resistance to your momentum in terms of working efficiently that eventually have you shouting abuse at the screen and wishing your could punch the living sh!t out of the person at Microsoft who decided to leave the cancel button enabled but not react to clicks on it whilst a long running process just chips away at your productivity.

There are many many many more instances of these sorts of niggles in VS that frustrate a developers life. And yet, there are a lot of things VS does well. It's by far the best IDE I've used, but these little things bug me because in my experience as a Windows developer, it's Microsoft who have told me over and over in MSDN articles to not use the UI thread for long running processes, and it's far from difficult. People who can make an IDE as complex as VS ought to be able to do better than lock the entire application when the content for single panel is loading. The VS team need someone doing UX for them, and that person needs to be senior in terms of decision making.

Tuesday 5 April 2011

PhoneGap Build is amazing

In my previous blog I wrote about how to install and configure the various SDKs and applications required to build a PhoneGap app on your own Windows PC. Since then I've discovered a whole new way of building PhoneGap apps for more than just the one platform. In my previous blog I created an Android app and would have had more work to do to build the same app for iOS, Blackberry, Symbian or webOS.

I've discovered a website called PhoneGap Build. It does all this donkey work for you. You install nothing - well, maybe Git.

In a nutshell, it will build your HTML, JavaScript, CSS and other assets into apps for up to 5 target device operating systems.

  1. Your files are hosted on GitHub.
  2. You give PhoneGap Build the URL of your GitHub repo[sitory]
  3. PhoneGap Build builds your apps
  4. PhoneGap provides clickable links to download your apps, and where supported, a 2D pixel code to download it directly to your device.

This all comes without installing anything besides Git if you didn't already have that. GitHub provides versioned source control (free for open source projects) and PhoneGap Build builds your apps for you. It's the easiest way to create phone apps I have ever heard or seen and provides multiple target device support out of the box.

PhoneGap Build is still in Beta and they people building it are doing amazing stuff. This is an amazing service.

Thursday 13 January 2011

Setting up PhoneGap for Android on Windows 7

Everything I see shows this on a Mac, so here are my notes on getting up to speed for Windows 7.

Preparation (Reading and Downloading)

Start with the generic Android Eclipse quickstart here: http://wiki.phonegap.com/w/page/30862722/phonegap-android-eclipse-quickstart

It tells you that you need the Android SDK which you download here (this is the start of a veritable download fest):
http://developer.android.com/sdk/index.html (31.2MB)
NB. I recommend the ZIP, not the EXE; you'll see why when you read the installation.

You read the notes and see you should follow the guide to installing the SDK:
http://developer.android.com/sdk/installing.html

You might need the JDK, or a newer version. Download from here:
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Note to self: This site expects you to know what edition and version you need rather than telling you or helping you decide. (You need JavaSE dummy.) (66.9MB)

You'll need the IDE as well, and this should be Eclipse Classic. Get it here:
http://www.eclipse.org/downloads/ (170MB)

Installations

Installation order:

  1. JDK (jdk-6u23-windows-x64.exe)
    Unsure of the options, the only thing I skipped installing was the source code. Also installed to D: rather than C: (space). Note that the JRE is actually a 2nd installation kicked off from the former, so you have to change the installation drive again here. Sidenote: Oracle want me to register, and to do that I need to create an account. Just to use Java? No thanks.
  2. Eclipse (eclipse-SDK-3.6.1-win32-x86_64.zip)
  3. Android SDK (installer_r80-windows.exe)
    Even though the JDK has been installed, this installer says it can't find the JDK and progress is blocked. You can't tell it where the JDK is; you can only exit. A reboot doesn't address this issue. I try by copying the entire D:\Program Files\Java\jdk1.6.0_23 to C:\Program Files (x86)\Java\jdk1.6.0_23 with no luck. I then add the bin folder to the PATH environment variable (Computer/Properties/Advanced System Settings/Advanced/Environment Variables.) Still no luck. At this point I give up on the installer and download android-sdk_r08-windows.zip (31.2MB) whilst cursing the installer for it's refusal to cooperate.
    I extract the contents to D:\Dev\android-sdk-windows and run SDK Manager.exe to download the packages I want/need. (I rejected the oldest libraries.)

By now I've done steps 1 and 2 of the SDK installation guide. On to Step 3: Installing the ADT plugin for Eclipse:
http://developer.android.com/sdk/eclipse-adt.html#installing. It's installed through Eclipse, so not a download I could easily measure in size. It's apparently around 8MB if you download it manually. At last we have a step that feels as painless as a typical Windows installation.

I realize at this point that I jumped the gun when I ran the package manager and installed those packages. The installation guide suggests doing that now. Though it's not made any difference - everything seems to work fine now.

Apparently we're done and we can get back to the QuickStart and making that first PhoneGap Android application. Woohoo!