YuiHatano介紹
YuiHatano是一款輕量級DAO單元測試框架墨叛,開發(fā)者可以通過此框架斩披,在Android Studio運行SQLiteDatabase、SharedPreference單元測試。
YuiHatano支持原生SQLiteDatabase操作及GreenDAO椰于、Afinal、XUtils遵班、DbFlow第三方庫。
在悅跑圈實踐
筆者在悅跑圈Android 2.10版本后使用了YuiHatano瞄勾,暫時沒發(fā)現(xiàn)問題费奸,配置方面也很方便。
關(guān)于命名
有道云翻譯:YuiHatano - 波多野**
(鑒于兒童不宜进陡,部分翻譯打碼愿阐。)
吐槽robolectric
相信很多同學,都用過或者聽聞過 Robolectric趾疚,一款Android單元測試框架缨历。無可否認,Robolectric稱得上是Android業(yè)界最權(quán)威的單元測試框架之一糙麦。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還有沒存在這問題)闸天。遇到這種情況暖呕,開發(fā)者只能花半天找問題或改配置。
盡管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一運行就加載資源問題,也更有效地輸出執(zhí)行的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參數(shù)欄唁影,點擊最右邊的...選擇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);
}
}
測試用例執(zhí)行SQL語句CREATE TABLE person (id INTEGER, name VARCHAR)
据沈,先創(chuàng)建臨時sqlite數(shù)據(jù)庫,再臨時創(chuàng)建person
表饺蔑。每個測試方法完成后锌介,臨時數(shù)據(jù)庫都會被刪除,因此不能在testA()
創(chuàng)建表猾警,testB()
使用這張表孔祸。
執(zhí)行結(jié)果:
結(jié)果顯示,只用了1秒多发皿,比robolectric快幾十倍崔慧。輸出的SQL語句是真實執(zhí)行在sqlite數(shù)據(jù)庫的。
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();
// 創(chuàng)建數(shù)據(jù)庫 build/test.db,數(shù)據(jù)庫名就是路徑
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "test.db", null);
// 獲取可寫數(shù)據(jù)庫
SQLiteDatabase db = helper.getWritableDatabase();
// 獲取數(shù)據(jù)庫對象
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());
}
}
執(zhí)行結(jié)果:
輸出結(jié)果玄货,顯示SQL語句CREATE TABLE "USER"...
皇钞、INSERT INTO "USER"
、SELECT...
松捉,上面的例子說了夹界,YuiHatano輸出的SQL都是真實執(zhí)行的。
AFinal惩坑、XUtils掉盅、DbFlow
YuiHatano還支持這幾款框架,本文不詳細說明以舒,在 Github 有詳細用例趾痘。
Native方法測試
(目前僅支持MacOS)
示例目錄結(jié)構(gòu):
./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等聯(lián)表查詢蔓钟,不知道YuiHatano對這方面是否有bug. 希望同學們遇到bug永票,在github issues上提出。
推薦閱讀:《Android 面試指南》
關(guān)于作者
我是鍵盤男滥沫。
在廣州生活侣集,悅跑圈Android工程師,猥瑣文藝碼農(nóng)兰绣。每天謀劃砍死產(chǎn)品經(jīng)理世分。喜歡科學、歷史缀辩,玩玩投資臭埋,偶爾旅行踪央。