使用TestSuite时,我可以避免在eclipse中运行两次junit测试吗?

时间:2012-06-07 12:20:39

标签: java eclipse junit junit4

我需要进行一些套件初始化(启动Web服务器)。它运行正常,除了当我在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
  • SubtestTwo
  • 的TestSuite
    • SubtestOne
    • SubtestTwo

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

5 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

你首先需要套房吗?根据您单击运行all(class,package或src / test / java)的时间,将执行所有基础测试。那么套房的重点是什么?

答案 2 :(得分:1)

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

使用注释@RunWith(DoNothingRunner.class)

标记测试用例

将DoNothingRunner变为如下:

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

我个人没试过,但我希望这会有用。

答案 3 :(得分:1)

我意识到这已经被问过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的原始行为和语义。

答案 4 :(得分:1)

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

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

}