3

I am trying to run a class with multiple tests under two different conditions. Basically I have a bunch of tests related to a search. I am adding new functionality of a new search strategy, and in the meantime want to run the already written tests under both configurations. As we have multiple classes each with multiple tests I want to streamline this process as much as possible. Ideally it'd be great to do the setup in a @BeforeClass with a data provider so that all tests in the class are basically run twice under the different configurations, but doesn't look like this is possible.

Right now I have:

public class SearchTest1 {
    @Test(dataProvider = "SearchType")
    public void test1(SearchType searchType) {
        setSearchType(searchType);
        //Do the test1 logic
    }

    @Test(dataProvider = "SearchType")
    public void test2(SearchType searchType) {
        setSearchType(searchType);
        //Do the test2 logic
    }

    @DataProvider(name = "SearchType")
    public Object[][] createData() {
        return new Object[][]{
            new Object[] {SearchType.scheme1, SearchType.scheme2}
        }
    }
}

Is there a better way to do this?

Clayton
  • 325
  • 5
  • 12
  • 1
    This looks like a pretty good way for me. Except I'd move the data provider in its own class, so everyone can reference the same one. – biziclop Sep 10 '14 at 16:20
  • 1
    That's actually how it's arranged. I wrote it this way to make it easier to read here. I should mention that there are ~20 classes with a total of 268 tests. I'd like to avoid writing these lines in all 268 of these locations. – Clayton Sep 10 '14 at 16:31

2 Answers2

2

If you want to avoid having to annotate each and every method with the data provider, you can use a Factory instead.

public class SearchTest1 {
    private final SearchType searchType;

    public SearchTest1( SearchType searchType ) {
       this.searchType = searchType;
    }

    @Test
    public void test2() {
        //Do the test2 logic
    }
    ...
}

And your factory class will be:

public class SearchTestFactory {
   @Factory
   public Object [] createInstances() {
      return new Object[] { new SeartchTest1( SearchType.ONE ), new SearchTest1( SearchType.TWO ) };
   }
}

See more on this here.

Then you can either have one factory that enumerates every test class or a separate factory for each, the first one is obviously less flexible, the second one means slightly more code.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • So this really means making a constructor for each of these classes and pass in the type. That works I think. Also I found this [http://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection] which points to a way to enumerate all the classes in this package to keep the amount of code minimal. – Clayton Sep 10 '14 at 18:00
  • Yes, that's a nice addition, although I'd probably combine the package scanning with the `MethodAnnotationsScanner` scanner from the Reflections library to return only classes that contain methods annotated with `@Test`. – biziclop Sep 10 '14 at 18:12
  • But that will return a set of methods. Would that mean going through each method and adding their class to the list to instantiate? Or is there a way to filter by that with reflections? – Clayton Sep 10 '14 at 18:35
  • It's been a long time since I used the Reflections library so I can't really answer whether it can do that, but manually building up a set of classes from the methods doesn't sound too complicated either. – biziclop Sep 10 '14 at 18:48
  • 1
    That may not work if using PowerMock; see https://github.com/powermock/powermock/issues/925 – Pr0methean Jul 26 '18 at 21:29
0

You can use parameters in @BeforeClass. Just use (with some cleanup)

context.getCurrentXmlTest().getParameters()

      @SuppressWarnings("deprecation")
      @BeforeClass
      public void setUp(ITestContext context) {
          System.out.println(context.getCurrentXmlTest().getAllParameters());
      }
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
Ben Herron
  • 13
  • 5