if ( document.comments_form.url ) { document.comments_form.url.value = getCookie("mtcmthome"); } Otaku, Cedric's weblog: September 2005 Archives

September 30, 2005

A date in heaven: TestNG and BeanShell

Recently, several TestNG users started asking for more control in the way test methods are selected.  For example, here is one way you specify which groups to run:

<groups>
  <run>
    <include name="nopackage"/>
    <exclude name="broken" />
  </run>
</groups>

The include/exclude syntax is fairly flexible, but it doesn't help when you want to perform more complex expressions, such as 'run the test methods that belong to the group "g1" and "g2" but not "g3"'.

There are many ways to solve this problem, and the most obvious one to me is to support a scripting language inside TestNG.

After thinking about it for a while, I decided to go for BeanShell for two reasons:

  • It's Java.
  • It's small (the core interpreter is 140k).

I was tempted to pick Groovy for a short while but I decided that the learning curve and the sheer size of its jar file made it a non-starter.  BeanShell is cleary designed to be embedded and has a solid reputation, so it was an easy choice.

  And so far, I don't regret my choice:  integrating BeanShell in TestNG took less than one hour, and you can now specify things such as:

<test>
  <eval><![CDATA[
     
groups.containKey("group1") && method.getName().equals("test1")
     ]]
  </eval>
  ...
</test>

Since I never miss an opportunity to do something silly, I tried the following expression:

0 == JOptionPane.showConfirmDialog(
  new JFrame(),
  "Run this method?\n" + method,
  "TestNG",
  JOptionPane.YES_NO_OPTION);

which promptly displayed the following dialog for every single test method:

This way, I can hand pick the test methods one by one for every run.  Not exactly practical, but you get the idea.

The possibilities offered by embedding a scripting language inside TestNG are quite exciting and I'm looking forward to more twisted ways to abuse this feature :-)

 

Posted by cedric at 01:32 PM | Comments (1)

September 28, 2005

Interview

Vanward Technologies just posted their interview of me.  On the menu:  testing, scripting  languages, IDE's, and software in general.

There is one particular point I'd like to emphasize:

The reason why dynamic languages are not taking off as much as they should is because of the lack of IDE support.  I urge all people who feel passionate about their scripting language of choice to carve out some time from their busy schedule and write a fantastic IDE plug-in.  Failure to do that will condemn your language to a niche market forever.

For more details, please see the interview, and post your comments here.

And big thanks to Andrew for the interesting email exchange that led to this interview!

 

Posted by cedric at 08:39 PM | Comments (8)

Rob Harwood on IDEA

Here is an interesting interview of Rob Harwood, one the main IDEA developers.  In this piece, Rob discusses mostly IDEA, but his remarks on Eclipse are respectful and well balanced, which is quite a change from what we usually hear from the "third IDE" advocates out there.  He also discusses Swing/SWT, components, the Open API, etc...

My preference for Eclipse is probably well known at this point, but I have the utmost respect for the JetBrains guys, who not only manage to keep up the pace against Eclipse, but are actually still able to sell a product while competing in a free (as in "no money") market.

Congratulations, guys, and keep giving Eclipse a run for its money!

 

Posted by cedric at 10:23 AM | Comments (1)

September 26, 2005

Myst 5 : End of Ages

You will find no spoilers about any Myst episode in this post.

Myst 5 came out last week, and it sold out pretty much everywhere right away. My Amazon order showed it as shipping at the beginning of October but I found one copy at Target by luck, so I grabbed it and canceled my Amazon order.

I have been a long-time fan of the Myst series, and in my experience, every Myst that comes out is better than the previous one. I already mentioned how much I liked Myst 4 : Revelation, and I am quite looking forward to immerse myself into the D'ni world one more time. Cyan has been very clear that this episode would be the last of the series, but I am hoping that they will change their mind, or that at least, the parallel Uru series will keep the adventure game genre alive for many more years.

Quick anecdote about Myst 4: I was in Hawaii a couple of weeks ago and as I was walking in the tropical forest among the lush vegetation disturbed by the screams of various animals, my first thought was that it reminded me of the Haven world in Myst 4.... That's how good it was..

