Android testing - start with clean database for every test

mDb.delete(DATABASE_TABLE_NAME, null, null); 

That is indeed the solution/way-to-go...

I changed the first line in my setUp(..) method to this:

cleanUpDatabase(tableList);

And then I added the method cleanUpDatabse(..) liek this:

private void cleanUpDatabase(List<String> dbTables) {
    Log.i(LOG_TAG, "Preparing to clean up database...");
    DatabaseHelper dbHelper = new DatabaseHelper(getInstrumentation().getTargetContext());
    ConnectionSource cs = dbHelper.getConnectionSource();
    SQLiteDatabase db = dbHelper.getWritableDatabase();

    Log.i(LOG_TAG, "Dropping all tables");
    for (String table : dbTables) {
        db.execSQL("DROP TABLE IF EXISTS " + table);
    }

    Log.i(LOG_TAG, "Executing the onCreate(..)");
    dbHelper.onCreate(db, cs);

    Log.i(LOG_TAG, "Verifying the data...");
    for (String table : dbTables) {
        Cursor c = db.query(table, new String[]{"id"}, null, null, null, null, null);
        int count = c.getCount();
        if (count != 1 && (table.equals("project") || table.equals("task"))) {
            dbHelper.close();
            Log.e(LOG_TAG, "We should have 1 record for table " + table + " after cleanup but we found " + count + " record(s)");
            throw new RuntimeException("Error during cleanup of DB, exactly one record should be present for table " + table + " but we found " + count + " record(s)");
        } else if (count != 0 && !(table.equals("project") || table.equals("task"))) {
            dbHelper.close();
            Log.e(LOG_TAG, "We should have 0 records for table " + table + " after cleanup but we found " + count + " record(s)");
            throw new RuntimeException("Error during cleanup of DB, no records should be present for table " + table + " but we found " + count + " record(s)");
        }
    }

    Log.i(LOG_TAG, "The database has been cleaned!");
    dbHelper.close();
}

This piece of code gets executed before every test, which makes all my tests independent from each other.

Caution: In order to retrieve a reference to your DatabaseHelper (your own implementation off course ;) ) you cannot call getActivity() because that will launch your activity (and thus do all your initial DB loading (if any..)


A bit tangential to this problem, but I landed here when I was looking for help. Might be helpful to some folks. If you initialize your database with the RenamingDelegatingContext, it cleans the database between runs.

public class DataManagerTest extends InstrumentationTestCase {

  private DataManager subject;

  @Before
  public void setUp() {
    super.setUp();

    RenamingDelegatingContext newContext = new RenamingDelegatingContext(getInstrumentation().getContext(), "test_");
    subject = new DataManager(newContext);
  }

  // tests...
}

And the associated DataManagerClass.

public class DataManager {

    private SQLiteDatabase mDatabase;
    private SQLiteOpenHelper mHelper;
    private final String mDatabaseName = "table";
    private final int mDatabaseVersion = 1;

    protected DataManager(Context context) {
    this.mContext = context;
    createHelper();
  }

  private void createHelper() {
    mHelper = new SQLiteOpenHelper(mContext, mDatabaseName, null, mDatabaseVersion) {
      @Override
      public void onCreate(SQLiteDatabase sqLiteDatabase) {
        // createTable...
      }

      @Override
      public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        // upgrade table
      }
    };
  }
    ...
}

InstrumentationRegistry → getContext → deleteDatabase

android.support.test.InstrumentationRegistry's getTargetContext and, counterintuitively perhaps, getContext should do the trick:


Synopsis

Use getContext for deleting database (not getTargetContext).

getContext().deleteDatabase(DbHelper.DATABASE_NAME);


Example

public class DbHelperTest {
private DbHelper mDb;

    @Before
    public void setUp() throws Exception {
        getContext().deleteDatabase(DbHelper.DATABASE_NAME);
        mDb = new DbHelper(getTargetContext());
    }

    @After
    public void tearDown() throws Exception {
        mDb.close();
    }

    @Test
    public void onCreate() throws Exception {
        mDb.onCreate(mDb.getWritableDatabase());
    }

    @Test
    public void onUpgrade() throws Exception {
        mDb.onUpgrade(mDb.getWritableDatabase(), 1, 2);
    }

    @Test
    public void dropTable() throws Exception {
        String tableName = "mesa";
        mDb.getReadableDatabase().execSQL("CREATE TABLE "
            + tableName + "(_id INTEGER PRIMARY KEY AUTOINCREMENT)");
        mDb.dropTable(mDb.getWritableDatabase(), tableName);
    }
}

Tags:

Sqlite