不同的sqlite数据库在android app中进行测试和实际使用
Posted
技术标签:
【中文标题】不同的sqlite数据库在android app中进行测试和实际使用【英文标题】:Different sqlite databases for testing and actual use in android app 【发布时间】:2015-02-26 08:24:03 【问题描述】:免责声明 - 我已使用 GreenDAO ORM 在我的 android 应用程序中创建和管理 sqlite 数据库。
对于我的 android 应用程序,在编写单元测试时,我希望告诉应用程序切换到使用与正常数据库不同的某个数据库,以确保测试不会污染真实的数据库。相应地,我使用了适当的函数来创建新的数据库并像这样切换到它
public class DbTests extends ApplicationTestCase<MyApp>
private static final String TAG = "DbTests";
private MyApp mApplication;
private Context mContext;
public DbTests()
super(MyApp.class);
@Override
protected void setUp() throws Exception
Log.d(TAG, "in setUp");
super.setUp();
createApplication();
mApplication = getApplication();
Log.d(TAG, "setUp done");
@Override
public void tearDown() throws Exception
super.tearDown();
private void setUpFreshInstallNoDataCase(boolean val)
assertNotNull(mApplication);
LocalDataHelpers.setupLocalData(mApplication, InitialConditions.FreshInstallNoData);
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
public void testFreshInstallNoDataCase()
Log.d(TAG, "testFreshInstallNoDataCase");
setUpFreshInstallNoDataCase(true);
mContext = mApplication.getApplicationContext();
assertEquals(0, PersonRepository.getAllPersons(mContext).size());
public class LocalDataHelpers
public static final String TAG = "LocalDataHelpers";
static MyApp globalApplication;
public static void setupLocalData(MyApp app, String condition)
globalApplication = app;
if(globalApplication.daoSession != null)
Log.d(TAG, "daoSession not null");
globalApplication.daoSession.clear();
globalApplication.setupDatabase(condition);
在我的应用中 onCreate 和 setupDatabase 是这样的
public void onCreate()
Log.d(TAG, "onCreate");
super.onCreate();
EventBus.getDefault().register(this);
EventBus.getDefault().post(new PersonEvents.FetchPersonsFromServer());
setupDatabase(InitialConditions.DefaultSetUp);
private void setupDatabase(String condition)
DaoMaster.DevOpenHelper helper = null;
SQLiteDatabase db = null;
DaoMaster daoMaster = null;
if (condition.equals(InitialConditions.DefaultSetUp))
helper = new DaoMaster.DevOpenHelper(this, "example-db", null);
db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
else if (condition.equals(InitialConditions.FreshInstallNoData))
helper = new DaoMaster.DevOpenHelper(this, "freshInstallNoData-db", null);
db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
//clear all possible data here by dropping all tables and recreate
Log.d(TAG, "Dropping all tables and recreating them");
DaoMaster.dropAllTables(db, true);
DaoMaster.createAllTables(db, false);
if (helper != null && db != null && daoMaster != null)
daoSession.clear();
daoSession = daoMaster.newSession();
else
Log.e(TAG, "setupDatabase Error : condition " + condition + ", either helper or db or daomaster is null");
List<Pair<String, String>> dbs = getDaoSession().getDatabase().getAttachedDbs();
for (Pair<String, String> pair : dbs)
Log.d(TAG, "setupDatabase <" + pair.first + ", " + pair.second + ">");
FetchPersonsFromServer 的 onEvent 获取人员列表并使用 PersonDao 将他们保存到数据库中。
现在,如果我从我的设备中清除所有应用数据并直接运行测试,那么测试会按预期通过。但是,如果我正常运行应用程序,然后运行测试,断言语句在
处失败assertEquals(0, PersonRepository.getAllPersons(mContext).size());
大小与默认 db 值相同。
我快要疯了,想找出原因。 setupDatabase 中的日志语句显示正确的数据库名称正在显示,即freshdbinstall-db ...
android 不允许有两个 dbs 吗?逻辑上应该没有问题吧?是GreenDao不允许吗?我是否犯了一些基本错误...
请帮忙。
编辑:Creating more than 1 *.db file with greenDao android ORM library 是否相关?
更新 1
我使用 adb shell、run-as cat /sdcard/debug/db 和 adb pull 在测试失败后查看默认数据库和新数据库
新数据库符合预期,没有 Person 条目,默认有 10 个条目。所以我猜问题出在断言/查询调用上......由于某种原因,它似乎正在使用默认数据库......查看存储库代码是
public static List<Person> getAllPersons(Context context)
return getPersonDao(context).loadAll();
private static PersonDao getPersonDao(Context c)
return ((MyApp) c.getApplicationContext()).getDaoSession().getPersonDao();
据此看来会话没有被更新,前一个会话仍在使用中
【问题讨论】:
【参考方案1】:如果您可以选择Robolectric,这就是我们使用内存 SQLite 数据库和填充测试数据的方式:
TestApplication.java
public class TestApplication extends YourApplication
implements TestLifecycleApplication
@Override
public void onCreate()
super.onCreate();
YourProvider provider = new YourProvider(YOUR_CONTENT_AUTHORITY);
provider.onCreate();
ShadowContentResolver.registerProvider(YOUR_CONTENT_AUTHORITY, provider);
...
SomeTest.java
@RunWith(RobolectricTestRunner.class)
public class SomeTest
@Test
public void testSQLite()
// insert test data into in-memory SQLite
ShadowContentResolver resolver = shadowOf(Robolectric.getShadowApplication().getContentResolver());
ContentValues cv = new ContentValues();
cv.put("column_name", "column_value");
resolver.insert(YOUR_CONTENT_URI, cv);
// test against in-memory SQLite
...
...
对不起,我忘记了我阅读这篇文章的文章来源。
【讨论】:
以上是关于不同的sqlite数据库在android app中进行测试和实际使用的主要内容,如果未能解决你的问题,请参考以下文章
Ionic - 在 android 的不同目录中创建 SQLite 数据库
Android Studio App开发中数据库SQLite的解析及实战使用(包括创建数据库,增删改查,记住密码等 附源码必看)