Question

Right now, I have this simple test suite:

@RunWith(Suite.class)
@Suite.SuiteClasses({
    CommentingTest.class,
    SubscriptionsTest.class,
    EditingTest.class,
    BasicOperationsTest.class
})
public class WebTestSuite { }

But now I want to pass parameters to these test classes, to tell them whether or not to test with an admin account, whether or not to test in view mode A or B, etc. I was hoping I could do something like this:

@RunWith(Suite.class)
public class WebTestSuite {
    public WebTestSuite() {
        this.addTest(new CommentingTest(Accounts.ADMIN, ViewMode.A));
        this.addTest(new CommentingTest(Accounts.ADMIN, ViewMode.B));
        this.addTest(new CommentingTest(Accounts.GUEST, ViewMode.B));
        this.addTest(new SubscriptionsTest(Accounts.ADMIN, ViewMode.A));
        this.addTest(new SubscriptionsTest(Accounts.ADMIN, ViewMode.B));
        this.addTest(new SubscriptionsTest(Accounts.GUEST, ViewMode.B));
        this.addTest(new EditingTest(Accounts.ADMIN, ViewMode.A));
        this.addTest(new EditingTest(Accounts.ADMIN, ViewMode.B));
        this.addTest(new EditingTest(Accounts.GUEST, ViewMode.B));
        this.addTest(new BasicOperationsTest(Accounts.ADMIN, ViewMode.A));
        this.addTest(new BasicOperationsTest(Accounts.ADMIN, ViewMode.B));
        this.addTest(new BasicOperationsTest(Accounts.GUEST, ViewMode.B));
    }
}

But I can't figure out how to do something like this. Any ideas? Thanks!

Was it helpful?

Solution

You can't do it the way you listed because the test classes need to have a no-arg constructor.

There are 2 options you can do depending on what the tests are like:

Option 1. Make abstract test classes with subclasses that have the parameters:

Make the abstract test classes with all of your tests then have subclasses provide the variable information. The abstract class can take parameters in the constructors, the subclass no-arg constructor calls super(...) with the appropriate parameters.

public abstract class AbstractCommentingTest{

    private Account account;
    private ViewMode mode;

    public AbstractCommentingTest(Account a, ViewMode v){
       this.account=a;
       this.viewMode = v;
    }


    //Put your tests here using the given account and view
    @Test
    public void foo(){

    }

    @Test
    public void bar(){

    }


}

Then your concrete classes

public class AdminViewACommentingTest extends AbstractCommentingTest{
      //no-arg constructor for JUnit
      public AdminViewACommentingTest(){
          super(Accounts.ADMIN, Viewmode.A);
      }
}

This works but can get out of hand quickly if there are lots of options

Option 2: Use Junit Parameterized tests to have every option combination:

I assume Accounts and ViewMode are enums ? If so you can easily use the values() method to create all possible combinations as part of a Parameterized test set.

@RunWith(Parameterized.class)
public class CommentingTest{

     @Parameters
     public static Collection<Object[]> createData(){
                List<Object[]> data = new ArrayList<Object[]>();

                 for(Accounts account : Accounts.values()){
                    for(ViewMode view : ViewMode.values()){
                         data.put(new Object[]{account, view});
                    }
                  }
                 return data;
    }


    private Account account;
    private ViewMode mode;

    public CommentingTest(Account a, ViewMode v){
       this.account=a;
       this.viewMode = v;
    }

    //Put your tests here using the given account and view
    @Test
    public void foo(){

    }

    @Test
    public void bar(){

    }

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top