推薦輕量級Android DAO單元測試框架——YuiHatano

image

YuiHatano介紹

https://github.com/kkmike999/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)理世分。喜歡科學、歷史缀辩,玩玩投資臭埋,偶爾旅行踪央。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瓢阴,隨后出現(xiàn)的幾起案子畅蹂,更是在濱河造成了極大的恐慌,老刑警劉巖荣恐,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件液斜,死亡現(xiàn)場離奇詭異,居然都是意外死亡叠穆,警方通過查閱死者的電腦和手機少漆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痹束,“玉大人检疫,你說我怎么就攤上這事〉凰唬” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵夺溢,是天一觀的道長论巍。 經(jīng)常有香客問我,道長风响,這世上最難降的妖魔是什么嘉汰? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮状勤,結(jié)果婚禮上鞋怀,老公的妹妹穿的比我還像新娘。我一直安慰自己持搜,他們只是感情好密似,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葫盼,像睡著了一般残腌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贫导,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天抛猫,我揣著相機與錄音,去河邊找鬼孩灯。 笑死闺金,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的峰档。 我是一名探鬼主播败匹,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼匣距,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了哎壳?” 一聲冷哼從身側(cè)響起毅待,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎归榕,沒想到半個月后尸红,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡刹泄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年外里,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片特石。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡盅蝗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出姆蘸,到底是詐尸還是另有隱情墩莫,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布逞敷,位于F島的核電站狂秦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏推捐。R本人自食惡果不足惜裂问,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牛柒。 院中可真熱鬧堪簿,春花似錦、人聲如沸皮壁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闪彼。三九已至甜孤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間畏腕,已是汗流浹背缴川。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留描馅,地道東北人把夸。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像铭污,于是被迫代替她去往敵國和親恋日。 傳聞我的和親對象是個殘疾皇子膀篮,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容