There are two styles of writing parameterized unit tests in FlexUnit, TestNG and JUint style. TestNG style works very well with ad-hoc type test classes that do not share similar data sets between tests. JUnit Style, on the other hand, is best used for test classes that do share similar data sets between tests

TestNG Style

In the example below we have a test class, written in TestNG style, which consists of a test and a data provider. The test takes two parameters, name and salary, supplied by the tests data provider. When the test class is executed, the test is run for each data set in the data provider. Writing this small ad-hoc test in TestNG is best as it eliminates the over head of maintaining test data.

package flexUnitTests
{
     import org.flexunit.runners.Parameterized;
     
     [RunWith("org.flexunit.runners.Parameterized")]
     public class MyTestNGTest
     {         
          
          private var foo:Parameterized;
          
          public static var testDataA:Array = [   ["Name 1", 50000], 
                                   ["Name 2", 100000], 
                                   ["Name 3", 200000]];
          
          [Test(dataProvider="testDataA")]
          public function testA(name:String, salary:int):void{
               // test name and salay   
          }
     }
}

By adding two more tests and data providers we get the example seen below. All three tests, in this example, take as arguments some combination of a name, salary, and address. Because each test takes a slightly different set of arguments, each test needs a specific data provider to run. In other words, even though the data used for these test are similar, we need to maintain three separate data providers. This example would be best written in the JUnit style.

package flexUnitTests
{
     import org.flexunit.runners.Parameterized;
     
     [RunWith("org.flexunit.runners.Parameterized")]
     public class MyTestNGTest
     {         
          
          private var foo:Parameterized;
          
          public static var testDataC:Array = [   ["Name 1", 50000, "Address 1"], 
                                   ["Name 2", 100000, "Address 2"], 
                                   ["Name 3", 200000, "Address 3"]];
          
          public static var testDataB:Array = [   ["Name 1", "Address 1"], 
                                   ["Name 2", "Address 2"], 
                                   ["Name 3", "Address 3"]];
          
          public static var testDataA:Array = [   ["Name 1", 50000], 
                                   ["Name 2", 100000], 
                                   ["Name 3", 200000]];
          
          [Test(dataProvider="testDataC")]
          public function testC(name:String, salary:int, address:String):void{
               // test name, salary, and address
          }
          
          [Test(dataProvider="testDataB")]
          public function testB(name:String, address:String):void{
               // test name and address
          }
          
          [Test(dataProvider="testDataA")]
          public function testA(name:String, salary:int):void{
               // test name and salay   
          }
     }
}

JUnit Style

In this example we have a test class, written in JUnit style, with a constructor, unit test, and array of parameters. When executed new instances of MyJunitTest are created for each data set in the testData Array. Each time a new instance is created, the constructor is called and the parameters passed in are stored as part of the instance. After an instance is created, each test is executed using the data stored by the constructor. Because of the overhead associated with writing a JUnit Style test, this particular example would be best written in TestNG style.

package flexUnitTests
{
     import org.flexunit.runners.Parameterized;

     [RunWith("org.flexunit.runners.Parameterized")]
     public class MyJunitTest
     {         
          private var foo:Parameterized;
          
          [Parameters]
          public static var testData:Array = [    ["Name 1", "Address 1"], 
                                   ["Name 2", "Address 2"], 
                                   ["Name 3", "Address 3"]];
          
          private var name:String; 
          private var address:String;
          
          [Test]
          public function myTestA():void{
               // Test name and address
          }
          
          public function MyJunitTest(name:String, address:String){
               this.name = name;
               this.address = address;
          }
     }
}

We add two additional classes and one additional field to our dataset in the example below. Instead of creating a new data provider to use the new salary field for each test, we can add the field to our existing data set. This will allow the tests to use any combination of data needed. Writing this example in JUnit style is best, as it cuts down on the effort to maintain test data.

package flexUnitTests
{
     import org.flexunit.runners.Parameterized;

     [RunWith("org.flexunit.runners.Parameterized")]
     public class MyJunitTest
     {         
          private var foo:Parameterized;
          
          [Parameters]
          public static var testData:Array = [    ["Name 1", 50000, "Address 1"], 
                                   ["Name 2", 100000, "Address 2"], 
                                   ["Name 3", 200000, "Address 3"]];
          
          private var name:String; 
          private var salary:int;
          private var address:String;
          
          [Test]
          public function myTestC():void{
               // Test name, address and salary
          }
          
          [Test]
          public function myTestB():void{
               // Test name and salary
          }
          
          [Test]
          public function myTestA():void{
               // Test name and address
          }
          
          public function MyJunitTest(name:String, salary:int, address:String){
               this.name = name;
               this.salary = salary;
               this.address = address;
          }
     }
}
  • No labels