当使用JUnit的@Parameterized时,我是否可以让一些测试仅运行一次?

58

我在许多情况下使用@Parameterized来运行一些测试用例,这很有效并且可以使测试代码本身变得简单和清晰。

但是有时候我仍然希望有些测试方法只运行一次,因为它们没有使用参数,是否有一种方法可以在JUnit中将测试方法标记为“单例”或“只运行一次”?

注:这不涉及在Eclipse中运行单个测试的问题,我知道如何做到这一点 :)


4
看起来那些测试不应该与参数化测试放在同一个测试套件中。 - Makoto
4
是的,那是我想到的唯一解决方案,但我真的很喜欢将“相关”的测试放在一个套件中,例如,将一个类的所有测试放在一个测试类中... - centic
4个回答

118

您可以使用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() {
            ...
        }
    }
}

不错!不知道Enclosed。谢谢! - troig

14

您可以使用测试套件将任意数量的测试类关联在一起以一起运行。这样当您测试您的类时,所有测试都会运行,并且您可以混合不同的测试运行器。

  1. 创建与您正在测试的类相关联的测试套件
  2. 添加对参数化测试类的引用
  3. 添加包含非参数化测试的其他类。

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

6
是的,这可能是我最终得到的结果,我曾希望单个测试方法有类似注释的东西... - centic

1

有一些JUnit插件可以为参数化测试提供更多功能/能力。请查看zohhak、junit-parames和junit-dataprovider。它们允许您混合使用参数化测试和简单的JUnit测试。


谢谢您的建议,这些看起来很有趣! - centic

1
在我了解"@RunWith(Enclosed.class)"方法之前,我使用了类似的解决方案,使用内部类扩展外部类。我继续使用这个结构,因为我喜欢测试在同一位置并共享某些属性和方法,对我来说事情似乎更清晰。然后,在Eclipse中,我选择运行配置选项"运行所选项目、包或源文件夹中的所有测试",只需点击即可执行所有这些测试。
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);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接