I spent an hour beginning Myst 5 this past weekend, and here are a few quick thoughts.

So far, the beginning has been a bit disappointing. I haven't been able to travel to a main age yet, and the scenery and the graphics are not really that impressive. I guess that six months of hardcore World of Warcraft set the bar very high, and it's disappointing to not be able to scroll at 360 degrees or to have to deal with jerky scrollings here and there.

But I have very high expectations, so don't get the wrong impression: the graphics are up to today's standards, and Myst 5 comes with three different ways to navigate, each conveniently assigned to the keys 1, 2 and 3. Mode 3 is probably the closest you can come to a World of Warcraft type of navigation (including complete freedom of movement, as in a first person shooter) while mode 1 only requires the mouse and one button to move around (but you are moving through static screens).

Cyan went one step further to make it easier for you to track your progress: not only can you take snapshots of any screen and annotate them, as in the previous episodes, the dialogues with the various characters are now archived as they happen, which will probably come in handy to make sure you didn't miss any crucial clue.

I will not say anything about the story itself, first of all because I have just begun, but most of all because the main appeal of the Myst series is to discover the plot line and unravel the mystery as it unfolds before you. A hallmark of the Myst series is the radical shift between the moment where you begin the game and you hardly understand anything you see or hear, and the feeling of triumph at the end when everything (and I mean everything) falls into place and suddenly makes complete sense.

I am looking forward to this moment, but I am even more prepared to enjoy the journey that will take me there.

Posted by cedric at 09:32 AM | Comments (0)

September 22, 2005

GMail vs. Outlook

    VS     

There are two programs that computer users feel very strongly about:  their email client and their Web browser.

Computer users very rarely change any of these applications, and it takes more than features to overcome the inertia and sense of comfort that you have acquired after spending so many hours on either of these tools.  And even though the Web browser has a very low retention threshold (except for your bookmarks and your habits, you are not putting much at risk by switching browsers), it's quite interesting to see how many people are still using the very first Web browser they started using.

The email client is even harder to switch away from, because the amount of personal email that you have accumulated over the years is not just huge, it's also extremely personal.  Of course, there is also the added damage that your email address might change in the process, forcing all your friends to update their contact information for you.

With that in mind, it's not without a certain sense of excitement that I recently made the decision to switch away from Outlook to...  GMail.

First of all, let me get something out of the way:  since I work for Google, you might think my decision has a corporate side to it, but those of you who read my weblog regularly know that I am fairly pragmatic person when it comes to picking the most productive tools.  A year ago, I wrote a comprehensive comparison between Outlook 2003 and Thunderbird where I explained my decision to prefer one over the other.

I spent these past months using both Outlook and GMail in an effort to evaluate and compare these two tools.  Outlook sets the bar pretty high in terms of functionalities and convenience, but what eventually tilted the scale was my one-week vacation Hawaii last week.  More about this below.

