【问题标题】:Can I avoid running junit tests twice in eclipse when using a TestSuite?使用TestSuite时,我可以避免在eclipse中运行两次junit测试吗?
【发布时间】:2012-06-11 11:59:56
【问题描述】:

我需要对每个套件进行一些初始化(启动网络服务器)。它工作正常,除了当我在 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 插件像这样运行测试两次:

  • SubtestOne
  • 子测试二
  • 测试套件
    • SubtestOne
    • 子测试二

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

【问题讨论】:

  • 能否提供 SubTestOne 和 SubTestTwo 的测试夹具?
  • 你有没有办法将TestSuite设置为默认运行目标?

标签: java eclipse junit junit4


【解决方案1】:

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

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

【讨论】:

  • 当我在项目上按 alt-shift-x,t 时,这个编辑的运行配置似乎没有启动? (这是我在其他项目中所做的,所以请继续偶然做!)
  • 通过eclipse也可以直接右键包,选择'run as-> JUnit Test',只运行那个包的内容。
【解决方案2】:

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

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

如下实现DoNothingRunner:

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

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

【讨论】:

  • 我做了同样的事情然后它甚至停止运行一次
【解决方案3】:

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

【讨论】:

  • 引用问题“我需要对每个套件进行一些初始化(启动网络服务器)”
  • 您也许可以使用 Maven 预集成测试阶段来执行该初始化:虽然这可能不适用于 Eclipse。对于 Eclipse,您可以定义一个测试运行配置,在其中您指示仅运行您的套件类。
【解决方案4】:

我意识到这个问题在 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 的原始行为和语义。

【讨论】:

  • 这个技巧确实有效,虽然它有点冗长。可惜默认的 JUnit 测试套件设计如此糟糕。
  • 是的,非常 horriblehacky 解决方案 :(
【解决方案5】:

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

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

}

【讨论】:

    猜你喜欢
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 2012-02-06
    • 1970-01-01
    相关资源
    最近更新 更多