Android的單元測試大家都不陌生慢叨,必要的單元測試可以提高工作效率纽匙,省去大量的在Android真機或者虛擬機上的調(diào)試,提高代碼質(zhì)量拍谐。尤其是在團隊項目開發(fā)中烛缔,為自己寫的代碼負(fù)責(zé)馏段,提高項目后期的可維護性。這篇文章算是個人心得體會吧践瓷。
前幾天接了一個任務(wù)就是對團隊中現(xiàn)有的一個項目的dao層寫單元測試(數(shù)據(jù)訪問對象)院喜,該項目中的數(shù)據(jù)庫適配器(MyDataBaseAdapter)中集成了大量的關(guān)于數(shù)據(jù)庫中增,刪晕翠,改喷舀,查的方法,現(xiàn)在要測試這些函數(shù)的功能淋肾。然后就遇到了一些問題硫麻,比如說不能對原有的數(shù)據(jù)庫帶來臟數(shù)據(jù),而且要測試這些方法還必須要在數(shù)據(jù)庫中測試樊卓。搜集了一些資料比如Spring結(jié)合junit利用對數(shù)據(jù)庫的回滾操作進行測試拿愧。但還是找到了更好的方法,就是robolectric框架简识。
有關(guān)Robolectric測試框架的詳細知識個人感覺簡書:鍵盤男http://www.reibang.com/u/0ef3dc77079c他的博客寫的是很不錯的有關(guān)其他的測試可以參考一下赶掖。
接下來總結(jié)一下對dao層的測試。
添加依賴七扰,(3.3.2并不是最新版本)
testCompile 'org.robolectric:robolectric:3.3.2'
定義數(shù)據(jù)工具類
定義的字段對應(yīng)之前數(shù)據(jù)庫的字段(比如原數(shù)據(jù)庫需要測試id或name的刪除更新等奢赂,根據(jù)需求定義)
如果數(shù)據(jù)庫表字段較少,可以直接插入數(shù)據(jù)颈走,不用定義該類
public class BaseInfo {
private int id(字段1)膳灶;
private String name(字段2);
·
·
·
·
·
private int 字段13;
private String 字段14;
public BaseInfo(int id,String name,``````,) {
super();
this.id=id;
this.name=name;
`
`
`
this.XX=XX;
}
設(shè)置geter和seter
}
定義各表字段
定義測試用的insert函數(shù)(將數(shù)據(jù)插入數(shù)據(jù)庫)
public Long insertTestData(BasemInfo basemInfo){
//hashmap保存表列與數(shù)據(jù)
ContentValues initialValues = new ContentValues();
initialValues.put(列名._ID,baseInfo.getID());
`
`
`
`
initialValues.put(列名.NAME,baseInfo.getNAME());
return mSQLiteDatabase.insert(數(shù)據(jù)庫表名, null, initialValues);
}
測試之前的環(huán)境配置
用這個框架測試之前建立一個新的數(shù)據(jù)庫立由,用于各種測試轧钓,每個測試結(jié)束后自動刪除數(shù)據(jù)庫,所以不用擔(dān)心對原有的數(shù)據(jù)庫造成干擾锐膜。
@RunWith(RobolectricTestRunner.class)//Robolectric是一個單元測試框架毕箍,可以對Android SDK jar進行消除
@Config(constants = BuildConfig.class, sdk = 21, manifest = Config.NONE)//配置環(huán)境sdk版本等等
/**
* 該類用于測試數(shù)據(jù)庫的一些增刪改查的方法
* 測試用類
*/
public class TestMyDataBaseAdapter {
public MyDataBaseAdapter myDataBaseAdapter;
private SQLiteDatabase mSQliteDatabase;
private Context mContext;
//用來添加一條模擬數(shù)據(jù)(自定義的數(shù)據(jù)bean類,收集數(shù)據(jù)且對應(yīng)數(shù)據(jù)庫字段)
private static BaseInfo testBaseInfo;
@Before
public void setUp() {
//創(chuàng)建并打開數(shù)據(jù)庫
myDataBaseAdapter =new MyDataBaseAdapter(RuntimeEnvironment.application);
//獲得測試環(huán)境
mContext = RuntimeEnvironment.application;
mSQliteDatabase = myDataBaseAdapter.getSQLiteDatabase();
//輸出log
ShadowLog.stream=System.out;
/**
* 測試用的模擬數(shù)據(jù)
*/
testBaseInfo=new BaseInfo(
4,//數(shù)據(jù)id=4
張三,//下面均為虛擬測試數(shù)據(jù)(每個數(shù)據(jù)對應(yīng)數(shù)據(jù)庫表的字段道盏,根據(jù)被測的函數(shù)模擬即可)
0,
null,
"測試1",
0,
1000,
"a",
false,
0,
0,
0,
0,
null,
null,
(byte)1,
(byte)0,
0,
0
);
}
@After
public void tearDown() {
//結(jié)束測試關(guān)閉數(shù)據(jù)庫
myDataBaseAdapter.close();
}
/**
* 根據(jù)id更新name
*
*/
@Test
public void update() {
//數(shù)據(jù)庫表插入測試數(shù)據(jù)
myDataBaseAdapter.insertTestData(testBaseInfo);
//調(diào)用被測試的方法update而柑,修改id=4的name值為李四(原本為張三)
//輸入期望的值
int expectValues=李四;
myDataBaseAdapter.update(testBaseInfo.getID(),expectValues);
Cursor cursor= myDataBaseAdapter.getDataByTimerId(testBaseInfo.getID());
//利用Cursor查出來真實的值(也可以直接用Sql語句)
cursor.moveToFirst();
String t actualValues=cursor.getString(MyDataBaseAdapter.NAME_INDEX);
//對比兩者值是否相同
cursor.close();
Assert.assertEquals(expectValues,actualValues);
}
/**
* 更新Xxxx
*/
@Test
public void updateXxxx() {
1.測試數(shù)據(jù)插入數(shù)據(jù)庫
2.調(diào)用被測函數(shù),修改對應(yīng)參數(shù)的值(期望值)
3.取出該數(shù)據(jù)(真實值)
4.期望值與真實值比較
}
/**
* 插入Xxxx
*/
@Test
public void insertXxxx() {
1.調(diào)用被測函數(shù)荷逞,插入一條數(shù)據(jù)(期望值)
2.取出該數(shù)據(jù)(真實值)
3.期望值與真實值比較
}
·
·
·
}
查找媒咳,刪除等也可以用類似的思想單元測試。
正在學(xué)習(xí)安卓种远,希望能夠多積累涩澡,多提升