Most of the Outlook pros and cons that I listed in the article above are still completely valid (I can't find one that no longer applies, actually), so I guess that one interpretation of my switch is the realization that the drawbacks of Outlook have finally reached a point where I no longer want to tolerate them, and also because GMail has slowly gained functionalities that I considered essential.  Overall, I still think that Outlook is more functional than GMail, but given the rapid pace at which GMail is evolving and the diminishing tolerance that I have for delays in my email reading, it still emerges as a winner.

There are basically three factors that eventually broke the deal for Outlook:  connectivity, spam handling and synchronization.

Connectivity

As I stated in the article above, Outlook is much more powerful and seamless to use with an Exchange server than with IMAP.  The IMAP support doesn't seem to have received any kind of improvement these past years (not really surprising) and not only does it lock up the interface very regularly, it's also extremely slow.  In contrast, GMail is always lightning fast, even on slower lines (I regularly use in over my GPRS cell phone and the delays are barely noticeable).

Spam handling

There are many anti-spam programs available for Outlook (I reviewed some of them here) and after a few evaluations, I had settled on SpamBully for Outlook, which is very good but also very slow.  As a consequence, running it on an Inbox that hasn't been updated for a week can take almost an hour.  Yes, it's that slow.  But it was so good that I didn't mind taking the hit.  GMail's spam filter has been absolutely terrific so far.

Synchronization

I access both my personal and work emails from a lot of different places:  work desktops, work laptop, home desktop, home laptop and sometimes even, from computers that I don't own.  This latter option is obviously not possible if you use Outlook as your main client, but even the first four types of accesses are problematic.  So far, I was dodging the issue by using Remote Desktop to log into my work machine, where my main Outlook client is always running.  While Remote Desktop is an outstanding piece of software, this technique has some serious limitations, mostly because of its bandwidth-intensive nature.

Finally, there is one thing that has always been very clunky with Outlook and to which I had somehow gotten used to (or rather, resigned myself to):  the address book.  Despite many efforts, I have never really understood why Outlook has so many places where it stores contact information (the Address Book, Contacts and the online cache for completion).  I have never been able to reconcile them or use them in a consistent manner.  As a result, not only were my contacts scattered left and right in all these places, it was also maddeningly difficult to create groups of email addresses (and also keep them in sync as I make changes to the individual email addresses).

Now, there is one added benefit that completed my conversion to GMail:  transparency.

In case you are not aware, you can start using GMail right now and you don't have to ask any of your friends to update their contact information for you if you don't want to.  This made possible by a critical GMail feature: "From masking". You can tell GMail to display all the emails you send from GMail as coming from another email address.  This is really what makes everything work so well, and it's a feature that was recently added.  To configure your From address, go to Settings / Accounts / Send Mail as.

Let's see if GMail keeps its promises (and if you are curious to try it yourself, email me and I'll send you an invitation).

 

Posted by cedric at 01:37 PM | Comments (22)

September 20, 2005

Sudoku obsession

2    
     
     
7    
  4 8
    2
  5  
    6
3   9
9    
  7  
  2 5
6    
  2  
    1
2 4  
  8  
    3
8   4
6    
  9  
9    
4 8  
    3
     
     
    8

Have you been sucked into Sudoku yet?  If not, here is your chance.

Fill the grid above with numbers from 1 to 9, making sure that each row, each column and each box (the nine smaller 3x3 grids) contain each number exactly once.

Sudoku is a fiendishly addictive puzzle that has been gaining an extraordinary popularity these past months.  Three Sudoku books are listed in the New York Times' top 50 list, I have seen dozen of people playing Sudoku in buses and airports, but what really made me realize how big the craze was is when I asked my brother, who lives in France, if he had heard of it, and his answer was "Who hasn't?".

I like solving Sudoku grids myself but I find the software challenges even more interesting.  If you are up for a little exercise, here are a few problems for you to solve:

  1. Write a program that solves a Sudoku grid.  It doesn't look too hard at first, but you need to know that there are much more Sudoku grids than you think, and therefore, brute force will only take you so far.  You will need to apply a few selected strategies to prune the solution space, or your program will never complete in acceptable time.
     
  2. Now the reverse problem:  write a program that generates Sudoku grids.  It's fairly easy to accomplish for someone who has some basic computer science training, and if you don't, you will probably want to Google the terms "backtracking algorithm" (which is not the only way to solve this problem).
     
  3. And finally, now that you have all these Sudoku grids, rank them by order of difficulty, 1 being an easy grid and 5 being a very difficult one.  In other word, I should be able to ask your program to give me a rank 1 grid, which will be very easy, and a rank 5 grid that will take me much longer to solve.  When solving this problem, you will probably end up realizing that what is difficult for a human is not necessarily difficult for a computer, and vice versa.  As a hint, you might want to generate grids, solve them with the first program you wrote and then have this program report to you how hard it was.

Happy hacking!

Posted by cedric at 09:39 AM | Comments (22)

September 10, 2005

Why unit tests are disappearing

In a recent article, Michael Feathers enumerates a set of rules defining unit tests:

A test is not a unit test if:

  • It talks to the database
  • It communicates across the network
  • It touches the file system
  • It can't run at the same time as any of your other unit tests
  • You have to do special things to your environment (such as editing configuration files) to run it.

