16

我需要对每个套件进行一些初始化(启动网络服务器)。它工作正常,除了当我在 eclipse 中运行我的项目中的所有测试时,我的测试运行了两次。我的测试套件看起来有点像这样:

@RunWith(Suite.class)
@Suite.SuiteClasses({
   SubtestOne.class,
   SubtestTwo.class
})
public class TestSuite
{
   [...]
}

public class SubtestOne
{
   @Test public void testOne() { [...] }
}

public class SubtestTwo
{
   @Test public void testTwo() { [...] }
}

当我在 eclipse 中运行项目中的所有测试时,这会导致 junit 插件像这样运行测试两次:

  • 子测试一
  • 子测试二
  • 测试套件
    • 子测试一
    • 子测试二

是否可以让“运行项目中的所有测试”不运行子测试两次?我希望我的子测试只作为套件的一部分运行。

4

5 回答 5

4

不,测试类将始终直接启动,然后通过套件中的“链接”启动。这正如预期的那样。

一种解决方法可能是在运行配置中设置为仅从包含您的套件的包中运行测试。打开运行配置并选择Run all tests in the selected project, package or source folder然后单击Search...并选择包。

于 2012-06-07T12:29:04.410 回答
2

你首先需要套房吗?根据您单击“全部运行”(类、包或 src/test/java)的时间,将执行所有底层测试。那么拥有套房有什么意义呢?

于 2015-07-01T18:46:25.190 回答
2

我意识到这在 5 年前就已经被问过了,但是由于很多人对这个问题投了赞成票,我认为我仍然会提出解决方案。如果您只想要解决方案,请直接跳到最后;如果您也想理解它,请阅读全文;-)

首先,确实可以确保特定的 JUnit 测试类只在测试套件内运行。此外,您是否想在 Eclipse(如此处所问)或任何其他工具或环境中运行该测试套件也无关紧要;这在很大程度上是一个纯粹的 JUnit 问题。

在我勾勒出解决方案之前,重新审视一下这里的确切问题可能是个好主意。所有 JUnit 测试都需要是可见的和可实例化的,以便 JUnit 框架及其各种运行程序能够获取。这也适用于测试套件和作为测试套件一部分的各个测试。因此,如果 JUnit 选择了测试套件,它也会选择单独的测试,并且套件中的所有测试都将执行两次,一次单独执行,一次作为套件的一部分执行。

所以,如果你愿意的话,诀窍是防止 JUnit 拾取单个测试,同时仍然能够将它们作为套件的一部分进行实例化和执行。

想到的一件事是使测试类成为嵌套在测试套件中的静态内部类。但是,嵌套类仍然需要是公共的(否则它们也不能在套件中运行),如果它们是公共类,它们也会被单独拾取,尽管它们嵌套在套件的公共类中。不过,JUnit 不会尝试运行不可见的测试类。因此,将测试类嵌套在非公共类中可能足以隐藏它们,但我们不能将套件类设为非公共类,因为 JUnit 不会执行它。然而,我们可以做的是将各个测试嵌套在另一个嵌套在测试套件中的非公共类中,这导致我们解决了这个难题:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({AllTests.InSuiteOnly.Test1.class, AllTests.InSuiteOnly.Test2.class})
public class AllTests
{
    static class InSuiteOnly
    {
        public static class Test1
        {
            @Test
            public void test1()
            {
                //...
            }
        }

        public static class Test2
        {
            @Test
            public void test2()
            {
                //...
            }
        }
    }
}

很多人可能会反对现在需要在单个源文件中进行的所有测试。如果我想维护单独的 JUnit 测试类,这些测试类不会自行执行但仍会在测试套件中执行,该怎么办?一个简单的解决方案是使各个测试类抽象(公共/非公共无关紧要),以便 JUnit 不会执行它们,并且在测试套件中,我们只需使用原始抽象测试类的具体子类:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({AllTests.InSuiteOnly.SuiteTest1.class, AllTests.InSuiteOnly.SuiteTest2.class})
public class AllTests
{
    static class InSuiteOnly
    {
        public static class SuiteTest1 extends Test1 {}
        public static class SuiteTest2 extends Test2 {}
    }
}

abstract class Test1
{
    @Test
    public void test1()
    {
        //...
    }
}

abstract class Test2
{
    @Test
    public void test2()
    {
        //...
    }
}

此方案适用于 Maven、Eclipse 和所有其他直接利用 JUnit 运行器或实现自己的运行器的环境,这些运行器密切遵循 JUnit 的原始行为和语义。

于 2017-07-26T07:51:36.217 回答
1

我有一个想法给你。实际上,您不想将这些测试用例作为独立的测试用例运行。您可以执行以下操作。

用注解标记测试用例@RunWith(DoNothingRunner.class)

实现 DoNothingRunner 如下:

public class DoNothingRunner extends Runner {
    public Description getDescription() {
              return "do nothing";
        }
    public void run(RunNotifier notifier) {
            // indeed do nothing
        }
}

我没有亲自尝试过,但我希望这会奏效。

于 2012-06-07T12:35:58.260 回答
1

有一个解决方案,它有点棘手,但它可以轻松解决您的问题:创建一个套件类,并将您的所有套件类包含在其中。然后你可以使用这个套件类来运行你所有的测试。

@RunWith(Suite.class)
@Suite.SuiteClasses({
    AXXSuite.class,
    BXXSuite.class,
    CXXSuite.class
})
public class AllSuites {    

}
于 2018-12-04T06:56:24.743 回答