Saturday, 22 November 2008

FluxUnit-ing Flex programming

In last week's blog, I talked about a number of different testing frameworks for doing test-driven development (TDD) in Flex. This week, I want to continuing the investigation of FluxUnit and how it can be used to do behaviour-driven development (BDD) type scenarios specifications.

In behaviour-driven development, they talk of writing stories and scenarios. The story describes the stakeholder, the feature wanted, and the benefits. The scenarios provide specific examples of the stories. In general terms, a scenario might be written in the form:
Scenario:

   Given [pre-condition]]
When I [action]
Then I expect [post-condition]

For any scenario, there may be more than one given, when, and then combination. For any given, there might be multiple when and then combinations.

Translating this to a testing tool means that I want some method of ensuring that the given pre-condition is created before executing the when action. Once the action is completed, there needs to be a way of testing that the post condition applies. Finally, there is a need to clean up after to ensure that there is nothing hanging around from this test that might interfere with the next test.

For a testing framework like FlexUnit, JUnit, or NUnit, The setup method provides a way of setting up the precondition so that it can be reused in a number of tests. The test method has to perform the when action and the testing of the post-conditions. The teardown method provides a clean up mechanism. Of course, you can be lazy and put everything in the test method but that limits the reuse of the pre-condition set up logic.

A first look at FlexUnit and its describe, before, it, and after functions and you wonder how can this match the BDD structure. My approach isn't the only method but it does provide a clean structure and the output from the tests reads like a BDD specification. Of course, I could change or extend FluxUnit's code to give me the labels that I would prefer but my goal isn't to write a new tool. I simply want to use what is already available.

describe('Verify the operation of clone and equals methods', function():void {
describe('Given a period', function():void {
var basePeriod : CallRatePeriod;
before(function():void {
basePeriod = new CallRatePeriod(4, 7, 10, 48, "WeekEnd");
});
describe('When cloned', function(): void {
var clonedPeriod : CallRatePeriod;
before(function():void {
clonedPeriod = basePeriod.clone();
});
it("should find the two periods are equal", function():void {
expect(basePeriod.startDay).to(equal(),clonedPeriod.startDay);
expect(basePeriod.equals(clonedPeriod)).to(be_true());
});
});
});
});

Note: I have left out the code that goes around this that sets up the FluxUnit environment. The first describe simply acts as a description of the scenario. It encloses all the Given, when, and then combinations that need to be satisfied. The first nested describe states the precondition (the Given). The before is required so that this logic is executed in the right sequence. They aren't essential but in the way that FluxUnit works, any code outside the call to the before method is executed as FluxUnit builds the execution sequence while the before code is executed once the build is complete. This can leave things undefined or containing null values. Using the before method is preferred. The describe nested within the given describe provides the when action. Again the actual action should be placed in a before call. Finally, the it call defines the post-condition tests.

The output from FluxUnit looks like:

The test entered in each of the describes and the it form the basis of the output. In this case giving a clear statement of the scenario, the pre-condition, the action, and the expected post-condition.

If I had used multiple when describe methods then I may have needed to introduce an after method. It wasn't necessary in this case. Multiple it method calls are also possible but you need to decide whether you want to report each post-condition separately.

If I was to enhance FluxUnit, I would change the describes so that the methods that I was calling were scenario, give, when, and then. This would make it clearer exactly what I was trying to do. The other issues that I have with the way that the code is executed are more than likely the result of using Flex rather than a result of the author's design.

The only reason that I will not be using FluxUnit on my current project is that I need a testing framework that will work in a Maven build context. Building the test program would work but I am not sure that it produces the required output so that the available Maven plugins can determine whether the tests all passed. This is on the list for further investigation.

No comments: