Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

E/TestRunner: android.database.sqlite.SQLiteException: no such table: Censored (code 1 SQLITE_ERROR)

I have an Android app with over 50 Espresso test cases. Most of the time the tests work correctly, but during some runs, one test case (only one) fails with a missing database table. All the other test cases use this table correctly. Sometimes the error message is different, such as:

android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 522 SQLITE_IOERR_SHORT_READ)

Code samples available on request, but it's a massive app so I doubt I could fit it all into a post.

Should I just replace the tablet with one that doesn't throw my bits away?


Another suggestion is I can warm up a Virtual Android Device and see if the error happens there.


Nope - the error also happens, occasionally, on a virtual tablet. Presumably with expensive ThinkPad storage, not with my cheap ONA tablet's storage.

The reason I can't post source for this (it's just by-the-book Espresso and Room code doing it) is when my app was small the problem didn't happen. Only growing the app allowed the problem to occur.

The test database uses a real file, in the getExternalFilesDir() folder; not the in-memory database. And switching to the getFilesDir() folder didn't fix the SQLite file corruption bugs. (I don't have a mounted SD card anyway.)


But lookie here, in the builder for the database: buildee.allowMainThreadQueries().

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you have a bug where corruption comes and goes, and appears in different forms, you have a race condition. So who is racing?

Android Espresso, following the Java ecosystem's penchant for thread abuse, runs its tests in a thread separate from the Android UI thread. (That breaks the rule "UI tests should treat UI objects like objects.")

But if the database is running IN that thread, then the tests' assembly code, creating database objects to test, is racing with the UI thread.

The solution is run as many tests as possible inside @UiThreadTest. And that requires throwing away all the Espresso onView() BS and just accessing view objects directly.


Per Room not creating database in UI-Tests , sprinkling some db.close() around the code also helped.

Switching the tests to use Room.inMemoryDatabaseBuilder() also seems to be helping.


The outer question remains: Has anyone written Espresso tests that called a Room database until smoke rolled out of their device like this before? Or am I really the first?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...