2011-08-26 28 views
10

我想在備份測試夾具之前備份我的應用程序的數據庫。由於Android的限制,我不得不使用Junit3,並且我想實現@BeforeClass和@AfterClass的等效行爲。如何在Junit3中獲得@BeforeClass和@AfterClass等效項?

更新:現在有一個工具(Junit4Android)在Android上獲得對 Junit4的支持。這是一個混亂,但應該工作。

爲了實現@BeforeClass等同,我一直在使用一個靜態變量,像這樣在第一次運行時初始化它,但我需要能夠運行所有測試後恢復數據庫。我無法想象的,當最後的測試已經運行檢測的方式

public class MyTest extends ActivityInstrumentationTestCase2<MainActivity> { 
    private static boolean firstRun = true; 

    @Override 
    protected void setUp() { 
     if(firstRun) { 
      firstRun = false; 
      setUpDatabaseFixture(); 
     } 
    } 
    ... 
} 
+0

但在你的情況下測試將視對方,並在某些特定狀態將被期待數據庫意味着它們不是真正的單元測試。你應該是一個模擬數據庫。 –

+1

這些都是驗收測試,而且絕大多數不是單元測試。這些完全集成在平臺上,由Android工具Robotium驅動。 –

+0

另請參見http://stackoverflow.com/questions/3023091/does-junit-3-have-something-analogous-to-beforeclass – Vadzim

回答

8

junit website(因爲我相信這是測試執行的順序沒有保證。):

包裹套件中的setUp和tearDown方法。如果您想運行單個YourTestClass測試用例,則這是針對 的情況。

public static Test suite() { 
    return new TestSetup(new TestSuite(YourTestClass.class)) { 

     protected void setUp() throws Exception { 
      System.out.println(" Global setUp "); 
     } 
     protected void tearDown() throws Exception { 
      System.out.println(" Global tearDown "); 
     } 
    }; 
} 

如果您想爲所有的測試用例 只運行一個安裝和拆卸,使一套房,並添加TestClass中給它,並通過在TestSetup constructor.But套房 對象我想有這並沒有太大的用處 ,並以某種方式違反了JUnit哲學。

+0

請注意TestSetup似乎在'junit.extensions.TestSetup' –

+3

@PeterAjtai和Nicholas ,儘管這可以在其他平臺上工作,Android [不包括支持](http://stackoverflow.com/q/10691737/403455)適用於'junit.extensions.TestSetup'。 –

+0

你在ANdroid上運行這段代碼嗎?你能不能與我分享完整的代碼?我正在努力實施Global setUp/tearDown .. –

1

最近,我也在尋找類似的解決方案。幸運的是,在我的情況下,JVM在最後一次測試運行後退出。所以我可以通過添加JVM關閉掛鉤來實現這一點。

// Restore database after running all tests 
Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     restoreDatabase(); 
    } 
}); 

希望這有助於。

+0

+1好主意。可能需要小心這個,雖然... –

0

我建議避免這種類型的依賴關係,您需要知道測試運行的順序。如果您只需要恢復被setUpDatabaseFixture()取代的真實數據庫,那麼您的解決方案可能來自使用RenamingDelegatingContext。無論如何,如果你不能避免知道最後的測試運行時,您可以使用這樣的事情:

... 

private static final int NUMBER_OF_TESTS = 5; // count your tests here 
private static int sTestsRun = 0; 

... 

protected void tearDown() throws Exception { 
    super.tearDown(); 
    sTestsRun += countTestCases(); 

    if (sTestsRun >= NUMBER_OF_TESTS) { 
     android.util.Log.d("tearDow", "*** Last test run ***"); 
    } 
} 
1

這不是(與數據處理優雅,所以你不必擔心恢復它)testing with mock objects是爲了什麼? Android supports mocking

我問一個問題,因爲我從來沒有嘲笑過Android。


在我的經驗,並從this blog post,當Android的測試製作成一套,並由InstrumentationTestRunner運行 - ActivityInstrumentationTestCase2ActivityTestCase的延伸範圍的InstrumentationTestCase的extendsion - 它們使用android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME按字母順序排列,所以你可以用你的測試名稱中字母低的方法恢復你的DB,例如:

// underscore is low in the alphabet 
public void test___________Restore() { 
    ... 
} 

注:

你必須要注意繼承的測試,因爲他們不會在這個順序運行。解決方案是覆蓋所有繼承的測試,只需從覆蓋中調用super()。這將再一次按字母順序執行。

例子:

// Reusable class w only one time setup and finish. 
// Abstract so it is not run by itself. 
public abstract class Parent extends InstrumentationTestCase { 
    @LargeTest 
    public void test_001_Setup() { ... } 

    @LargeTest 
    public void test_____Finish() { ... } 
} 

/*-----------------------------------------------------------------------------*/ 

// These will run in order shown due to naming. 
// Inherited tests would not run in order shown w/o the use of overrides & supers 
public class Child extends Parent { 
    @LargeTest 
    public void test_001_Setup() { super.test_001_Setup(); } 

    @SmallTest 
    public void test_002_MainViewIsVisible() { ... } 

    ... 

    @LargeTest 
    public void test_____Finish() { super.test_____Finish(); } 
} 
+0

謝謝,但這是驗收測試,而不是單元測試。我已經使用PowerMock + Mockito創建了用於在主機上運行快速單元測試的模擬。 –

+0

@glen - 噢好吧,這很有道理。我認爲Android測試是按字母順序運行的,所以你可以創建一個testZZZZZ()來恢復一切。從http://blogprogramistyandroid.blogspot.com/2011/02/randomizing-order-of-tests.html android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME –

相關問題