Ushering TestNG into the new year

I took advantage of the holiday break to completely revamp TestNG’s HTML reports, something I’ve been meaning to do for a very long time but never found the time to put at the top of my TODO list. I wrote the original reports pretty much with the very first version of TestNG, around 2004, and I hardly touched them since then. My intention with this rewrite was not just to revamp them visually but also technically, so that I could give myself as much freedom as possible to improve them from this point on.

Here are some notes I took during this process.

Content and appearance

First of all, here are the new reports. They show all the suites on the same page with a banner at the top, a navigator pane on the left hand side (which always stays visible) and a main panel on the right hand side, which shows all the information you requested depending on which item you clicked in the navigator. Pretty straightforward.

If you take a look at the source, you will see that it hardly contains any HTML: it’s mostly made of <div> and <span>. I didn’t really set out to do this initially, it’s just that whenever I used HTML elements, I inherited undesirable CSS attributes (margins, paddings, etc…) which I ended up resetting manually, so after a while, it just seemed much easier to use divs and spans knowing that they start with a clean CSS slate.

Since there is so much generated text, I pondered using a templating library to make my life easier. The first question to settle was: client side or server side templates? In this case, there is not really a “server” side, so the question is more “Java” or “Javascript” templates. I quickly rejected the client side approach which, while well adapted to serve pages over a network, doesn’t seem to have much benefit in this particular case since the page is generated locally. As for the Java side, the two standard options for templates (Freemarker and Velocity) seemed quite overkill for what I was trying to do, so I ended up writing my own tiny implementation of mustache.js (which I’ve used in the past and liked quite a bit)..

Once I had the templating code working, I started converting the Java code over to it but… something felt wrong. I quickly gained the impression that this was actually a step backward compared to doing the generation 100% from Java, and the reason quickly became apparent to me: the Java compiler.

The problem with using templates is that you get very little help from the tools. Some template libraries allow you to include other templates, which can reduce the repetition, but it’s still very easy to make simple typos or being forced to copy/paste a lot. In contrast, my Java hierarchies makes it quite trivial to, say, add a new panel on the right hand side with a link to the left. Implement the right class, declare it and it will automatically work, with the right defaults (CSS selectors) and a lot of the logic validated by the compiler.

This comfort was too good to pass up so I scrapped my template idea (my mustache.js implementation is still around, though, and I might use it some time in the future) and I stuck to 100% Java generation.

Javascript and development tools

Picking jQuery was a no-brainer, it’s hard for me to imagine doing anything in Javascript that manipulates the DOM without using JQuery. The logic in the new reports is fairly simple and is just above one hundred lines of Javascript.

Chrome’s development environment is also quite superb (I’m sure other browsers’ is just as good). In a nutshell, you have access to pretty much the same range of support that Eclipse or IDEA provides in Java: breakpoints, inspection and modification of variables, and even CSS debugging, which I’ve found invaluable to track down unexpected CSS behaviors (I came across quite a few).

If you haven’t kept up with what you can do with Chrome/Javascript/JQuery these days, try the following:

  • Open http://testng.org/new in Chrome.
  • Right click anywhere on the page and select "Inspect element". This will open the document explorer at the bottom.
  • With the focus in the document explorer, type ESC, which will open the REPL.
  • Type $('.navigator-suite-content').hide().
  • This will collapse the content under both suites.

You can see how easy it is to debug this kind of code.

Other libraries

If you select the "Times" link of the first test suite in the Navigator pane, you will see the following table:




Click to enlarge

I am using Google’s Chart Tools to display this table and it was quite straightforward to add. The only tricky part was how to generate the data in Javascript form and make sure that the table gets drawn only after this data has been initialized, which required using a few Javascript tricks to make sure the initialization order is correct. The Google Chart Tools are very powerful and I will probably use more of their API to display additional graphs in the TestNG reports (pie charts, etc…).

Conclusions

Here are my main take away points:

  • CSS still feels like black magic to me. The theory is trivial on paper but in reality, I often come across results that just don’t make sense. With the help of modern CSS debuggers, it’s a little bit easier to find out what is happening and why (I especially like Chrome’s “Computed style” which gives you a list of all the attributes that were derived from .css files), but there are still times where I feel completely helpless trying to find out why something is not how it should be.
  • I’m a bit concerned with the size of the reports: I was quite surprised to find out that the reports you’re looking at is one meg in size. Admittedly, it shows over five hundred test methods, but the fact that it contains all the panels, even those the user might not be interested in, is a potential place for improvement. I might decide to put each individual pane in its own file.
  • Javascript’s rubbery type system is handy for this kind of task, but I’m still a bit unsure how well it scales to hundreds of thousands of lines of code. For example, I really enjoy being able to say if (v) regardless of what type v is and have Javascript’s truthiness values do the right thing. Similarly, it’s nice to be able to add a parameter to a function and not having to update one single call site (if you call a Javascript method with less parameters than it expects, the extra parameters simply receive the Undefined value. Obviously you need to test for this in said function).
  • JQuery is great and it’s probably making Javascript even more popular than it already is. I’m hoping the Dart team is taking notes and making sure that a similarly powerful and elegant framework will be available in Dart.

