Archive for the 'tech' Category

Writing Brittle (Yet Useful!) Acceptance Tests for ExtJS Applications Using Selenium’s getEval()

Friday, August 15th, 2008

I’m a somewhat enthusiastic fan of Selenium these days. It works consistently well in most situations, and it provides some mechanisms for “going deep” when its more regular API calls prove insufficient.

Recently, I was testing an application we’re writing that has a front-end built using the ExtJS framework. Normally, with a bit of XPath-fu, testing our (neatly!) tangled messmass of Javascript is no big deal, but occasionally, ExtJS produces a div or other element that Selenium just can’t seem to find. I ran into such an element (a div with a handler) that I *really* wanted to have my test click(), but no amount of XPath munging would get the job done. Perhaps Selenium is more strict about what elements are click()able than I thought, but no matter, getEval() to the rescue.

I found a number of interesting blog posts on the subject, with the best being Darren Deridder’s. This got me started on using this.browserbot.getCurrentWindow().Ext in the getEval()… the Ext object provides get() and getCmp(), which are gateways into basically any element in your application.

Of course, the one downside to this is that your effectively shortcutting the entire idea of acceptance testing, as your user-agent is now (but only briefly) doing something that your real end user wouldn’t do. I will only use this sparingly, I promise!

The end result are lines something like this in your testing code (C# here, broken up because our CSS won’t wrap it properly):

DefaultSelenium _selenium = new DefaultSelenium(
    "localhost",
    4444,
    "*iexplore",
    "http://localhost");

_selenium.Start();

String evalString = "this.browserbot.getCurrentWindow()."
evalString += "Ext.getCmp('my_component_id').items.get('some_subcomponent_key').doSomething()"

_selenium.GetEval(evalString);

You don’t even have to use the Ext object here… the scope this.browserbot.getCurrentWindow() is your application. The possibilities are endless, but remember the caveat: you’re doing something a real user-agent won’t, so be careful with this in an acceptance-testing scenario.

(Another thing to make the most of this technique is Firebug’s console.dir() function, which you can use while debugging to quickly examine object dumps.)

Hudson - too easy

Saturday, August 2nd, 2008

Continuous integration is a lovely thing. Automated testing is also lovely as you can see where things work or not almost instantly in different environments and scenarios.

Over the years I have used a few CI servers and tools - most notably, CruiseControl (Java and .NET) and Continuum (from the Maven crew). These systems, whilst useful, cam e with a few annoyances, most notably their slight fiddliness in getting up and running. Whislt they worked, it seemed that there were always tweaks required here and there to get things running smoothly and when things went wrong they we not that easy to correct.

After chatting with a few friends, I thought I would give Hudson a try as it seems like a new contender for CI server of the month. Spurned on by glowing feedback from said friends I though I would see how easy it would be to try and aggregate our disparate CI servers (For Java and .NET) into a single hudson installation - something advertised to be easy on the tin.

Here are the steps I followed:
- download WAR, runit
- config master/slave
- config maven app
- config .NET app
- force some builds
- too easy

A simple distributed build system that works cross platform sounded too good to be true, however it seems that hudson is well on the way to being just that. I couldn’t believe how easy it was to get a distributed build/CI system up and running and building/testing our Java and .NET apps with all reports and config managed centrally. I especially like the simple reports on build trends and the weather paradigm used for displaying build stability.

After this simple proof of concept, we moved the setup to a cluster of VMWare instances (Linux and windows) so we can now build multi-platform apps and manage things centrally for all projects. This is now our main CI platform and seems to be working well.

Hurray for progress!

No Fluff Just Stuff, April 2008

Tuesday, June 17th, 2008

With forecasts of April snow, our 2Paths contingent of two headed off at the crack of dawn one Friday for Bellevue, WA to attend the No Fluff Just Stuff - Pacific Northwest Software Symposium (NFJS). Having only spent 10 minutes at the border (whew!), we arrived early enough in the Seattle area to fit in some Fluff (aka shopping and dining) before getting into the Stuff.

After a quick introduction by Evangelist Scott Davis, and with hopes of winning an IPhone by the end of the weekend, I headed right into his double-bill of sessions about Groovy. The first one entitled “Groovy, the Blue Pill: Writing Next Generation Java Code in Groovy” was a good gentle introduction to neophytes like myself on Groovy basics. Now that my interest was piqued, I was eager to continue on with Scott’s next session “Groovy, The Red Pill: Metaprogramming, the Groovy Way to Blow a Buttoned-Down Java Developer’s Mind”. Never mind the Blue Pill - the Red Pill is where it’s at!

Scott’s enthusiasm for Groovy was definitely contagious, and my mind started churning, trying to think of ways to start introducing Groovy into current projects or future projects at 2Paths. An allure of Groovy is that it’s a dynamic language and can be run on the JVM. Groovy is implemented in Java, so the two languages offer seamless interoperability. Groovy compiles down to Java bytecode, so Groovy code can call Java code, and vice-versa. This would make integration into our existing infrastructure much simpler.

The Blue Pill was starting to take effect, as Scott showed us the terseness of the language. No need to labouriously write getters and setters, amongst other many nifty language shortcuts. Who needs semicolons or parentheses anymore? Because Groovy really is Java under the hood, programmers unwilling to let go of that extra baggage can continue to use it and nothing will break. We were then shown demos on how much more quickly we could bang out Unit Tests in Groovy.

In the next session, the Red Pill stuff was pretty mind-blowing. Introducing method pointers, closures, the ExpandoMetaClass. Method pointers make our code more readable and understandable by allowing us to alias methods with semantics tailored to our own business logic. Closures are an exciting and powerful inclusion in Groovy that aren’t available in Java, allowing us to pass around executable snippets of code. And last but certainly not least, there’s the ExpandoMetaClass that lets us either do a lot of really cool stuff, or get ourselves into a heap of trouble. With the ExpandoMetaClass we can intercept methods and inject methods into any Class. Scott showed us some fun examples that got us all fired up wanting to try more!

With my introduction to Groovy setting the stage for the weekend, I went on to choose more sessions on Groovy (Design Patterns, Testing, Groovy with Spring), but also attended other sessions such as Spring Configuration, Regular Expressions, and GIS for Web Developers. I found most of the other sessions mostly affirming knowledge I already had, but augmenting it with good snippets here and there that were new to me. Venkat Subramaniam was the other main Groovy Prophet, and I came home with his book “Programming Groovy” in hand, eager to start integrating Groovy at least into our testing infrastructure.

The atmosphere at NFJS was inspiring, as the speakers all had great enthusiasm for the technologies they were touting, and the audience was generally equally as keen. It felt great to be in a large conference hall amongst so many other like-minded programmers, all sharing, and getting fired up about what we do, and our seemingly unlimited potential. I fully recommend NFJS (regardless of me not winning an IPhone), and would love the opportunity to go again!

You got mono!

Sunday, May 25th, 2008

One of our recent projects has a .NET backend (with a JavaScript frontend). As we use macs for our dev platform, this means dual booting or using parallels in order to fire up Visual Studio to work on and debug the backend using the embedded ASP.NET server … until now.

The other day, out of curiosity, I downloaded Mono for Mac OSX to see how it works and if it would be at all viable to use as a development tool for .NET projects. With the installation came a Mac version of the MonoDevelop IDE which supports Visual Studio 2005 solution and project file support. I thought it sounded too good to be true but decided to give it the five minute test to see what might happen. I did a fresh checkout of the codebase, fired up MonoDevelop, opened the projects solution file and unsurprisingly some things did not function. For one, we use an add-in for Web Deployment Projects which wasn’t recognized. Additionally there seemed to be some build issues when trying to locate our logging DLL. With a bit of poking (literally a few minutes) I had found that all we needed was a hint in the project file to point to our DLL and the project built - very scary. Next thing was seeing if it would run.

As it turns out, Mono comes with an ASP.NET server called xsp2. Even more interestingly, editing the properties of the web Cleint project in MonoDevelop reveals very simple integration with xsp2 as an embedded server. This was all looking too good to be true. A simple config change (ports) and then I hit run for the client project and was amazed that the thing actually came to life and seemed functional. Very shocked was I!

There was a minor problem in that our configuration service was reading files and serving them to the client but had issues with line endings given the difference between windows and mac platforms and their ideas of what a line ending should be (for the record its \n!). That was swiftly fixed and the app not only came to life but was fully functional.

Admittedly, MonoDevelop is a pretty rough IDE but the fact that it took less than 30 minutes and not much tweaking to get things working was quite a lovely surprise!

Persistence

Friday, April 11th, 2008

Any developers working on projects involving databases will need to be aware of persistence strategies, and take these into consideration at design time. Persistence strategies are tailored to specific projects depending on a variety of circumstances such as if they are read-only or read/write, how important the timeliness of data is within the application, and how likely it is for data-collisions, etc. If coupled units of work involve writes to various tables, the units of work will need to be wrapped in transactions to avoid data corruption, and have proper rollback strategies in place. Optimistic or pessimistic locking strategies need to be put in place where there are possibilities of data collisions. Appropriate isolation levels need to be associated with the transactions.

These concepts are all database-agnostic, but there are specific tools for use with Java, Hibernate, and Spring to assist in persistence strategy integration. For more information, see the wiki here:

https://dev.2paths.com/wiki/display/2pathsTECH/Persistence

Seriously, No BullFluff

Friday, October 5th, 2007

Last week’s No Fluff Just Stuff symposium was undoubtedly the best Java event I’ve attended thus far, and the icing on the cake was Brian Sletten’s talk on “Beyond Cute-sy Mashups”. It was worth showing up for that alone. It’s not very often that it happens, but I’m stoked.

Below is my newly updated ‘Bleeding Edge Learning Curve Road Map’:

No Fluff Just Stuff

Friday, September 28th, 2007

The day started curiously as I was waiting for the 57, where I came across a quaint wannabe bus driver from Somalia. Naturally, I asked him why he had opted for life over here in Canada. “Here the supermarkets don’t sell bullets side by side with the vegetables”, was his honest reply. I never did get his name, but he did manage to leave an impression.

Anyhow, arriving at the square dusky-coloured Delta hotel, Barbie presented me with my name tag for this year’s No Fluff Just Stuff Western Canada Software Symposium. I inquired if it wasn’t necessary to register, at which she bluntly retaliated, “Are you lying about having paid? Well, you look like a honest guy, but nice of you to ask!”. Charming.

Scott Davis kicked off the show, and before we knew it, he had bewildered us Java techies with some Groovy magic. As his finale, he had Grails spooning off a fully-CRUD enabled web app in a split-second jiffy. Admittedly Grails does hit that sweet spot, which no doubt will have me succumbing to its allure, yet one growing pet peeve I have with it is that it does come with shackles of its own. For one, it imposes its own build tool, namely gant. But since, for better or for worse, most of us use maven as our build tool of choice, i would cast an early warning to the coders behind Grails - choice is key.

Thus, and surprisingly so, the much talked about shiny new toy didn’t earn my first merit, instead the honour went to a talk on Agile testing strategies. Jared, a likable confectionery-throwing speaker, not only talked a good talk, he also walked the walk. Test Driven Development (TDD) is a notion that has been much paraded about on the Agile front, yet until now I have remained skeptical. Until now, I didn’t fully take on board what its potential benefits could be. Enlightened, I now realize that by using TDD this has the knock on effect of it driving the design, hence driving the developer in keeping the code testable, which in turn keeps it simple, modular, and loosely-coupled. Genius.

And with that, I will finish off Day 1 with the quote of the day:
“I can’t fix stupid” ~Jared Richardson’s take on dumb developers.

Sweet Online Reference Tool

Thursday, June 7th, 2007

Got API

Unit Test Your Web Security

Thursday, May 31st, 2007

Web-based business applications require stringent security measures. Within a secure website, a user must be authenticated by the system and for each different user role a predetermined set of authorization rights must be imposed. This isn’t anything new, and luckily, there exists an open source Java security framework, known as Acegi, which makes the job of keeping those hackers at bay a relatively straightforward one.

Acegi is a powerful, flexible security solution for the Java enterprise application. Working in tandem with its best friend, Spring, it provides applications with comprehensive authentication and authorization capabilities.

Integrating Acegi into your Spring enabled web application is generally an easy, although perhaps sometimes tedious, process of adding a bunch of XML wiring into your Spring context. And after you add that little extra touch of custom configuration for your specific web application, you are good to go.

Or are you? How do you know the thing actually works? And, more importantly, how can you be sure that it will continue to work for every project build? Here’s a JUnit test that shows you how.


package com.twopaths.test.core.security;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import
  org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;

public class AcegiSecurityTest
  extends AbstractTransactionalDataSourceSpringContextTests {

  private static final String SECURITY_CONTEXT_CLASSPATH =
    "classpath:/com/twopaths/test/core/security-context.xml";

  private static final String TEST_USERNAME = "test";
  private static final String TEST_PASSWORD = "test";

  private MockServletContext servletContext;
  private MockFilterConfig mockConfig;
  private FilterChain mockFilterChain;
  private Filter authenticationFilter;

  @Override
  protected String[] getConfigLocations() {
    return new String[] {SECURITY_CONTEXT_CLASSPATH};
  }

  @Override
  protected void onSetUpInTransaction() throws Exception {
    // Insert user dummy data
    jdbcTemplate.execute("insert into end_user values(1, 'ROLE_USR', '" +
      TEST_USERNAME + "', '" +
      TEST_PASSWORD + "', 'true')");
  }

  @Override
  protected void onSetUpBeforeTransaction() throws Exception {
    // Init servlet context mock
    servletContext = new MockServletContext("");
    servletContext.addInitParameter(
      ContextLoader.CONFIG_LOCATION_PARAM,
      SECURITY_CONTEXT_CLASSPATH);

    // Init servlet context listener
    ServletContextListener contextListener = new ContextLoaderListener();
    ServletContextEvent event = new ServletContextEvent(servletContext);
    contextListener.contextInitialized(event);

    // Init filter config and filter chain mocks
    mockConfig = new MockFilterConfig(servletContext);
    mockFilterChain = new MockFilterChain();

    // Init authentication filter
    authenticationFilter = (Filter)
      this.getApplicationContext().getBean("authenticationProcessingFilter");
    authenticationFilter.init(mockConfig);
  }

  public void testThatTestUserLogsInOk() throws Exception {
    // Build mock request
    MockHttpServletRequest request =
      new MockHttpServletRequest("POST", "/j_acegi_security_check");
    request.setParameter(
      AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY,
      TEST_USERNAME);
    request.setParameter(
      AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY,
      TEST_PASSWORD);

    // Build mock response
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Run authentication filter
    authenticationFilter.doFilter(request, response, mockFilterChain);

    // Get authentication instance
    Authentication authentication =
      SecurityContextHolder.getContext().getAuthentication();

    // Verify authentication instance
    assertNotNull(authentication);
    assertEquals(TEST_USERNAME, authentication.getName());

    // Verify response redirected URL
    assertEquals("/home", response.getRedirectedUrl());
  }

}

Eclipse WTP 1.5.4 and 2.0RC1 for OS X

Monday, May 28th, 2007

I’ve downloaded and hand-configured the latest Eclipse WTP builds for your convenience. I’d included the Subclipse SVN plugin as well. If there are any other plugins you’d like to see by default in the future, let me know.

First of all, if you haven’t installed this update to the Java SWT libraries from Apple, do it now. It should improve stability with Eclipse.

Download: SWT Compatibility Update (188KB)

Eclipse WTP 1.5.4 is the latest update to the WTP 1.5 line. Not anything new, but contains numerous bug fixes etc.

Download: Eclipse WTP 1.5.4 (183.9MB)

Eclipse WTP 2.0 RC1 is based on Eclipse 3.3 RC1 and appears to be fairly stable. Some of the new features are support for Tomcat 6, support for JPA projects (annotations, , mappings etc), built in support for web services, and spell checking. This is pre-release, so use at your own risk (I’ve been using it and it seems ok, although I keep my 1.5.4 around just incase).

Download: Eclipse WTP 2.0RC1 (227MB)

Remember to update your copy of eclipse regularly to receive the latest bugfixes, or better yet, set it to auto update in preferences.