Android單元測(cè)試之對(duì)Activity的測(cè)試示例
上一篇文章已經(jīng)介紹了單元測(cè)試的作用和簡(jiǎn)單示例,如果不了解的讀者可以先閱讀上一篇Android單元測(cè)試-作用以及簡(jiǎn)單示例。
這篇文章主要介紹常見的Activity中的測(cè)試。
對(duì)Acitivity的測(cè)試
對(duì)于Activity,我們大致有兩種測(cè)試需求:
1、在Activity正常啟動(dòng)后,查看界面布局是否正確,包括View的點(diǎn)擊事件等是否正確。
2、需要在Activity啟動(dòng)前完成各種數(shù)據(jù)的部署,然后查看Activity的效果。
對(duì)于這兩種需求,筆者分別做了兩個(gè)示例解說:
1、檢測(cè)一個(gè)布局中的button和TextView是否正確。
2、從網(wǎng)絡(luò)動(dòng)態(tài)獲取String到Activity界面顯示,并且這個(gè)圖片的URL是由Intent傳遞過來的。
環(huán)境部署
首先要導(dǎo)入expresso-core的包,如下:
dependencies {
// Other dependencies ...
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
}
當(dāng)然在目前的項(xiàng)目架構(gòu)中一般已經(jīng)自動(dòng)導(dǎo)入了這個(gè)包,所以不需要自己導(dǎo)入,筆者項(xiàng)目中自動(dòng)導(dǎo)入的包如下如下:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
}
項(xiàng)目結(jié)構(gòu)如下:

