Skip to content

Integrating JavaScript Tests with Continuous Integration

At my current client I’ve been building a rather complex rich client app using ExtJs. The team has written a lot of JavaScript code, and has been writing a lot of JavaScript unit tests as well.

We’ve gone through several unit testing tools along the way trying to solve some logistical problems. We started with JSUnit, added Selenium, switched from JSUnitt to envjs, and are now using a hybrid approach I’ll describe in detail.

Some of the issues we wanted to address with our testing tools were:

  • How easy is it to run the tests?
  • How easy is it to debug the tests?
  • How easy is it to integrate the tests into our existing continuous integration environment

Most of the tools we used easily met the first two logistical issues, but the last one was not as simple.

The following describes an approach that meets all of the above list (after the jump).

(Continued)

Revert to Console for IM – Gtalk Example using Mcabber

I can finally sleep at night now that I have a command-line solution for Google Talk.

What’s needed (for a poor windows user):

If cygwin and ssh are new to you, read this to get up to speed.

If you are setting up mcabber on a host machine, you’ll want to setup ssh as a service or daemon on that machine as well. Use the ssh-host-config script to do that.

Quickly, here’s how to get going.

  1. Get the latest updates for cygwin using the cygwin setup program. I was missing the latest glib and I didn’t have pkg-config.
  2. Download the mcabber source from the website. Run the configure script with no arguments. Take note of any errors; they are most likely related to missing libraries. Get these libraries with the cygwin setup program.
  3. Once configure is successful, you should be able to run make, and then make install with no problems.
  4. Create a mcabberrc file in the directory ~/.mcabber, note that the filename is “mcabberrc” and not “.mcabberrc”.
  5. Put the following into the mcabberrc file to configure it for Google Talk.

set username = <your username at gmail dot com>
set server = talk.google.com
set ssl = 1
set ssl_verify = 0
set port = 5223

That’s all there is to it. Type mcabber and it should prompt you for your password and then connect.

You’ll see 3 different “panes” or frames and the command prompt at the bottom. Scroll through your contacts with Page Up and Page Down. When you’ve selected a contact, just start typing in the command prompt to send messages. The program commands start with a “/” character, type “man mcabber” for a complete list of commands. If you’re in mcabber, you can type “/help” for help on specific mcabber commands.

That’s all for now!

-eokuwwy

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

The best 59$, a java developer can ever invest

If you don’t buy this now, you’re either dumb. Or just plainly stupid.

For the impatient: it’s a small jar that lets you compile/run/deploy java instantly, like php. I’ts the real HOT DEPLOY that jvm lacks out of the box.

No more restarting the server, ever again, even after reconfiguring Spring beans.

I used this for a month, and convinced my manager to buy licenses for all. It’s that good.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Basic Pine Gmail Config

I always forget this, and periodically find myself setting up a new pine client. So rather than digging around on the web each time, I’m adding my notes here:

Create a .pinerc file, maybe a custom one for gmail like .gmailpinerc

POP3

smtp-server=smtp.gmail.com/user=user@gmail.com/ssl

inbox-path={pop.gmail.com/pop3/ssl/user=user@gmail.com}inbox

IMAP

smtp-server=smtp.gmail.com:587/tls/user= user@gmail.com

inbox-path={imap.gmail.com:993/ssl/novalidate-cert/user= user@gmail.com}inbox

There are a host of other options that can be configured, but this is a good start.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Unit Testing JavaScript with HtmlUnit and Screw.Unit

Writing apps with today's rich client libraries such as Extjs , YUI , and JQuery really shows how much potential is still left in web development. But it takes a lot of code, and the amount of technical debt can get heavy, quickly. Good tests can help reduce this technical debt, and there are a lot of testing tools available for the client. Today though, I want to go beyond just using a tool, and talk more about integrating your JavaScript tests into an existing Continuous Integration environment. 

I have a confession to make- I hate running tests manually. I'll write tests when I'm doing new development or bug fixing, but I hate running them after I've fixed the bug or implemented the code. That's why we have CI environments, right? So I don't have to run the stupid tests each time! There are enough ridiculous rules put in place in corporate work environments today already, I don't like adding tasks that can be automated into the mix.
Here's what I've come up with for integrating my JavaScript Unit Tests:
  1. Write tests with Screw.Unit . Why Screw.Unit? I like the simple DOM it creates. I like the code behind it- specifically the separation of builders and matchers. It's relatively easy to debug my code in Firebug. But mostly, it's because it's of the easy DOM it displays. There's nothing magical about Screw.Unit. It's just a simple tool. But that's the point.
  2. Use HtmlUnit to execute Screw.Unit tests, and inspect the results. HtmlUnit has the best JavaScript framework support in the Java world today. It uses Rhino to execute JavaScript and has written very comprehensive DOM support on top of that. It can handle most major JS framework code. So I execute my tests with HtmlUnit, and then inspect the simple DOM results. Easy!
  3. I use a Parameterized JunitTest to read through all of my ScrewUnit tests (*.html files), and execute a JUnit test for each. 
Done! Simple integration at it's best.

Posted via email

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Developing Grails Apps in Eclipse

This was a post I was planning on linking to; a colleague of mine was going to write a post about it, but he hasn’t yet and I’ve just spent an extra hour trying to get this to work and am frustrated- and so here is the post you’ve all been waiting for.

There are lots of holes in the existing documentation about setting up eclipse to work with grails.

First off, you will want to generate groovy class files to a directory, like bin-groovy. It’s not just for debugging, it’s also for running unit tests. Running unit tests from eclipse is a lot faster than running them from the command line, because eclipse will generate the class files needed as you develop. It’s really nice to have.

