其他信息:
为了澄清,被测试的应用程序使用ContentProvider
来访问数据库。
修改
如果有人愿意并且能够帮我调试这个。完整项目可用here。在issue107-contentprovider
分支BaseballCardListAddCardsTest
。
问题:
当我分别运行两个Android JUnit测试时,它们通过就好了。但是,当我一起运行它们时,第一个通过而第二个通过。问题似乎是第一次测试运行会向底层数据库添加一行。 tearDown()
正确删除了数据库,但第二个测试仍然以ListView
中显示的脏数据开始,尽管数据库不包含额外的行。 (我使用adb shell
确认了这一点。)有没有人有任何想法如何解决这个问题?
可以找到正在测试的Activity类here。
这是我的测试代码:
/**
* Tests for the {@link BaseballCardList} activity when the database contains
* data.
*/
public class BaseballCardListWithDataTest extends
ActivityInstrumentationTestCase2<BaseballCardList> {
/**
* Create instrumented test cases for {@link BaseballCardList}.
*/
public BaseballCardListWithDataTest() {
super(BaseballCardList.class);
}
/**
* Set up test fixture. This consists of an instance of the
* {@link BaseballCardList} activity, its {@link ListView}, and a populated
* database.
*
* @throws Exception
* If an error occurs while chaining to the super class.
*/
@Override
public void setUp() throws Exception {
super.setUp();
this.inst = this.getInstrumentation();
// Create the database and populate table with test data
InputStream cardInputStream = this.inst.getContext().getAssets()
.open(BBCTTestUtil.CARD_DATA);
BaseballCardCsvFileReader cardInput = new BaseballCardCsvFileReader(
cardInputStream, true);
this.allCards = cardInput.getAllBaseballCards();
cardInput.close();
this.dbUtil = new DatabaseUtil(this.inst.getTargetContext());
this.dbUtil.populateTable(this.allCards);
// Start Activity
this.activity = this.getActivity();
this.listView = (ListView) this.activity
.findViewById(android.R.id.list);
this.newCard = new BaseballCard("Code Guru Apps", 1993, 1, 50000, 1,
"Code Guru", "Code Guru Devs", "Catcher");
}
/**
* Tear down the test fixture by calling {@link Activity#finish()} and
* deleting the database.
*
* @throws Exception
* If an error occurs while chaining to the super class.
*/
@Override
public void tearDown() throws Exception {
this.dbUtil.deleteDatabase();
super.tearDown();
}
/**
* Check preconditions which must hold to guarantee the validity of all
* other tests. Assert that the {@link Activity} to test and its
* {@link ListView} are not <code>null</code>, that the {@link ListView}
* contains the expected data, and that the database was created with the
* correct table and populated with the correct data.
*/
public void testPreConditions() {
Assert.assertNotNull(this.activity);
BBCTTestUtil.assertDatabaseCreated(this.inst.getTargetContext());
Assert.assertTrue(this.dbUtil.containsAllBaseballCards(this.allCards));
Assert.assertNotNull(this.listView);
BBCTTestUtil.assertListViewContainsItems(this.inst, this.allCards,
this.listView);
}
/**
* Test that the {@link ListView} is updated when the user adds a new card
* which matches the current filter.
*
* @throws Throwable
* If an error occurs while the portion of the test on the UI
* thread runs.
*/
public void testAddCardMatchingCurrentFilter() throws Throwable {
this.testYearFilter();
Activity cardDetails = BBCTTestUtil.testMenuItem(this.inst,
this.activity, R.id.add_menu, BaseballCardDetails.class);
BBCTTestUtil.addCard(this, cardDetails, this.newCard);
BBCTTestUtil.clickCardDetailsDone(this, cardDetails);
this.expectedCards.add(this.newCard);
BBCTTestUtil.assertListViewContainsItems(this.inst, this.expectedCards,
this.listView);
}
/**
* Test that the {@link ListView} is updated when the user adds a new card
* after an active filter was cleared.
*
* @throws Throwable
* If an error occurs while the portion of the test on the UI
* thread runs.
*/
public void testAddCardAfterClearFilter() throws Throwable {
this.testClearFilter();
Activity cardDetails = BBCTTestUtil.testMenuItem(this.inst,
this.activity, R.id.add_menu, BaseballCardDetails.class);
BBCTTestUtil.addCard(this, cardDetails, this.newCard);
BBCTTestUtil.clickCardDetailsDone(this, cardDetails);
this.allCards.add(this.newCard);
BBCTTestUtil.assertListViewContainsItems(this.inst, this.allCards,
this.listView);
}
private List<BaseballCard> allCards;
private List<BaseballCard> expectedCards;
private Instrumentation inst = null;
private Activity activity = null;
private DatabaseUtil dbUtil = null;
private ListView listView = null;
private BaseballCard newCard = null;
private static final int TIME_OUT = 5 * 1000; // 5 seconds
private static final String TAG = BaseballCardListWithDataTest.class
.getName();
}
答案 0 :(得分:0)
似乎ContentProvider
的生命周期与Application
生命周期的生命周期相关联,而不是Activity
的生命周期。另外,据我所知,ActivityInstrumentationTestCase2
为所有测试创建了一个Application
;只有Activity
被销毁并重新开始每次测试。这意味着每个测试将共享相同的ContentProvider
。这意味着数据库文件在ContentProvider
的第一次访问时打开,并且仅在ActivityInstrumentationTestCase2
中的所有测试方法完成后才关闭。由于数据库文件在测试用例之间保持打开,因此即使从基础文件系统中删除文件,也可以访问数据。我的解决方案是单独删除数据库的行而不是删除整个数据库。