我想在用测试夹具替换它之前备份我的应用程序的数据库。由于Android限制,我被迫使用Junit3,我想实现@BeforeClass和@AfterClass的等效行为。
更新:现在有一个工具(Junit4Android)可以获得支持 Android上的Junit4。这有点像kludge但应该有用。
为了实现@BeforeClass等价物,我一直在使用静态变量并在第一次运行期间初始化它,但我需要能够在运行所有测试后恢复数据库。我想不出有什么方法可以检测上次测试的运行时间(因为我认为不能保证测试执行的顺序。)
public class MyTest extends ActivityInstrumentationTestCase2<MainActivity> {
private static boolean firstRun = true;
@Override
protected void setUp() {
if(firstRun) {
firstRun = false;
setUpDatabaseFixture();
}
}
...
}
答案 0 :(得分:8)
在套件中包装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 ");
}
};
}
如果您只想为所有人运行一个setUp和tearDown testcase,创建一个套件并将testClass添加到它并传递套件 TestSetup构造函数中的对象。但我认为没有太多用法 为此,它在某种程度上违反了JUnit哲学。
答案 1 :(得分:1)
最近,我也在寻找类似的解决方案。幸运的是,在我的情况下,在最后一次测试运行后JVM退出。所以我能够通过添加一个JVM关闭钩子来实现这一点。
// Restore database after running all tests
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
restoreDatabase();
}
});
希望这会有所帮助。
答案 2 :(得分:1)
这不是(优雅地处理数据,所以你不必担心恢复它) testing with mock objects 是什么意思? Android supports mocking 。
我问一个问题,因为我从未嘲笑Android。
根据我的经验,以及this blog post,当Android测试进入套件并由 InstrumentationTestRunner - ActivityInstrumentationTestCase2 <运行时/ strong>是 ActivityTestCase 的扩展,它是 InstrumentationTestCase 的扩展 - 它们是使用android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME
按字母顺序排序的,所以你可以使用一种方法恢复数据库,该方法是测试名称中字母表中的低位,例如:
// 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(); }
}
答案 3 :(得分: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 ***");
}
}