Here’s where the fun starts- let’s assume you want to use a plugin. It’s a reasonable assumption, since there are so many cool plugins available. The first thing you need to know is where plugins download and install to. These go to a plugin directory in your .grails directory, which is normally in your home folder. You’ll need the jars from these plugins in your eclipse classpath, so you’ll need to unzip them and add them as external jars. Then, you’ll also need the source from those plugins in your classpath. For this, I added an External Class Folder to my Java Build Path- the folder was located in .grails/projects//classes.

While you’ll want to uncheck the Disable Groovy Compiler Generating Class File checkbox, you’ll want to enable the Disable Check Package Matches Source Directory, otherwise you’ll have a compiler error from resources.groovy.

Finally, add bin-groovy as a class folder to your java build path libraries tab.

This entry was a big help.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Grails and HtmlUnit

I was struggling to add HtmlUnit to Grails to do some testing when I came upon this.

The solution was to remove the HtmlUnit included jar, xml-apis-1.3.04.

The error looked like this:

loader constraint violation: loader (instance of &amp;amp;lt;bootloader&amp;amp;gt;) previously initiated loading for a different type with name &quot;org/w3c/dom/NamedNodeMap&quot;
java.lang.LinkageError: loader constraint violation: loader (instance of ) previously initiated loading for a different type with name &quot;org/w3c/dom/NamedNodeMap&quot;
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
at java.lang.Class.getMethod0(Class.java:2670)
at java.lang.Class.getMethod(Class.java:1603)
at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.isDom3Present(ContextFactory.java:301)
at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.getE4xImplementationFactory(ContextFactory.java:328)
at net.sourceforge.htmlunit.corejs.javascript.Context.getE4xImplementationFactory(Context.java:2175)
at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.initStandardObjects(ScriptRuntime.java:222)
at net.sourceforge.htmlunit.corejs.javascript.Context.initStandardObjects(Context.java:1069)
at net.sourceforge.htmlunit.corejs.javascript.Context.initStandardObjects(Context.java:1036)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.init(JavaScriptEngine.java:157)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.access$000(JavaScriptEngine.java:68)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$1.run(JavaScriptEngine.java:130)
at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:515)
at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.initialize(JavaScriptEngine.java:141)
at com.gargoylesoftware.htmlunit.WebClient.initialize(WebClient.java:1107)
at com.gargoylesoftware.htmlunit.WebWindowImpl.setEnclosedPage(WebWindowImpl.java:99)
at com.gargoylesoftware.htmlunit.html.HTMLParser.parse(HTMLParser.java:268)
at com.gargoylesoftware.htmlunit.DefaultPageCreator.createHtmlPage(DefaultPageCreator.java:127)
at com.gargoylesoftware.htmlunit.DefaultPageCreator.createPage(DefaultPageCreator.java:101)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:442)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:329)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:386)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:371)
at UIUnitTests.setUp(UIUnitTests.groovy:12)
at _GrailsTest_groovy$_run_closure4.doCall(_GrailsTest_groovy:202)
at _GrailsTest_groovy$_run_closure2.doCall(_GrailsTest_groovy:146)
at _GrailsTest_groovy$_run_closure1_closure19.doCall(_GrailsTest_groovy:112)
at _GrailsTest_groovy$_run_closure1.doCall(_GrailsTest_groovy:95)
at TestApp$_run_closure1.doCall(TestApp:66)
at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy:334)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:344)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:334)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.processTargets(Gant.groovy:495)
at gant.Gant.processTargets(Gant.groovy:480)
[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

A Note On Checking In Open Source Crap

Ok, so I just announced the my new google code project, and I’m checking in the 0.00000002 alpha version of the code. And this is a media app, so I’ve got some test data, some mp3s. And I didn’t think before I committed, and low and behold subclipse is chugging away in it’s customary slow IDE crappy fashion with 100+MB of mp3s to upload! Oops!

Now, to be honest, I really don’t care about that, it’s just digital detritus after all. But there are really creepy, nasty, vile corporate interests that do care a lot about it. And as much as I think they’re vile, immoral, creepy entities whose members will surely rot in hell, I have to let them, at least momentarily, invade my normally quite pure thoughts… and I gasp in horror at the thought of invertantly violating their corrupt business practices- er I mean copyright laws… and…

Anyway I killed the process midstream.

This is one of those things you don’t think about until something crappy like that happens. Normally a VCS process is simple- commit, comment, done! I really don’t think about it. It’s habit. So what happens when you think you’re committing 100 or so files and maybe that amounts to 1MB and suddenly whoops! And you kill the process?

Well, SVN really has trouble dealing with killed processes, obviously. But thankfully it cleans up after itself really well!

svn cleanup

That’s it. It’s easy. But I didn’t see an svn cleanup option in subclipse, so I did it from the command line.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

New Google Code Project

I’ve started a new google code project, tuneshost, for a presentation I’m giving this week. It’s a bare minimal start, and in the short term I’m not going to be making many enhancements- I’ll just be using it to demonstrate htmlunit and selenium testing.

It’s built on the grails platform, and uses extjs for the UI. Communication is predominantly done in a restful fashion, with json. I’m using the acegi and searchable plugins. (btw, searchable is a @#$!@# awesome plugin!!!)

The concept is that you search through your media (it supports music right now, but the plan is to support all media), a la google style. I’m tired of importing 4 gigs into iTunes over my home network and having to wait 2 hours for it to finish. I’m also tired of syncing my ipod. So it’s streaming media for me all the way, and smart searching.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

JBoss Seam 2.1 Presentation at Java Meetup

Here’s my presentation on JBoss Seam 2.1 from the Boston Java meetup group

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]