login
Blurts on the Art of Software Development

Today | RSS | RDF | Atom | Other Tags
Categories : All | All | CI | .NET | General | Humour | Java | Personal | Reviews | Ruby | SW Eng

I ran a serious after-hours hack-a-thon on Sunday this past weekend. The result of which is now a Sourceforge project named JspTest. Here's the short description from the Sourceforge summary page:

JspTest is a JUnit extension for testing JavaServer Pages (JSP) outside a J2EE container. Internally, it uses the Jasper JSP compiler from the Jakarta Tomcat project and the Java compiler distributed as part of the system's default JDK.

We're talking about real unit testing here, not integration testing against code deployed on a web container like is the case with many web-related "xUnit" libraries.

In other words, it lets you write unit tests for your JSP pages like so:

import net.sf.jsptest.JasperTestCase;

/**
 * Unit testing JavaServer Pages has never been this easy!
 */
public class HelloJspTest extends JasperTestCase {

    protected String getWebRoot() {
        return "./websrc";
    }

    public void testRenderingIndexJsp() throws Exception {
        get("/index.jsp");
        assertPageContains("Hello from Jasper");
    }

    public void testRequestAttributes() throws Exception {
        setRequestAttribute("who", "You");
        get("/say_hello.jsp");
        assertPageContains("Hello, You!");
    }
}

The good news is that there's no servers to start up (not even lightweight ones) and once a given JSP source file has been compiled (seems to take around 1 sec per file), further tests rendering that page with different request attributes etc. will execute blazing fast--just as if you were invoking a Servlet class directly (because you are!).

It's alpha and needs a whole lot of improvement (not least in terms of the API and extension points, not to mention missing built-in assertions) but it works alright for what I've used it on. What's in version control right now is based on a spike I did (I actually named the original Eclipse project as "JasperSpike") at figuring out how to use Jasper. As a result, the class hierarchy will likely evolve quite a bit in the near future. Also, I've only got a couple of acceptance tests in place because I was mostly just hacking to get Jasper's peculiarities sorted out for myself. That'll have to change if this thing takes on a life of its own.

There's no release, yet, (not even a development snapshot) so if you'd like to take a closer look you'll have to resort to doing a...

svn export https://svn.sourceforge.net/svnroot/jsptest/trunk jsptest-snapshot

...and (because I haven't yet written a build script) importing the "jsptest-snapshot" directory into Eclipse in order to export a .jar file.


PS. I am aware of the JSPUnit project at Sourceforge and that the first Google hit for "jsptest" is an existing open source library with the same name as my stuff. The thing is, both of these are effectively dead and haven't seen any real activity in years. They're basically inferior implementations of a subset of what projects like HttpUnit, jWebUnit, HtmlUnit, and Canoo WebTest offer to thousands of users worldwide.


Cool stuff Lasse! Have to check this out ASAP!

Thanks, although you won't yet have much to work with--there are hardly any built-in assertions implemented in trunk.

The good news is that if you've used HttpUnit before and have a "AbstractHttpUnitTestCase" lying around with a bunch of assertions built on top of WebResponse, you should be able to copy-paste most of the stuff into a JspTest test class.

Or, better yet, send me your assertion code and I'll add those into WebResponseTestCase.

As an early step in the project I'm currently working on, I did some experiments a year or two ago to prove to myself that out-of-container execution of pre-compiled JSPs is feasible. I'm kind of surprised nobody seems to have tackled this more formally, as the basics are pretty obvious and straightforward. So it's very interesting to find someone else that sees the benefit of being able to do out-of-container testing of JSPs, and who's starting to try out the use of Jasper in this context.

Of course, once you can execute JSPs you're back at the more general problem of how to test servlet code outside of a container (as the JSP could make pretty much any use of the servlet API, tag libraries etc, unless one restricts them in some way). But at least improvements in Jasper plus Java SE 6 support for compilation should make it a lot easier to automate the JSP translate & compile steps.

In the past I've tried testing web components using mock objects and various other tools, but haven't personally found any of them to be a good fit for unit testing of arbitrary "real" code. The "in-container" approaches are by nature too inconvenient and restrictive, but none of the existing "out-of-container" tools I've looked at seem adequate; there always seems to be some important failing re features, generality, convenience, reliability, documentation, or the overall status of the product. (Yes, I'm working on an a new alternative, but can't talk publicly about it yet).

I'd be interested in your own view on mock objects and the various approaches and tools for testing of Servlet/JSP code (e.g. Cactus, ServletUnit, HttpUnit etc)... are their limitations part of your motivation for JspTest, or have you generally found in-container testing and/or mock objects to be sufficient for most purposes?

Anyway, good luck with JspTest!

Mike,

The biggest driver for my ending up putting together JspTest would have to be the hoops one has to jump through to get HttpUnit's ServletRunner, for example, set up. It's not many lines of code but still.

By bypassing the Servlet container we're effectively getting direct access to the code we're testing (just like testing a Servlet class, as you said) and we're able to intercept (mock) taglibs etc. -- something we could not do with container-based approaches.

In-container testing is always in the "last resort" category in my books, mostly because I don't like waiting several seconds for the tests to even start. In other words, I tend to prefer mock objects over the real thing and JspTest is kind of like the necessary plumbing that lets me invoke my JSP, possibly making use of some mock objects.

have you written any documentation for how to use this? It looks simple but every little bit helps

I'm afraid I haven't. That's on top of my to-do list for JspTest -- some kind of a 5-minute tutorial plus publishing proper javadocs online for the API.

The thing is, I'm renovating right now so spare time is an oxymoron for me at the moment.

Yep, know that that's like. Now for a more significant request. Know of anything like this for JDK1.4 and Struts1.1 code? This one looks like it requires JDK1.5 and other much newer things than I have in my environment ;-(
Hi Lasse, I found two bugs in the current implementation. I filed them in sourceforge. I also added the fixes of course! Great Job!
Thanks for the contributions, Mathias! I've applied both patches with slight modifications to the trunk.
Hi Lasse,

I did a first try on our project - which has of course some nice traps for jsptest ;) I filled your patch list with the fixes for the issues.

Thanks, Mathias! Since I'm not using JspTest myself at the moment (it started as a proof-of-concept that took on a life of its own :), this kind of end user feedback is ever more important. For example, I had already fixed that jar path stuff (locally) but had no idea that non-string attributes were needed - now that you mention it, we did use that stuff all the time but it wasn't obvious to me anymore... Good stuff!
Hi Lasse: I'm echoing arturo's comment, since (coincidentally) I am working with a team that is suffering with the same Struts 1.1 Java 1.4 technology stack.

Lasse, we really need your tool. I'm hoping there is a way for it and its dependent jars to work under Java 1.4. Is there a way?
Patrick,
I've tried to configure Eclipse to use 1.4 for the JspTest stuff and it's not showing any violations - but apparently it's not reliable. Once I switched to using an actual 1.4 JRE, I saw that there were indeed calls made to post-1.4 API. I churned out a new release (0.17) with these fixed - it's now available from the public Maven repository.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 7 + 9 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/lasse/addTrackBack.action?entry=1144185588886