Android 开发基础 在 uiautomator2.0 中使用 android api

benlee · April 25, 2016 · Last by double replied at May 07, 2016 · 3056 hits

使用uiautomator2.0一段时间,总结一下一些使用。比如如何使用android api来加强自动化测试的效率和正确性。

首先看一下项目的目录结构:

红框为uiautomator2.0的项目结构。而com.meizu.ltemtbf实际其实就是一个apk工程。
所以我们可以在uiautomator2.0中直接调用android api来服务自动化测试。

初始化测试:

//@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
public class ApplicationTest {

private static final String TEST_PACKAGE = "com.android.dialer";
private static final int TIMEOUT = 5000;
private static final String TAG = "benlee";
private Context mContext;
private Context appContext;
private UiDevice mDevice;
private TelephonyManager telephonyManager;

// @Before
@Before
public void before() {
Log.i(TAG, "before");
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mContext = InstrumentationRegistry.getContext();
appContext = InstrumentationRegistry.getTargetContext().getApplicationContext();
//返回到桌面
mDevice.pressHome();
}

@After
public void after() throws IOException {
Log.i(TAG, "after");
mDevice.pressHome();
//退出app
// mDevice.executeShellCommand("am force-stop " + TEST_PACKAGE);
}

其中:
appContext = InstrumentationRegistry.getTargetContext().getApplicationContext();
该行代码可以让uiautomator2.0获取当前apk的Context来调用相关android api方法。
要注意的是,这里获取的Context其实是测试apk本身的Context,而非被测apk的Context。

以下是使用android api的方式查询uri为"content://sms/sent"和"content://sms/inbox"对应字段,来确认短信是否成功发送/接收

public String getMessageStatus(String uri,String phonenum,String smstext) {
//使用appContext
ContentResolver cr = appContext.getContentResolver();
Cursor cursor = cr.query(Uri.parse(uri), null, null, null, null);
while(cursor.moveToNext()) {
//根据发送/接收地址(手机号码)和短信内容,查询获取其短信的发送/接收状态
int phoneColumn = cursor.getColumnIndex("address");
int infoColumn = cursor.getColumnIndex("body");
String num = cursor.getString(phoneColumn);
String smsText = cursor.getString(infoColumn);
if(num.contains(phonenum)&&smsText.equals(smstext)){
int typeColumn = cursor.getColumnIndex("type");
return cursor.getString(typeColumn);
}
else{
Log.i(TAG,phonenum+":"+num+":"+smsText);
}
}
cursor.close();
return null;
}

然后我们就可以使用上述的方法在测试用例中应用:

@Test
public void test003SMS() throws InstantiationException, IllegalAccessException {
startApp("com.android.mms");
findObjById("com.android.mms:id/create_new_btn").click();
String num = getPhoneNumber();
findObjById("com.android.mms:id/mz_recipient_edit").setText(num);
mDevice.pressBack();
SystemClock.sleep(1000);
findObjById("com.android.mms:id/embedded_text_editor").setText("test003SMS");
if (findObjById("com.android.mms:id/right_btn").isEnabled()) {
findObjById("com.android.mms:id/right_btn").click();
}
//判断短信是否发送成功,返回为2,即发送成功
boolean res = checkSmsStatus("content://sms/sent",getPhoneNumber(),"test003SMS","2");
Assert.assertTrue(res);
//判断短信是否接收成功,返回为1,即接收成功
boolean inboxres = checkSmsStatus("content://sms/inbox",getPhoneNumber(),"test003SMS","1");
Assert.assertTrue(inboxres);

int count = mDevice.wait(Until.findObjects(By.text("test003SMS")), TIMEOUT).size();
Assert.assertEquals(count,2);
}

P.S:代码写的不怎么样,有些方法自己封装的。大家大概看得懂就好。: )

当然也要在AndroidManifest.xml上添加相应的权限。

<uses-permission android:name="android.permission.READ_SMS" />

后续:
会尝试应用broadcast、service、多线程、aidl、binder等的方式来提高自动化测试的效率和正确性。

有人可能觉得这样做自动化成本太高,但其实在实践的过程中是完全可以提升自己对android开发的理解,
这样也未尝是另一种提升的方式。

共收到 6 条回复 时间 点赞

学习了

@sziitash 大神,我在您另一篇帖子留的问题有点儿急啊,能否回覆一下救救小弟啊谢谢@@ !!

好帖留名。

包名泄露身份。。。

好赞

这么多魅族的童鞋

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up