YuiHatano介紹
YuiHatano是一款輕量級DAO單元測試框架,開發者可以通過此框架,在Android Studio運行SQLiteDatabase、SharedPreference單元測試。
YuiHatano支持原生SQLiteDatabase操作及GreenDAO、Afinal、XUtils、DbFlow第三方庫。
在悅跑圈實踐
筆者在悅跑圈Android 2.10版本后使用了YuiHatano,暫時沒發現問題,配置方面也很方便。
關于命名
有道云翻譯:YuiHatano - 波多野**
(鑒于兒童不宜,部分翻譯打碼。)
吐槽robolectric
相信很多同學,都用過或者聽聞過 Robolectric,一款Android單元測試框架。無可否認,Robolectric稱得上是Android業界最權威的單元測試框架之一。Google推薦的AndroidJUnitRunner、espresso,跑測試都要運行在真機或模擬器上,而robolectric可以在pc上跑ui測試,無疑大大地提高運行速度。
robolectric下載依賴慢、配置麻煩
但是,剛上手robolectric的小白,特別是天朝的同學,都會說上百次Fu*k。因為,robolectric在運行時,會去https://oss.sonatype.org下載幾十M的庫,最可怕的是,https://oss.sonatype.org很慢很慢,第一次運行你可以去吃個中午飯,喝個下午茶,回來也未必下載完。筆者已給出解決方案:《加速Robolectric下載依賴庫》。
還有,robolectric有各種配置,偶爾還有配置沒改,突然跑不起來,說找不到**文件等bug(不知道3.3還有沒存在這問題)。遇到這種情況,開發者只能花半天找問題或改配置。
盡管robolectric第一次hello world比較頭疼,配置繁瑣,文檔較少,ui測試功能有限,但確實是一種不錯的在本地運行的單元測試方案。
robolectric還是慢
雖然,robolectric在本地運行,比編譯單元測試,扔上真機跑的AndroidJunitRunner、espresso要快;但是無論你跑多簡單的test case,它每次運行都要花上幾秒加載&解析資源等,如果項目比較復雜,甚至耗時十幾秒(筆者親測)。
一個簡單的test case:
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class RoboTest {
@Test
public void test() throws Exception {
System.out.println("first robo test");
}
}
居然耗費10s!!
更好的方案——YuiHatano
其實,YuiHatano是筆者擼的一個框架,目的是解決robolectric運行慢問題。YuiHatano不存在robolectric一運行就加載資源問題,也更有效地輸出執行的sqlite語句。
YuiHatano僅僅提供DAO測試功能,如果你要測ui,請選其他方案。
Getting Started
Building with Gradle
repositories {
maven { url "https://dl.bintray.com/kkmike999/maven" }
}
dependencies {
testImplementation('net.yui:YuiHatano:1.1.4') {
exclude group: 'com.android.support'
}
}
Configuration
在Android Studio操作欄,Run->EditConfigurations,雙擊Defaults,選擇Android JUnit窗口,找到Working directory參數欄,點擊最右邊的...選擇MODULE_DIR。
寫第一個測試
SQLiteDatabase
public class SQLiteDatabaseTest extends YuiCase {
SQLiteDatabase db;
@Before
public void setUp() throws Exception {
// 使用YuiHatano提供的Context,獲取SQLiteDatabase實例
db = getContext().openOrCreateDatabase("build/test.db", 0, null);
}
@Test
public void testCreateTable() {
String sql = "CREATE TABLE person (id INTEGER, name VARCHAR)";
db.execSQL(sql);
}
}
測試用例執行SQL語句CREATE TABLE person (id INTEGER, name VARCHAR)
,先創建臨時sqlite數據庫,再臨時創建person
表。每個測試方法完成后,臨時數據庫都會被刪除,因此不能在testA()
創建表,testB()
使用這張表。
執行結果:
結果顯示,只用了1秒多,比robolectric快幾十倍。輸出的SQL語句是真實執行在sqlite數據庫的。
GreenDAO
先按 GreenDAO 官方文檔,配置好gradle等。
User
類
@Entity
public class User {
// 不能用int
@Id(autoincrement = true)
private Long id;
@Unique
private int uid;
private String name;
public User(int uid, String name) {
this.uid = uid;
this.name = name;
}
}
單元測試
public class GreenDAOTest extends GreenDAOCase {
private DaoSession mDaoSession;
private UserDao mUserDAO;
@BeforeClass
public static void beforeClass() {
DebugHook.setDebug(true);
}
@Before
public void setUp() throws Exception {
Context context = getContext();
// 創建數據庫 build/test.db,數據庫名就是路徑
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "test.db", null);
// 獲取可寫數據庫
SQLiteDatabase db = helper.getWritableDatabase();
// 獲取數據庫對象
DaoMaster daoMaster = new DaoMaster(db);
// 獲取Dao對象管理者
mDaoSession = daoMaster.newSession();
mUserDAO = mDaoSession.getUserDao();
}
@Test
public void testInsert() {
int uid = 1;
String name = "鍵盤男";
User user = new User(uid, name);
mUserDAO.insert(user);
List<User> users = mUserDAO.loadAll();
Assert.assertEquals(1, users.size());
Assert.assertEquals(1, users.get(0).getUid());
Assert.assertEquals("鍵盤男", users.get(0).getName());
}
}
執行結果:
輸出結果,顯示SQL語句CREATE TABLE "USER"...
、INSERT INTO "USER"
、SELECT...
,上面的例子說了,YuiHatano輸出的SQL都是真實執行的。
AFinal、XUtils、DbFlow
YuiHatano還支持這幾款框架,本文不詳細說明,在 Github 有詳細用例。
Native方法測試
(目前僅支持MacOS)
示例目錄結構:
./app/
└── src
├── main
│ ├── cpp
│ │ ├── CMakeLists.txt
│ │ └── jni.cpp
│ ├── java
│ │ └── net
│ │ └── yui
│ │ └── app
│ │ ├── JNI.java
└── test
└── java
└── net
└── yui
└── app
├── jni
│ └── TestJNI.java
含有native方法的JNI
:
public class JNI {
public native int add(int a, int b);
}
測試用例繼承JNICase
,其他代碼照常:
public class TestJNI extends JNICase {
static {
System.loadLibrary("jni");
}
@Test
public void testJNI() {
JNI jni = new JNI();
Assert.assertEquals(2, jni.add(1, 1));
}
}
不完善的地方
筆者還未試過GreenDAO等聯表查詢,不知道YuiHatano對這方面是否有bug. 希望同學們遇到bug,在github issues上提出。
推薦閱讀:《Android 面試指南》
關于作者
我是鍵盤男。
在廣州生活,悅跑圈Android工程師,猥瑣文藝碼農。每天謀劃砍死產品經理。喜歡科學、歷史,玩玩投資,偶爾旅行。