These are indeed very surprising rules, because a unit test is traditionally defined as a set of test that exercises a single class in isolation of all others.  With this definition, if the responsibility of your class is to verify that a file contains the appropriate data, it will obviously violate one of Michael's laws.  Yet, by my definition, this test still qualifies as a unit test.

Another interesting observation is that based on my experience, 90% of the tests that I see written with JUnit on a daily basis are not unit tests.

Anyway, these semantic games are fun to play but not very useful at the end of the day.  The bottom line is that the success of JUnit has shown that the line between unit and non-unit tests is increasingly being blurred.

However, when I write a test, I don't really care if it's a unit test or a functional test.

What I care about, though, is its categorization:  is it a database test?  A front-end test?  A network test?  Does it run quickly?  Slowly?

This is why groups are so important in tests, because they give the developer maximum flexibility to define additional information on the tests they write, something that packages or class naming cannot give you (a test class can obviously not belong to two packages).  And obviously, these categories are not mutually exclusive:  a database test can run fast or slow, as can a network test.

Here is what it looks like with TestNG:

@Parameters({ "name" })
@Test(groups = { "fast", "database" })
public void insertOneRow(String name) { ... }

@Test(groups = { "slow", "database" })
public void verifyIntegrity() { ... }

Do you want a quick sanity check before committing code? Run all the fast tests, regardless of whether they exercise the database or the network.

Do you want a full functional coverage to make sure absolutely nothing is broken in your product? Run the slow tests (or the integration ones).
Did you just modify a schema and you want to make sure you didn't break anything? Just run the database tests.

Groups are a very powerful and addictive feature once you start using them...

Posted by cedric at 05:42 PM | Comments (14)

September 07, 2005

FTP hack

I just came across this cool hack:

The idea isn't to get Squeak to serve out the file system, but to have a way to use the FTP protocol as an interface to any data you want, in the same way that dynamic web servers let you use HTTP for applications far beyond serving static HTML files.

The article illustrates the challenge by creating a dynamic FTP server that exposes the internals of a Smalltalk application.  Of course, it would be equally interesting to expose a Java application this way and browse the packages, classes and methods.  You could also imagine creating a file system (/dev/java ?) that would let you create an object with touch and remove it with rm... 

Completely useless, but totally cool :-)

 

Posted by cedric at 09:10 AM | Comments (8)

September 06, 2005

Setting pointers to null is useful

Setting pointers to null is useful

This discussion on TheServerSide is showing people up in arms about the practice of setting pointers to null:

FUD at its best... Not only it is unnecessary in most situations (read any Java book) but it is been lately discouraged to rely on such technique at all.

Itīs a false statement, GC works when the object is out of the scope, when has no references, if an object goes out of the scope all referenced objects goes out of the scope if they are only referenced by this object, a single null can send to GC tons of objects, itīs great, itīs invaluable.

There is no reason to set things to null to help GC do its work unless its part of your application logic or flow.

Setting pointers to null does help the garbage collector.  Regardless of the type of garbage collector you are using (generational, mark and sweep, etc...), setting a pointer to null allows the algorithm to skip a step in its implementation.  If you don't set the pointer to null, the virtual machine will try to follow this pointer and will, later, realize that the pointed object only has one reference, and is therefore up for garbage collection.  If you set the pointer to null, you save one step.  It's as simple as that.

Now, while this practice helps the garbage collector, it doesn't help it by much, and I would argue that for most applications (JSE and JEE), you should never bother using it.  It's a bit different for JME, though, where every byte counts and where I recommend (and personally use) this technique with lazy initialization to limit the amount of heap used by my applications.

Finally, one last comment:

Setting references to NULL to "help" GC is the easiest way to sign up for a NPE in other parts of the code.

This strikes me as a code smell.  If you are keeping a pointer alive just in case some other part of your code uses it, you have a bigger problem than memory management.  Regardless of your implementation, you should always be able to answer the question:  "Is this object still needed after this point or not?".  Sometimes, the answer is "maybe" (multithreaded code for example), but in most cases, the answer to this question should be a clear "yes" or "no".

 

Posted by cedric at 10:33 AM | Comments (11)