When using JUnit's @Parameterized, can I have some tests still run only once

JavaJunitJunit4Parameterized

Java Problem Overview


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 :)

Java Solutions


Solution 1 - Java

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() {
            ...
        }
    }
}

Solution 2 - Java

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.

  1. Create a test suite associated with the class you are testing

  2. Add a reference to the parameterized test class

  3. 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...
    }
    

Solution 3 - Java

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

Solution 4 - Java

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);
		}
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncenticView Question on Stackoverflow
Solution 1 - JavaStefan BirknerView Answer on Stackoverflow
Solution 2 - JavadaverView Answer on Stackoverflow
Solution 3 - JavapiotrekView Answer on Stackoverflow
Solution 4 - JavaPFROLIMView Answer on Stackoverflow