2012-06-07 67 views
15

我需要做一些每個套件的初始化(啓動一個web服務器)。它工作正常,但是當我在eclipse中的項目中運行所有測試時,我的測試運行兩次。我的測試套件看起來有點像這樣:使用TestSuite時,能否避免在eclipse中運行兩次junit測試?

@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

是否有可能使「在項目中運行所有測試」不能兩次運行子測試?我希望我的子測試只能作爲套件的一部分運行。

+0

你能否提供SubTestOne&SubTestTwo的測試裝置? –

+0

您是否找到任何將TestSuite設置爲默認運行目標的方法? –

回答

3

不,測試類將始終直接啓動,然後通過套件中的「鏈接」。這是預期的。

一個解決方法可能在運行配置中設置爲僅從包含套件的包運行測試。打開運行配置並選擇Run all tests in the selected project, package or source folder,然後單擊Search...並選擇包。

+0

當我按下alt-shift-x,t在項目上時,編輯後的運行配置似乎不會啓動? (這是我在我的其他項目上所做的事情,所以請不要這麼做!) – lexicalscope

+0

通過eclipse,您還可以直接右鍵單擊包並選擇'run as-> JUnit Test'以僅運行該包的內容。 – user2316667

1

我有一個想法給你。實際上,您不希望將這些測試用例作爲獨立測試用例運行。您可以執行以下操作。

標記測試用例註釋@RunWith(DoNothingRunner.class)

Implment DoNothingRunner如下:

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

我沒有親自試過,但我希望這會工作。

+1

我做了同樣的事情,它甚至停止運行一次 – Sanjiv

+0

我試過了,它繼續運行兩次。 – zelinka

2

你首先需要套房嗎?取決於何時單擊運行所有(類,包或src/test/java),所有基礎測試都將被執行。那麼擁有套房有什麼意義?

+0

引用問題「我需要做一些每個套件的初始化(啓動一個web服務器)」 – lexicalscope

+0

你也許可以使用Maven預集成測試階段來執行初始化:儘管Eclipse可能不太適用。對於Eclipse,您可以定義一個測試運行配置,其中您指示只運行套件類。 –

0

我意識到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測試類,但它們本身不能執行但仍然在測試套件中執行?一個簡單的解決方案是使單個測試類抽象化(public/non-public無關緊要),以便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原始行爲和語義的環境。

相關問題