android - 连续的 Android Junit 测试不反射(reflect)底层数据库中的真实数据

标签 android database unit-testing junit

附加信息:

澄清一下,被测应用使用 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();
}

最佳答案

看来 ContentProvider 的生命周期与 Application 的生命周期相关,而不是与访问它的 Activity 的生命周期相关。另外,据我所知,ActivityInstrumentationTestCase2 为所有测试创建了一个 Application;每次测试只有 Activity 被销毁并重新启动。这意味着每个测试将共享相同的 ContentProvider。这意味着数据库文件在 ContentProvider 第一次访问时打开,只有在 ActivityInstrumentationTestCase2 中的所有测试方法完成后才关闭。由于数据库文件在测试用例之间保持打开状态,因此即使从底层文件系统中删除文件后也可以访问数据。我的解决方案是单独删除数据库的行,而不是删除整个数据库。

关于android - 连续的 Android Junit 测试不反射(reflect)底层数据库中的真实数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21449529/

相关文章:

java - "No Activity found"错误

android - 线程 "Test worker"java.lang.IllegalStateException : Module with the Main dispatcher had failed to initialize 中的异常

python-2.7 - python - Flask test_client() 没有使用 pytest 的 request.authorization

unit-testing - 单元测试 Google 的 Go API 客户端

java - 如何等待用户在 Marshmallow 中授予权限

android - 在该 View 外单击时 View 消失

android - 无法在 flutter 中运行 stripe_sdk 示例

c# - 在 C# 中的数据库中添加新字段时更新数据集

mysql - 在mysql工作台中正向工程ER图时出现错误1064

sql - 描述表结构