When using JUnit's @Parameterized, can I have some tests still run only once [duplicate]
I use @Parameterized
in many cases to run tests on a number of permutations. This works very well and keeps the test-code itself simple and clean.
However sometimes I would like to have some of the test-methods still run only once as they do not make use of the parameters, is there a way with JUnit to mark the test-method as "singleton" or "run-once"?
Note: This does not concern running single tests in Eclipse, I know how to do that :)
You could structure your test with the Enclosed runner.
@RunWith(Enclosed.class)
public class TestClass {
@RunWith(Parameterized.class)
public static class TheParameterizedPart {
@Parameters
public static Object[][] data() {
...
}
@Test
public void someTest() {
...
}
@Test
public void anotherTest() {
...
}
}
public static class NotParameterizedPart {
@Test
public void someTest() {
...
}
}
}
You can associate any number of test classes to run together using a suite. This way all the tests are run when you test your class and you can mix different test runners.
- Create a test suite associated with the class you are testing
- Add a reference to the parameterized test class
-
Add the other class(es) containing non parameterized tests.
import org.junit.runners.Suite; import org.junit.runner.RunWith; @RunWith(Suite.class) @Suite.SuiteClasses({ParameterizedTestClass.class, UnitTests.class, MoreUnitTests.class}) public class SutTestSuite{ //Empty... }
there is a number of junit plugins that give you some more features/power regarding parameterized tests. check zohhak, junit-parames and junit-dataprovider. they allow you to mix parametrized and simple junit tests
Before I knew about "@RunWith(Enclosed.class)" approach, I used the following (similar) solution, with inner classes extending outer class. I keep using this structure because I like that the tests are in same place and share some properties and methods and things seems clearer to me. Then, using Eclipse, in my run configuration, I choose that option "Run all tests in the selected project, package or source folder" and all these tests will be performed with just a click.
public class TestBooksDAO {
private static BooksDAO dao;
@Parameter(0)
public String title;
@Parameter(1)
public String author;
@Before
public void init() {
dao = BooksDAO.getInstancia();
}
/** Tests that run only once. */
public static class SingleTests extends TestBooksDAO {
@Test(timeout=10000)
public void testGetAll() {
List<Book> books = dao.getBooks();
assertNotNull(books);
assertTrue(books.size()>0);
}
@Test(timeout=10000)
public void testGetNone() {
List<Book> books = dao.getBooks(null);
assertNull(books);
}
}
/** Tests that run for each set of parameters. */
@RunWith(Parameterized.class)
public static class ParameterizedTests1 extends TestBooksDAO {
@Parameters(name = "{index}: author=\"{2}\"; title=\"{0}\";")
public static Collection<Object[]> values() {
return Arrays.asList(new Object[][] {
{"title1", ""},
{"title2", ""},
{"title3", ""},
{"title4", "author1"},
{"title5", "author2"},
});
}
@Test(timeout=10000)
public void testGetOneBook() {
Book book = dao.getBook(author, title);
assertNotNull(book);
}
}
/** Other parameters for different tests. */
@RunWith(Parameterized.class)
public static class ParameterizedTests2 extends TestBooksDAO {
@Parameters(name = "{index}: author=\"{2}\";")
public static Collection<Object[]> values() {
return Arrays.asList(new Object[][] {
{"", "author1"},
{"", "author2"},
{"", "author3"},
});
}
@Test(timeout=10000)
public void testGetBookList() {
List<Book> books = dao.getBookByAuthor(author);
assertNotNull(books);
assertTrue(books.size()>0);
}
}
}