Finally, a call for help: I welcome any feedback on how to improve the CSS of these new reports, so if you are so inclined, feel free to improve the look of these new reports and share your improvements with me. I will be very grateful.

Happy new year!

Ground control to major Tom


This could be you!

Who hasn’t dreamed of becoming an astronaut? Well, now you can. The NASA has an open position for an “Astronaut Candidate” for the International Space Station in Houston, TX. The requirements are pretty interesting.

The training will take two to three years and will require a lot of traveling, probably mostly to Russia, since they will be using Soyuz to travel to and from the ISS. The required education is fairly broad, and more interestingly, the list of degrees that are not applicable is fairly short (technology, psychology, nursing(!), etc…). It looks like a CS degree is good enough, and you can make up for the lack of flying experience with an MS or better, a PhD.

“Correctable” 20/20 eyesight is required, which means that contact lenses and Lasik are accepted (I wonder how hard it is to put contact lenses on in zero gravity…). The ad also takes the time to explain each jargon occurrence: “Extravehicular Activities (space walks)”, “the extravehicular activity mobility unit (space suit)”.

Although the ad will only be open for the next couple of months, the selection process takes a while since the selection will be announced in the spring of 2013.

I was fortunate to be able to experience a Zero-G flight a few years ago, I can’t say I’m not tempted to apply :-)

Table of contents in Javascript

This is my week end project: a table of contents generator. Well, technically, it’s more like a two hour project interrupted four times over the course of a Saturday but I guess it still qualifies as a week end project.

I got tired of managing the table of contents of my documentations manually and in particular, of having to modify all the section numbers by hand whenever I moved things around. This short Javascript program now automatically takes care of it for me. Here is the quick documentation:

// A simple HTML "table of contents" generator.
//
// 1) Include toc.js in your HTML file:
//          <script type="text/javascript" src="toc.js"></script>
//
// 2) Call generateToc() in your onLoad() method:
//           <body onLoad="generateToc();">
//
// 3) Declare a div with the id "table-of-contents" where you want
// your table of contents:
//           <div id="table-of-contents"></div>
//
// 4) Put each of your sections in an <a> tag with class "section",
// specifying an "indent" representing the indentation of that section.
// Only the length of the indent matters, now its content. If no indent
// is found, a string of size 1 is the default.
//
// Example:
// <a class="section" name="Section 1">Section 1</a>
// <a class="section" indent=".." name="Section 1a">Section 1a</a>
// <a class="section" name="Section 2">Section 2</a>

This script now powers both testng.org and jcommander.org, go take a look there if you want to see what it looks like.

Ideas for potential improvements:

  • Make the numbering optional or configurable.
  • Have the script add CSS classes to the sections for easier styling (“section1″, “section2″, etc…), since the indenting is pretty crude right now.

JCommander 1.20

I just released JCommander 1.20. The main new feature is “parameter delegates”:

Parameter delegates

If you are writing many different tools in the same project, you will probably find that most of these tools can share configurations. While you can use inheritance with your objects to avoid repeating this code, the restriction to single inheritance of implementation might limit your flexibility. To address this problem, JCommander supports parameter delegates.

When JCommander encounters an object annotated with @ParameterDelegate in one of your objects, it acts as if this object had been added as a description object itself:

class Delegate {
  @Parameter(names = "-port")
  public int port;
}

class MainParams {
  @Parameter(names = "-v")
  public boolean verbose;

  @ParametersDelegate
  public Delegate delegate = new Delegate();
}

The example above specifies a delegate parameter Delegate which is then referenced in MainParams. You only need to add a MainParams object to your JCommander configuration in order to use the delegate:

MainParams p = new MainParams();
new JCommander(p).parse("-v", "-port", "1234");
Assert.assertTrue(p.isVerbose);
Assert.assertEquals(p.delegate.port, 1234);

