在本文中,就我在HYB项目中实际遇到的问题,和大家做一个分享.
#1.在控件的模拟事件执行的时候,尽量不要使用@UiThreadTest.因为如果一个Activity中,控件很多的话,很容易造成UI线程阻塞.
可以采用如下一段代码代替之:
1 private class PerformClick implements Runnable {
2 Button hhButton;
3 public PerformClick(Button HHButton) {
4 hhButton = HHButton;
5 }
6
7 @Override
8 public void run() {
9 hhButton.performClick();
10 }
11 }
#2.怎样对控件进行压力测试,我的处理是不停的调用View的Click事件
1 public void stressTestForButton(final Button btn,int pressNumber) {
2 for(int i = 0;i <= pressNumber;i++) {
3 new Thread(new Runnable() {
4 @Override
5 public void run() {
6 btn.requestFocus();
7 btn.performClick();
8 btn.clearFocus();
9 }
10 });
11 Log.i("count times", i + "");
12 }
13 }
#3.对控件上显示字段的测试,显示的字段来自strings.xml
1 public void testText() {
2 //testing String values
3 assertEquals(hayhouseLinkButtonString, (String)hayhouseLinkButton.getText());
4 assertEquals(hayhouseradioLinkButtonString, (String)hayhouseradioLinkButton.getText());
5 assertEquals(healLinkButtonString, (String)healLinkButton.getText());
6 }
#4.怎样在Activity中对各个Button的压力测试,注意对线程的控制
1 public void testButtonStress() {
2 Log.v(TAG, "testButtonStress method is starting");
3 SystemClock.sleep(400);
4 new OperateUtil().new performButtonClickStress(hayhouseLinkButton,10);
5 SystemClock.sleep(400);
6 addClickTimes(hayhouseLinkButton,50);
7 SystemClock.sleep(400);
8 addClickTimes(hayhouseLinkButton,100);
9 SystemClock.sleep(400);
10 addClickTimes(hayhouseLinkButton,200);
11 SystemClock.sleep(400);
12 new OperateUtil().new performButtonClickStress(hayhouseradioLinkButton,10);
13 SystemClock.sleep(400);
14 addClickTimes(hayhouseradioLinkButton,50);
15 SystemClock.sleep(400);
16 addClickTimes(hayhouseradioLinkButton,100);
17 SystemClock.sleep(400);
18 addClickTimes(hayhouseradioLinkButton,200);
19 SystemClock.sleep(400);
20 new OperateUtil().new performButtonClickStress(healLinkButton,10);
21 SystemClock.sleep(400);
22 addClickTimes(healLinkButton,50);
23 SystemClock.sleep(400);
24 addClickTimes(healLinkButton,100);
25 SystemClock.sleep(400);
26 addClickTimes(healLinkButton,200);
27 }
#5.在tearDown()方法里面一般进行的操作
1 @Override
2 protected void tearDown() throws Exception {
3 hayhouseLinkButton.clearFocus();
4 hayhouseLinkButton.clearComposingText();
5 hayhouseradioLinkButton.clearFocus();
6 hayhouseradioLinkButton.clearComposingText();
7 healLinkButton.clearFocus();
8 healLinkButton.clearComposingText();
9 detailView.clearFocus();
10
11 hayHouseActivity.finish();
12 super.tearDown();
13 }
#6.在app跑起来前,要保证所有的widget不能为空.
public void testPreConditions() { assertTrue(hayhouseLinkButton != null); assertTrue(hayhouseradioLinkButton != null); assertTrue(healLinkButton != null); assertTrue(gobackButton_hayhouse != null); assertTrue(detailView != null); }
#7.怎样对一个Service进行测试
1 /**
2 * From sdk description
3 *
4 * This test case provides a framework in which you can test Service classes
5 * in a controlled environment. It provides basic support for the lifecycle of a
6 * Service, and hooks with which you can inject various dependencies and
7 * control the environment in which your Service is tested.
8 */
9
10 public class AudioServiceTest extends ServiceTestCase<AudioService> {
11 private static final String TAG = "-----AudioServiceTest-----";
12
13 public AudioServiceTest() {
14 super(AudioService.class);
15 }
16
17 @Override
18 protected void setUp() throws Exception {
19 Log.i(TAG, "=====AudioServiceTest setUp Start=====");
20 super.setUp();
21
22 Log.i(TAG, "=====AudioServiceTest setUp End=====");
23 }
24
25 /**
26 * 2011.09.16 jack.li add......
27 * test basic startup/shutdown of Service
28 */
29 @SmallTest
30 public void testStartable() {
31 Log.i(TAG, "+++++AudioServiceTest testStartable Start+++++");
32 Intent startIntent = new Intent();
33 startIntent.setClass(getContext(), AudioService.class);
34 startService(startIntent);
35 assertNotNull(getService());
36 }
37
38 /**
39 * 2011.09.16 jack.li add......
40 * test binding to service
41 */
42 @MediumTest
43 public void testBindable() {
44 Log.i(TAG, "+++++AudioServiceTest testBindable Start+++++");
45 Intent startIntent = new Intent();
46 startIntent.setClass(getContext(), AudioService.class);
47 IBinder service = bindService(startIntent);
48 assertNotNull(service);
49 }
50
51 }
#8.如何对android中数据库进行一个单元测试,这里我引用网上的一个案例
数据库的逻辑代码如下:
1 import java.text.SimpleDateFormat;
2 import java.util.ArrayList;
3 import java.util.Date;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Random;
8
9 import android.content.ContentValues;
10 import android.content.Context;
11 import android.database.Cursor;
12 import android.database.DatabaseUtils;
13 import android.database.sqlite.SQLiteDatabase;
14
15 import com.android.hanhan.R;
16
17 public class DatabaseService {
18 private DatabaseHelper dbOpenHelper;
19 protected static final String TBL_NAME = "article";
20 protected static final String FIELD_ID = "id";
21 protected static final String FIELD_TITLE = "title";
22 protected static final String FIELD_CONTENT = "content";
23 protected static final String FIELD_DELETE = "deleted";
24 protected static final String FIELD_PUBLISHDATE = "publishdate";
25 protected static final String FIELD_FAVORITE = "favorite";
26 protected static final String FIELD_CLICKCOUNT = "clickcount";
27 protected static final String FIELD_FAVORITEDATE = "favoritedate";
28
29 //构造器,初始数据库服务
30 public DatabaseService(Context context) {
31 dbOpenHelper = new DatabaseHelper(context);
32 }
33
34 //删除表
35 public void dropTable(String taleName) {
36 dbOpenHelper.getWritableDatabase().execSQL(
37 "DROP TABLE IF EXISTS " + taleName);
38 }
39 //关闭数据库
40 public void closeDB() {
41 dbOpenHelper.getWritableDatabase().close();
42 }
43 //取得数据库TBL_NAME 表的所有数据
44 public List<Map<String, Object>> fetchALLArticle() {
45 SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
46 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
47 Cursor cur = db.query(TBL_NAME, new String[] {FIELD_ID, FIELD_TITLE, FIELD_CONTENT,
48 FIELD_PUBLISHDATE,FIELD_FAVORITE ,FIELD_DELETE }, null, null, null,
49 null, null);
50 list = getListFromDb(list, cur);
51 return list;
52 }
53 //取得数据库TBL_NAME表的数据个数
54 public long getPageCount(){
55 SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
56 return DatabaseUtils.queryNumEntries(db, TBL_NAME);
57 }
58 //根据分页尺寸和页数,取得数据列表
59 public List<Map<String, Object>> fetchCustomArticle(long pageSize, long pageID) {
60 SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
61 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
62 String sql = "select * from " + TBL_NAME +
63 " Limit "+String.valueOf((pageID-1)*pageSize)+" ,"+String.valueOf((pageID)*pageSize);
64 Cursor cur = db.rawQuery(sql, null);
65 list = getListFromDb(list, cur);
66 return list;
67 }
68 //取得数据列表方法
69 private List<Map<String, Object>> getListFromDb(List<Map<String, Object>> list, Cursor cur) {
70 if(cur.moveToFirst()){
71 do{
72 Map<String, Object> map = new HashMap<String, Object>();
73 map = addValueToMap(cur);
74 list.add(map);
75 }while(cur.moveToNext());
76 }
77 return list;
78 }
79 //将数据映射到map
80 private Map<String, Object> addValueToMap(Cursor cur) {
81 Map<String, Object> map = new HashMap<String, Object>();
82 map.put("id", cur.getString(cur.getColumnIndex(FIELD_ID)));
83 map.put("title", cur.getString(cur.getColumnIndex(FIELD_TITLE)));
84 map.put("info", cur.getString(cur.getColumnIndex(FIELD_PUBLISHDATE)));
85 map.put("content", cur.getString(cur.getColumnIndex(FIELD_CONTENT)));
86 map.put("publishdate", cur.getString(cur.getColumnIndex(FIELD_PUBLISHDATE)));
87 map.put("favorite", cur.getString(cur.getColumnIndex(FIELD_FAVORITE)));
88 map.put("delete", cur.getString(cur.getColumnIndex(FIELD_DELETE)));
89 map.put("img", R.drawable.stop);
90 return map;
91 }
92 }
对该sqlite数据库单元测试的方法如下:
1 import android.test.AndroidTestCase;
2 import com.android.hanhan.util.DatabaseService;
3
4 public class DatabaseServiceTest extends AndroidTestCase{
5 private DatabaseService dbs;
6
7 @Override
8 protected void setUp() throws Exception {
9 dbs = new DatabaseService(getContext());
10 }
11
12 @Override
13 protected void tearDown() throws Exception {
14 dbs.closeDB();
15 }
16
17 public void testPageCount() throws Exception{
18 assertEquals(12, dbs.getPageCount());
19 }
20
21 public void testFetchALLArticle() throws Exception{
22 assertEquals(12, dbs.fetchALLArticle().size());
23 }
24
25 }
#9.我在HYB项目中写的Database测试类也贴出来给大家看看
1 package com.ceosoftcenters.healyourbody.db.test;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8
9 import com.ceosoftcenters.healyourbody.sqlite.SQLiteHelper;
10 import com.ceosoftcenters.healyourbody.sqlite.vo.ProblemDetailVO;
11 import com.ceosoftcenters.healyourbody.sqlite.vo.ProblemVO;
12 import com.ceosoftcenters.healyourbody.util.ConstantsUtil;
13
14 import android.database.Cursor;
15 import android.database.sqlite.SQLiteDatabase;
16 import android.test.AndroidTestCase;
17 import android.util.Log;
18
19 /**
20 * @file SQLiteHelperTest.java
21 * @author Jack.Li
22 * @date 2011.09.15
23 * @description this class is mainly for SQLite Database's unit testing
24 * AndroidTestCase--->Extend this if you need to access Resources or other things that depend on Activity Context.
25 *
26 */
27
28 public class SQLiteHelperTest extends AndroidTestCase {
29 private static final String TAG = "-----SQLiteHelperTest-----";
30
31 //declare SQLiteHelper's instance ---> testSQLiteHelper
32 private SQLiteHelper testSQLiteHelper;
33
34 //private HealYourBodyApplication hybApp;
35
36 //declare SQLiteDatabase's instance ---> database
37 SQLiteDatabase database;
38
39 //all the data from the database
40 private ArrayList<ProblemVO> problemDataSet = null;
41
42 //2011.09.26 jack add......custom data for testing
43 private List<Map<String,Object>> list_testSQLiteHelper = null;
44
45 public static final String ITEM_PROBLEM_ID= "problem_Id";
46 public static final String ITEM_PROBLEM_NAME = "problem_Name";
47
48 //2011.10.12.PM jack new add...
49 public int ITEM_Number;
50
51 @Override
52 protected void setUp() {
53 try {
54 super.setUp();
55 }catch (Exception e) {
56 e.printStackTrace();
57 }
58
59 Log.i(TAG, "==SQLiteHelperTest setUp method is starting==");
60
61 testSQLiteHelper = new SQLiteHelper(getContext());
62 System.out.println("+++++" + testSQLiteHelper + "+++++");
63
64 database = SQLiteDatabase.openOrCreateDatabase(getContext().getFilesDir().getAbsolutePath() + ConstantsUtil.HEAL_YOUR_BODY_DBFILE_PATH, null);
65 System.out.println("+++++" + database + "+++++");
66
67 list_testSQLiteHelper = new ArrayList<Map<String,Object>>();
68 getListValue(list_testSQLiteHelper);
69
70 problemDataSet = new ArrayList<ProblemVO>();
71 setProblemDataSet(problemDataSet);
72
73 Log.i(TAG, "==SQLiteHelperTest setUp method is ending==");
74
75 }
76
77 //set values for problemDataSet
78 public void setProblemDataSet(ArrayList<ProblemVO> problemDataSet) {
79 //query database file to set data for list view
80 SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(getContext().getFilesDir().getAbsolutePath() + ConstantsUtil.HEAL_YOUR_BODY_DBFILE_PATH, null);
81
82 //query all data from the table bookdata -----> String sql = "select id,problem from bookdata";
83 Cursor cursor = database.rawQuery(ConstantsUtil.QUERY_ALL_ITEMS_ID_PROBLEM_SQL,null);
84 if (cursor.getCount() > 0) {
85 cursor.moveToFirst();
86 ProblemVO pd = null;
87 while(!cursor.isLast()) {
88 int id = cursor.getInt(0);
89 String problemName = cursor.getString(1);
90 pd = new ProblemVO(id,problemName);
91 problemDataSet.add(pd);
92 cursor.moveToNext();
93 }
94 int id = cursor.getInt(0);
95 String problemName = cursor.getString(1);
96 pd = new ProblemVO(id,problemName);
97 problemDataSet.add(pd);
98 //get the problemDtaSet's size -----> because it is a manually edit database,some items do not be used.
99 //So the last id number is not the problemDataSet's size
100 //get the problemDataSet's size
101 System.out.println("**********" + problemDataSet.size() + "**********");
102 ITEM_Number = problemDataSet.size();
103 }
104 cursor.close();
105 database.close();
106 }
107
108 //custom list values for testing
109 public void getListValue(List<Map<String,Object>> list_testSQLiteHelper) {
110 //I don't know why the last item is -----> "Itis" -----> solved
111 //we think "Itis" is a dirty data
112 //the custom data's number are 20
113 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("5", "Acne"));
114 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("11", "Aids"));
115 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("16", "Amnesia"));
116 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("22", "Anus"));
117 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("48", "Bad Breath"));
118 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("54", "Birth"));
119 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("64", "Blood"));
120 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("80", "Brain"));
121 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("117", "Coma"));
122 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("134", "Death"));
123 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("169", "Fat"));
124 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("177", "Fever"));
125 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("186", "Fistula"));
126 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("198", "Gastritis"));
127 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("234", "Hypertension"));
128 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("252", "Itching"));
129 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("260", "Knee"));
130 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("331", "Petit Mal"));
131 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("364", "Root Canal"));
132 list_testSQLiteHelper.add(SQLiteHelperTest.getHashMapValue("444", "Wrist"));
133 }
134
135 //jack new add...2011.09.26.am
136 public static HashMap<String,Object> getHashMapValue(String problem_Id,String problem_Name) {
137 HashMap<String,Object> hm_testSQLiteHelper = new HashMap<String,Object>();
138 hm_testSQLiteHelper.put(ITEM_PROBLEM_ID, problem_Id);
139 hm_testSQLiteHelper.put(ITEM_PROBLEM_NAME, problem_Name);
140
141 return hm_testSQLiteHelper;
142 }
143
144 public void testGetProblemDetailById() {
145 //total item's number is 440 -----> get the size 2011.10.08.am
146 //iterator the list_testSQLiteHelper,to get per item's id and name
147 Iterator<Map<String,Object>> it = list_testSQLiteHelper.iterator();
148 while(it.hasNext()) {
149 Map<String,Object> hm = it.next();
150 String problem_Id = (String)hm.get(ITEM_PROBLEM_ID);
151 String Problem_Name = (String)hm.get(ITEM_PROBLEM_NAME);
152
153 ProblemDetailVO pdvo = testSQLiteHelper.getProblemDetailById(problem_Id, Problem_Name);
154 //perform toString() method
155 System.out.println(">>>>>" + pdvo + "<<<<<");
156 }
157 System.out.println("@@@" +"iterator method is ending......" + "@@@");
158
159 }
160
161 public void testGetProblemDetailByIdAllData() {
162 for(ProblemVO pd: problemDataSet) {
163 String problemId = pd.getId() + "";
164 String problemName = pd.getProblemName();
165 ProblemDetailVO pdvo = testSQLiteHelper.getProblemDetailById(problemId, problemName);
166
167 System.out.println(">>>>>" + pdvo + "<<<<<");
168 }
169 }
170
171 //test the data count ---> sum
172 public void testSetProblemDataSetSize() throws Exception{
173 //put all the ProblemVO instance into the problemDataSet ArrayList
174 //problemDataSet = new HealYourBodyApplication().getProblemDataSet();
175 assertEquals(440, problemDataSet.size());
176 assertEquals(false, problemDataSet.size() == 445);
177 assertEquals(false, problemDataSet.size() == 335);
178 }
179
180 @Override
181 protected void tearDown() throws Exception {
182 Log.i(TAG, "==SQLiteHelperTest tearDown method is starting==");
183 //close the resource
184 database.close();
185 super.tearDown();
186 }
187
188 }
至此我对android单元测试的研究告一段落.以后有机会会继续深入学习的.
2011.10.21.pm
jack.li
QQ:523072842
Email:523072842@qq.com
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.