Main Page | Recent changes | Edit this page | Page history

Printable version | Disclaimers

127.0.0.1 (Talk)
Log in | Help
 

AspectJ-based framework for SWT

From AbbotWiki

The following is adapted from a wiki page written by Kyle Shank.

Table of contents

Overview

Framework

The intention of this testing framework is to provide an accessible and maintainable abstraction to Abbot. The old way of defining test cases required inexact timing assumptions, lots of setup and pratically unmaintainable code that resided in dozens of inline Threads. It was far too complex and time consuming to be productive. The new approach deals with these issues by defining a standard for reusing code via helper classes, eliminating the need to fret over delays and abstracting thread operations to the framework.

SimpleCase

SimpleCase is the main abstract class from which all others derive from. It extends JUnit's TestCase and takes care of initializing the context that will be used throughout the test. SimpleCase and its inner classes do the heavy lifting when it comes to threading.

The perform method of SimpleCase is abstract and must be implemented by the helper subclass. SimpleCase.perform will invoke the specified method on the test case through reflection. It has been made abstract so the implementing helper actually performs the invocation action as opposed to the superclass that may or may not encounter IllegalAccessExceptions.

SimpleCaseWorker is an inner class that extends Thread. It is the object returned from the start(function) method. The start method will construct the SimpleCaseWorker object and thread the call to the specified function. The function is passed to the start method as a string. SimpleCase takes care of setting things up for the reflection invocation and then calls the perform method on the helper with the appropriate arguments. The reason for this abstraction to simply thread the method call is to avoid defining inline or many Thread classes that keep functionality within their defined run method. This allows the test writer to simply add the method to their class and tell the framework to thread the call. The exec(function) method works much in the same way start does except it does a safeJoin and waits for the thread to complete before returning. You can think of start as asynchronous and exec as synchronous calls to a method.

SimpleCase houses the important static utility method "waitForJobs" which joins on jobs remaining in the eclipse ob manager to ensure safe test execution. SimpleCase.waitForJobs will be hooked before every call to a helper method to validate that it is indeed okay to proceed.

While threading was at the heart of the original test cases, this new framework only uses it in a few choice situations. The safety hooks that query eclipse's job manager now protect the test case from executing at the wrong time. As a result, the test writer no longer needs to define inconsistent delays or a seperate thread for every bit of functionality. With that said the use of the threading using start method should now only be required when dealing with dialogs or other shells that abbot must wait on in order to gain access. For instance, you would need to do this if you wanted to automate action within a New Faces Action wizard. The process would entail calling start with the function that wait for the shell then clicking on the Faces Action palette item. Examples of this can be found in the test.helpers package. The bottom line is that

structure

The helper library introduces a new way to create test cases. One of the goals of this framework was to make it even easier for the developer to write test cases. With the helper library this is done by having the helper functions return instances of the helper class itself. This in effect creates a mini-grammar within java that doesn't break the programming flow. The following example focuses on the editor for FacesFromCB.jsp, drags a command button onto the faces page and changes its ID.

DiagramHelper.openSession(context)
.clickTab("FacesFromCB.jsp")
.dragPaletteItem("Command - Button",200,200)
.doubleClickLabel("Properties")
.doubleClickLabel("&Id:")
.keyAction(SWT.SHIFT | SWT.END)
.keyAction(SWT.DEL)
.keyString("hello");

aspects

The framework uses a single aspect (Safety.aj) to define a pointcut that will call SimpleCase.waitForJobs() before every method matching this expression public * test.helpers.*Helper.* (..). This means that the framework will automatically check and wait on existing jobs before every call to a helper method. This is done by defining an extension point on the org.aspectj.weavingruntime extension point named org.aspectj.weavingruntime.aspects. Define an aspect on the extension point and have it point to the defined aspect Safety.aj. That's it: the aspect will now be applied at runtime. The traditional approach to this issue would have been to apply some variant of the Proxy pattern. This would require maintainence of three interfaces instead of one. That doesn't help the TDD cause or encourage the creation and sharing of helper libraries.

Aspects are extremely powerful and useful in the context of testing. Here we are using it to ensure a safe and consistent GUI test environment but it's applications reach into other areas as well. FVT testing could greatly benefit from the use of aspects. Simply use the after directive on a pointcut for all the test methods and add a prompt so the test runner can verify whether or not the case passed or failed and log the result. Instead of hacking the ends of your test methods, define an aspect that can provide this functionality external to your test code.

Here is what the the Safety aspect looks like:

package test.helpers; 

public aspect Safety {
  pointcut safeStart():
    call(public * test.helpers.*Helper.* (..));

  before(): safeStart() {
    SimpleCase.waitForJobs();
  }	
}

Note: Notice that this expression only applies the safety advice to classes ending in Helper located within the test.helpers package. Conform to this convention in order for the aspect to work or add an additional pointcut to apply the advice based on another expression.

Howto

dependencies

creating a test plugin

Retrieved from "http://abbot.sourceforge.net/wiki/index.php/AspectJ-based_framework_for_SWT"

This page has been accessed 1655 times. This page was last modified 02:27, 6 Feb 2006. Content is available under Attribution-ShareAlike.


[Main Page]
Main Page
Recent changes
Random page
Current events

Edit this page
Discuss this page
Page history
What links here
Related changes

Special pages
Bug reports