Change log for 1.20

  • Added: Support for delegating parameter definitions to child classes (rodionmoiseev)
  • Added: @Parameter(commandNames) so that command names can be specified with annotations
  • Added: Support for enums (Adrian Muraru)
  • Fixed: Throw if an unknown option is found
  • Fixed: Main parameters are now validated as well (Connor Mullen)

  • Doom 3 source code

    Browsing the source code of Doom 3 comforts me in my belief that I’m simply not cut out for graphic programming.

    The new Google Reader

    Count me as one more Google Reader faithful user who really doesn’t like the new look.

    Google, don’t make the mistake of dismissing all the criticism as “They’re complaining because it’s different, they’ll get used to it, we just to wait them out” and take the time to ponder the new look.

    It’s basically black and white, with a lot (a lot) of empty space and a selection that turns the foreground (yes, the foreground, and the foreground only) of the font to red:

    I mean, the whole page seems to be using five colors total. Surely it’s possible to make a better use of colors without going all psychedelic on us?

    Any default theme of WordPress looks ten times better than Reader right now.

    Come on, Google, you can do better than this.

    A new coding challenge

    It’s been a while since I offered a coding challenge, so let’s remedy this.

    This one comes from this week’s Car Talk’s puzzler. Here is the short version of it:

    A farmer has a forty pound stone that he uses to weigh food for his animals on a scale. One day, he loans the stone to his neighbor. A few days later, the neighbor returns the stone and apologizes to the farmer because his stone is now broken in four pieces. The farmer responds “Please don’t apologize, you have actually made my life easier because with these four pieces, I can now measure any weight between one and forty pounds”.

    The question is: how much do these four individual pieces weigh?

    I’m adding a few clarifications, which are not necessarily what the Car Talk guys meant (I don’t have the solution and I haven’t looked at any discussion on the subject):

    • The four weights are integers.
    • The weights we can measure between one and forty pounds are in one pound increment.
    • They are measured in one session (otherwise, you could measure forty pounds with a one pound stone by performing forty measurements).
    • If there is no solution (the farmer might be bad at math), show the four weights that allow to measure the most weights between one and forty pounds.

    The challenge? Write a brute force solution to this puzzler in any language that you want. I don’t care if your solution is slow, fast, ugly or elegant as long as it works, and I suspect that certain languages will be very good for this puzzler

    Bonus questions:

    • Your solution should explain how exactly you use the stone pieces to measure each weight.
    • Is there a formal way to solve this problem without using brute force?

    Solution to the quiz

    Wow, my little quiz received a lot more attention than I thought it would. Surprisingly, of all the answers that I have read so far (over 150 between the comments on my blog and Google+), I only spotted three that match exactly my reasoning, which in itself, has to be a statistical anomaly.

    Anyway, enough waiting, here is my interpretation of the puzzler.

    This is a meta quiz: a question about a question. The first step to figure it out is to solve the “inner” question, which is determining what “right answer” or means. In other words, we need to answer “If you have a choice between four options and you pick randomly, what are the odds you’ll get the right answer?”.

    This is a very general question that can be answered easily: 1 in 4. 25%.

    Armed with this knowledge, we now focus on the “outer” question, which we can rephrase as follows:

    If you choose an answer to this question at random, what is the chance you will pick 25%?

    Looking at the choices, we notice that 25% appears twice among four choices, so you will be right 50% of the time.

    Therefore, the answer is 50%, right?

    Wrong!

    It’s B! You’re asked to pick a choice between A, B, C and D, not a percentage. Some teachers will actually fail you if your answer doesn’t typecheck :-)

    I think this is the answer that the creator of this quiz expected, however, the more I thought about it, the more I started to realize that there was a crack in the reasoning. Can you spot it?

    It’s the answer to the question above:

    If you have a choice between four options and you pick randomly, what are the odds you’ll get the right answer?

    The answer will be 25% only if the answer is present exactly once among the options. Not zero, not two, three or four.

    Do you think the meta quiz obeys this constraint? After all, 25% appears twice in the options, right? Yes, except that the correct answer is not 25% but 50%, which appears exactly once, so the quiz seems to be consistent with this caveat.

    Exercise left to the reader: can you rephrase the original quiz to close this loophole?

    Probability quiz



    Link to the discussion on Google+.

    Goodbye, old friend

    Yesterday, I received my Galaxy S II and it’s now time to say goodbye to my trusty Nexus One.

    I’ve had it for over two years and it is by far the best phone that I’ve ever owned. Even today, I still think it looks absolutely gorgeous. If you’ve never held one in your hands, you are missing out. It managed to run all of the applications that I’ve installed very well, even compared to more modern phones.

    As for the Galaxy S II, it’s quite a formidable phone and I have a lot of things to say about it after only twenty-four hours, but I’ll save this for a future post.