布局View的測(cè)試:
package com.example.xujiajia_sx.myexpressotest;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class SimpleViewActivity extends Activity{
private TextView tv;
private Button btn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_simple_view);
initView();
}
private void initView() {
tv=findViewById(R.id.tv_simple_view);
btn=findViewById(R.id.btn_simple_view);
tv.setText("111");
btn.setText("222");
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tv.setText("777");
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_simple_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btn_simple_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
package com.example.xujiajia_sx.myexpressotest;
import android.support.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class SimpleViewTest {
@Rule
public ActivityTestRule<SimpleViewActivity> mActivityTestRule =
new ActivityTestRule<SimpleViewActivity>(SimpleViewActivity.class);
@Test
public void textViewTest() throws Exception {
onView(withId(R.id.tv_simple_view))
.check(matches(withText("111")));
}
@Test
public void buttonTest() throws Exception {
onView(withId(R.id.btn_simple_view))
.check(matches(withText("222")))
.perform(click());
onView(withId(R.id.tv_simple_view))
.check(matches(withText("777")));
}
}
測(cè)試主要邏輯:
1、首先要使用ActivityTestRule初始化你要測(cè)試的Activity。
2、編寫測(cè)試方法,測(cè)試View是否是我們預(yù)期的樣子。
兩個(gè)測(cè)試方法邏輯如下:
textViewTest():
在Activity中查找id為tv_simple_view的View,檢查它的text是否為“111”。
buttonTest():
在Activity中查找id為btn_simple_view的View,檢查它的text是否為“222”。然后執(zhí)行點(diǎn)擊事件,點(diǎn)擊事件的邏輯是在Activity的OnCreate中設(shè)置的,是把TextView的text設(shè)置為777。在執(zhí)行完點(diǎn)擊事件后,測(cè)試方法中繼續(xù)測(cè)試TextView的text是否為“777”。
讀者可能閱讀到對(duì)View的測(cè)試非常陌生,不用擔(dān)心,此處主要要理解測(cè)試的邏輯即可,筆者會(huì)在下篇文章具體講解View的各種測(cè)試方法。
網(wǎng)絡(luò)獲取String的Activity測(cè)試:
package com.example.xujiajia_sx.myexpressotest;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.TextView;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class ActTestActivity extends Activity{
private TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_act_test);
initView();
}
private void initView() {
tv= findViewById(R.id.tv_act_test);
new Thread(new Runnable() {
@Override
public void run() {
String url =getIntent().getStringExtra("url");
final String s=mHttpClient.getInstance().get(url);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(s);
}
});
}
}).start();
}
}
package com.example.xujiajia_sx.myexpressotest;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class mHttpClient {
private static HttpURLConnectionClient mClient = null;
public static void setClient(HttpURLConnectionClient client) {
mClient = client;
}
public static HttpURLConnectionClient getInstance() {
return mClient;
}
}
package com.example.xujiajia_sx.myexpressotest;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import static android.content.ContentValues.TAG;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class HttpURLConnectionClient {
public String get(String url) {
HttpURLConnection conn = null;
try {
URL mURL = new URL(url);
conn = (HttpURLConnection) mURL.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
conn.connect();
InputStream is = conn.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
} catch (IOException e) {
Log.e(TAG, "network error for mini program ", e);
return "";
} finally {
//最后將conn斷開連接
if (conn != null) {
conn.disconnect();
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_act_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
package com.example.xujiajia_sx.myexpressotest;
import android.content.Intent;
import android.support.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
/**
* Created by xujiajia_sx on 2017/8/14.
*/
public class ActTest {
@Rule
public ActivityTestRule<ActTestActivity> mActivityTestRule=
new ActivityTestRule<ActTestActivity>(ActTestActivity.class){
@Override
protected Intent getActivityIntent() {
Intent intent=new Intent();
intent.putExtra("url","http://www.weather.com.cn/adat/sk/101310201.html");
return intent;
}
@Override
protected void beforeActivityLaunched() {
mHttpClient.setClient(new HttpURLConnectionClient());
}
};
@Test
public void mTest() throws Exception{
Thread.sleep(5000);
}
}
網(wǎng)絡(luò)獲取不要忘記在AndroidManifest中加網(wǎng)絡(luò)權(quán)限喔。
這個(gè)Activity的主要邏輯就是接收Intent,然后獲取到傳過來的url,接著通過網(wǎng)絡(luò)獲取到url的String,顯示到TextView上。
主要測(cè)試邏輯:
首先還是要定義ActivityTestRule,確定使用哪個(gè)Activity。
與前一個(gè)例子不同的是,這里要重寫ActivityTestRule的兩個(gè)方法,getActivityIntent() 和beforeActivityLaunched()。顧名思義,一個(gè)是設(shè)置Activity獲取到的Intent,另一個(gè)是設(shè)置Activity啟動(dòng)跟之前的準(zhǔn)備工作。
筆者此處在getActivityIntent() 中設(shè)置了傳遞的url,在beforeActivityLaunched()設(shè)置的網(wǎng)絡(luò)獲取的方式。
有些讀者可能會(huì)好奇為什么網(wǎng)絡(luò)獲取的方式不默認(rèn)呢,而要通過setClient()來設(shè)置?
因?yàn)檫@樣可以更方便我們測(cè)試,在正式的項(xiàng)目中,我們可能會(huì)需要在代碼中加入log等操作,但是正式的代碼一般我們是不會(huì)去修改的,但是我們可以繼承它,重寫某些方法,然后把它放到測(cè)試需要的地方。
在這里我們就可以繼承HttpURLConnectionClient 這個(gè)類,然后把繼承的子類使用setClient()來作為網(wǎng)絡(luò)獲取的方式。
總結(jié)
Activity的使用方法大致如此了,如果有更多需求的讀者可以查看一下官方ActivityTestRule的Reference。
鏈接如下:https://developer.android.google.cn/reference/android/support/test/rule/ActivityTestRule.html
第一種使用方法中設(shè)計(jì)到了對(duì)View的測(cè)試,由于篇幅較大,本篇文章未能詳細(xì)講述,筆者會(huì)在下篇文章做一定講解。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解appium+python 啟動(dòng)一個(gè)app步驟
- Python腳本在Appium庫(kù)上對(duì)移動(dòng)應(yīng)用實(shí)現(xiàn)自動(dòng)化測(cè)試
- 詳解Android單元測(cè)試最佳實(shí)踐
- android開機(jī)自啟動(dòng)APP及使用adb命令測(cè)試方法
- Android利用Espresso進(jìn)行UI自動(dòng)化測(cè)試的方法詳解
- 在Android打包中區(qū)分測(cè)試和正式環(huán)境淺析
- 淺談Android單元測(cè)試的作用以及簡(jiǎn)單示例
- Android和iOS 測(cè)試五個(gè)最好的開源自動(dòng)化工具
- Android 中構(gòu)建快速可靠的 UI 測(cè)試
- 簡(jiǎn)單談?wù)刟ndroid studio 的單元測(cè)試
- Android Monkey壓力測(cè)試詳細(xì)介紹
- Ubuntu中為Android系統(tǒng)上實(shí)現(xiàn)內(nèi)置C可執(zhí)行程序測(cè)試Linux內(nèi)核驅(qū)動(dòng)程序
- Android App開發(fā)的自動(dòng)化測(cè)試框架UI Automator使用教程
- Android自動(dòng)測(cè)試工具M(jìn)onkey的實(shí)現(xiàn)方法
- Android測(cè)試中Appium的一些錯(cuò)誤解決技巧
相關(guān)文章
有關(guān)微博content的封裝實(shí)現(xiàn)詳解
本文將詳細(xì)介紹關(guān)于微博content的封裝實(shí)現(xiàn),需要的朋友可以參考下2012-11-11
Android RatingBar星星評(píng)分控件實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了Android RatingBar星星評(píng)分控件,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-06-06
淺談Android性能優(yōu)化之內(nèi)存優(yōu)化
Android的內(nèi)存優(yōu)化是性能優(yōu)化中很重要的一部分,本文將詳細(xì)介紹Android性能優(yōu)化之內(nèi)存優(yōu)化。2021-06-06
Android中Fragment子類及其PreferenceFragment的創(chuàng)建過程演示
這篇文章主要介紹了Android中Fragment子類及其PreferenceFragment的創(chuàng)建過程演示,PreferenceFragment用來保存Fragment的選項(xiàng)設(shè)置,需要的朋友可以參考下2016-05-05
自定義GridView并且實(shí)現(xiàn)拖拽(附源碼)
本文實(shí)現(xiàn)了GridView的拖拽功能,原理很簡(jiǎn)單只是在交換位置上記錄了X軸的相關(guān)坐標(biāo),計(jì)算了X軸的相關(guān)變量,實(shí)例代碼如下,感興趣的額朋友可以參考下哈2013-06-06
WorkManager解決應(yīng)用退出后繼續(xù)運(yùn)行后臺(tái)任務(wù)
這篇文章主要為大家介紹了WorkManager解決應(yīng)用退出后繼續(xù)運(yùn)行后臺(tái)任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Android開發(fā)筆記之:如何安全中止一個(gè)自定義線程Thread的方法
本篇文章是對(duì)Android中如何安全中止一個(gè)自定義線程Thread的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android APP使用自定義字體實(shí)現(xiàn)方法
這篇文章主要介紹了Android APP使用自定義字體實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下2016-10-10

