How can I run my tests with parameters?

The development of parameterized tests or theories involves maintaining sets of data. Data can be maintained inside of the test, externally in a data source, or both internally and externally. We will explain these approaches and the reasons why to use each in the section below.

Maintaining data internally is uses public static functions to return values set within the class. Here is an example.

[Parameters]
public static function returnSomeData():Array {
            return [[1], [2], [3]];
    }

Writing a parameterized test that uses small data sets, is a good example of a situation where it is best to maintain test data internally. In this case a simple change to the data, a change to an element in an array for example, is a trivial task. Another example of a situation in which this approach is best used is when a specific set of static data must be tested every time a test is run. One benefit of maintaining data internally is that it eliminates the overhead associated to creating custom external dependency loaders.

The two parameterized test styles under which we have organized the walkthrough are JUnit style and TestNG style. JUnit is a better style for cases where the same data is used from test method to test method. TestNG style is used for test cases in which the methods are more ad-hoc, and share data less consistently.

JUnit Style

[RunWith("org.flexunit.runners.Parameterized")]
public class TestParameterized {
    private var foo:Parameterized;

    [Parameters]
    public static function data1():Array {
        return [ [ 0, 0 ], [ 1, 2 ], [ 2, 4 ] ];
    }

    [Test]
    public function doubleTest():void {
        Assert.assertEquals(_expected, _input*2);
    }

    private var _input:int;
    private var _expected:int;

    public function TestParameterized( param1:int, param2:int ) {
         _input = param1;
         _expected = param2;
    }   
}

Let's start from the top, [RunWith("org.flexunit.runners.Parameterized")] is needed to declare the runner for FlexUnit. If this is the first time that this runner is being invoked then you must declare a variable of type Parameterized as on line 3.
Specifying [Parameters] is what will be passed into the constructor.

The constructor is the key to the JUnit style of parameterized testing, which is used primarily for cases where all the test methods require the same data parameters.

TestNG Style

[RunWith("org.flexunit.runners.Parameterized")]
public class TestParameterized {
    private var foo:Parameterized;

    public static function dataTwo():Array {
        return [ [ 5, 10 ], [ 6, 12 ], [ 7, 14 ] ];
    }

    public static function dataThree():Array {
        return [ [ 0, 0 ], [ 1, 3 ], [ 2, 6 ] ];
    }

    [Test(dataProvider="dataTwo")]
    public function timesTwoTest( value:int, required:int ):void {
        Assert.assertEquals( 2*value, required );
    }

    [Test(dataProvider="dataThree")]
    public function timesThreeTest( value:int, required:int ):void {
            Assert.assertEquals( 3*value, required );
    }

}

The testNG style allows for data to be used on a method by method basis. As you can see, each tests takes it own parameters using the [Test(dataProvider="collectionName")] metadata.

Combined Style

[RunWith("org.flexunit.runners.Parameterized")]
public class TestParameterized {
    private var foo:Parameterized;

    [Parameters]
    public static function data1():Array {
        return [ [ 0, 0 ], [ 1, 2 ], [ 2, 4 ] ];
    }


    public static function dataTwo():Array {
        return [ [ 5, 10 ], [ 6, 12 ], [ 7, 14 ] ];
    }

    public static function dataThree():Array {
        return [ [ 0, 0 ], [ 1, 3 ], [ 2, 6 ] ];
    }

    [Test(dataProvider="dataTwo")]
    public function timesTwoTest( value:int, required:int ):void {
        Assert.assertEquals( 2*value, required );
    }

    [Test(dataProvider="dataThree")]
    public function timesThreeTest( value:int, required:int ):void {
            Assert.assertEquals( 3*value, required );
    }

    [Test]
    public function doubleTest():void {
        Assert.assertEquals(_expected, _input*2);
    }

    private var _input:int;
    private var _expected:int;

    public function TestParameterized( param1:int, param2:int ) {
         _input = param1;
         _expected = param2;
    }
}

This last test case combines the TestNG and JUnit styles, using the constructor and its corrresponding parameters for any test merely marked [Test] and a specific array for any test marked with [Test(dataProvider="collectionName")] metadata.