Home

GivWenZen Flex

A BDD style acceptance testing framework for flex. Based on the GivWenZen concepts from original GivWenZen by Wes Williams and others.


News

27/06/2013 - New milestone M11 build available. We added integration with FlexMojos 4.x. Please use new test runner template in your build:TestRunnerGWZ-FlexMojos4.vm. From this version FlexMojos 3.x is no longer supported.

23/09/2010 - I uploaded updated TestRunnerGWZ.vm that has a major fix for running GWZ tests with flexunit4 from maven. The issue was fairly complex and I'm working on a patch for the flex mojos to fix that issue.

2/09/2010 - Important - Due to the issues with flex mojos implementation of the FlexUnit4 runner , executing scenarios from maven was unreliable. New milstone fixes the issue but requires some changes to the build configuration.

  1. Add this test runner template to your source base and ...
  2. Configure flex mojos to use it by adding this line to the plugin configuration: <testRunnerTemplate>${project.build.sourceDirectory}/resources/TestRunner.vm</testRunnerTemplate> more details you can find in the flex mojos documentation

The code has been linked against flex mojos 3.5. Please file a bug if you need it to be updated to something newer.

27/08/2010 - New milstone build available. It improves usability by enhancing the stacktraces in FlexUnit4 integration. A stack trace that navigates to the script is now available and works with IntelliJ 9.0.3.

25/08/2010 - New milstone build available that comes with FlexUnit4 integration

Example use of FlexUnit4:

package org.givwenzen.integration.flexunit4
{
import org.givwenzen.LoginStep;
import org.givwenzen.givWenZen;

// Use GWZ runner on your story
[RunWith("org.givwenzen.integration.flexunit4.GWZRunner")]

// a good practice is to name a class after the story and use some kind of suffix or prefix
// I chose Story, you can stick to Test

// The class has to be dynamic to allow generating scenario functions on it later on
public dynamic class LoginToSystemStory
{
    [Embed(source="/stories/logintosystem.story", mimeType="application/octet-stream")]
    public static var criteria:Class;

    {
        // you register steps in a static section of the class
        givWenZen().addStep(LoginStep);
    }

    public function LoginToSystemStory()
    {
        super();
        // you have to use one of the GWZRunner functions that convert scripts into the test functions
        GWZRunner.addValidationScriptFromResource(criteria, this);
    }

}
}

13/08/2010 - I created tutorial demonstrating how to use GivWenZen with UI automation
29/06/2010 - 1.1 - Milestone 1 released. It gives smart hints when step is not recognized due to a spelling or some formatting problem:

Example:

None of the registered domain steps matched the criteria:
'I entered login name 'kris' and pass 'secret''
However we found some that looked alike:
'I enter login name '(.*)' and password '(.*)'' in class org.givwenzen::LoginStep/loginToSystem()

Make sure you:
1) Created a domain step class and registered the domain step class with givWenZen().addStep(...).
2) Added metadata [DomainStep('I entered login name 'kris' and pass 'secret'')] or with another regular expression matching given step to a function.
3) The regular expression actually matches the step.

Also fixes some of the case issues when recognizing steps.


Intro

GivWenZen is supposed to provide ability for executing BDD acceptance validation.

The story acceptance criteria should be first created in a textual form as part of the conversation with a customer.

Here is an example:

given 
    I enter values 2 and 1
when 
    I sum values
then
    the result is 3

To allow validation of such acceptance criteria with GivWenZen one should provide a Domain Steps implementation. In this case CalculatorSteps.

In order for the GivWenZen to recognize the steps in a Domain Steps class each function needs to be annotated with [DomainStep("regular expression")]

public class CalculatorSteps
{
    public function CalculatorSteps()
    {
    }

    [DomainStep("I enter values ([\0-9]*) and ([\0-9]*)")]
    public function enterValues(v1:int, v2:int):void
    {
    }

    [DomainStep("I sum values")]
    public function sum():void
    {
    }

    [DomainStep("the result is ([\0-9]*)")]
    public function verifySum(expected:int):void
    {
    }

}

Please note how regex group matches the argument number in a function.

In the verification function one should use assert of some kind (can be one from your favorite unit testing framework) to ensure the criteria is met. It can be also any kind of exception thrown from the function.

To validate such criteria, all the required Domain Steps need to be registered in the GivWenZen:

givWenZen().addSteps(CalculatorSteps);

Later on you load script somehow and execute it:

var script:String = ....;
givWhenZen().run(script);

That's it.

You may check the integrations section to see how to incorporate it in your builds.

If you use flex unit integration and run it from IntelliJ you should see something like:

example results

Have fun!

Demo

Demo application

Support

For questions and support please join mailing list.


API

Registering the domain steps:

givWhenZen().addStep(SomeDomainStep);
givWhenZen().addSteps(SomeDomainStep, AnotherDomainStep);

Running tests:

givWhenZen().run("given I need 1000 hours to do it right\n" 
                             + "when I start doing it\n" 
                             + "then you can see the results");

Annotating the domain steps:

public class SomeDomainSteps
{
    [DomainStep("I need (\d*) hours to do it right")]
    public function contemplatingTime(time:int):void
    {
       ....
    }
}

Integration

FlexUnit 3

Below is an example of suite that you need to implement in order to run givwenzen tests. If you use IDE flex unit plugin like IntelliJ 9, you should get nice test output in with individual steps listed.

Please note, that IntelliJ does not run suite when running packages. A suite needs to be executed individually.

In this example test scripts are embedded into the unit testing application.

package org.givwenzen.integration.flexunit3
{
import flash.utils.ByteArray;

import org.givwenzen.CalculatorStep;
import org.givwenzen.LoginStep;
import org.givwenzen.givWenZen;

public class TestIntegration extends GivWenZenSuite
{
    [Embed(source="test1.txt", mimeType="application/octet-stream")]
    private static var test1:Class;
    [Embed(source="test2.txt", mimeType="application/octet-stream")]
    private static var test2:Class;

    public static function loadTest(embeddedResource:Class):String
    {
        return ByteArray(new embeddedResource()).toString();
    }

    public function TestIntegration()
    {
        givWenZen().addSteps(LoginStep, CalculatorStep);
        addTestScript(loadTest(test1), "Login To System")
                .addTestScript(loadTest(test2), "Calculator");
    }


    /**
     * Implement this function if you need to execute any type of prerequisite
     * example: calling morefluent integrate() or preparing mock classes 
     * @return BeforeTest instance
     */
    override protected function provideBeforeTest():BeforeTest
    {
        return super.provideBeforeTest();
    }
}
}

Integration with Morefluent

To properly integrate with morefluent one needs to return appropriate BeforeTest implementation from provideBeforeTest().

Example:

import flexunit.framework.TestCase;

import org.givwenzen.integration.flexunit3.BeforeTest;
import org.morefluent.integrations.flexunit3.integrate;

public class IntegrateMoreFluent implements BeforeTest
{

    public function run(testCase:TestCase, testExecutionFunction:Function):void
    {
        integrate(testCase);
        testExecutionFunction();
    }
}

Above will enable morefluent to install asynchronous support on the executed tests.

Later on within the domain steps class one can use morefluent api to effectively delay steps execution till the requested event arrives.

FlexUnit 4

Work in progress.

Tutorial on verification through the UI

A short introduction to usign givwenzen with morefluent and u-input.


License

Uses as3reflect licensed under Apache License 2.0

The MIT License

Copyright (c) 2010 givwenzen-flex contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Updated

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.