日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Robolectric测试框架使用文档

發(fā)布時(shí)間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Robolectric测试框架使用文档 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

Robolectric使用文檔

--keeng2008@qq.com 2016-01-07

1.測(cè)試驅(qū)動(dòng)你的Android應(yīng)用代碼

在Android模擬器或者手機(jī)上運(yùn)行單元測(cè)試是很漫長(zhǎng)的。每次編譯、部署、啟動(dòng)應(yīng)用都需要耗時(shí)1分鐘以上。有沒(méi)有更好的辦法呢?

Robolectric 是一個(gè)針對(duì)于Android SDK 的單元測(cè)試框架,使用它可以測(cè)試驅(qū)動(dòng)你的Android應(yīng)用程序的開(kāi)發(fā)。測(cè)試用例只需要在JVM基礎(chǔ)上就能運(yùn)行起來(lái),這節(jié)省了大量的時(shí)間。使用Robolectric后,你只需要寫出類似這樣的測(cè)試代碼:

@RunWith(RobolectricTestRunner.class)

public class MyActivityTest {

? @Test

? public void clickingButton_shouldChangeResultsViewTest() throws Excepiton {

MyActivity activity = Robolectric.setupActivity(MyActivity.class);

?

Button button = (Button) activity.findViewById(R.id.button);

TextView results = (TextView) activity.findViewById(R.id.results);

?

?button.performClick();

?assertThat(results.getText().toString()).isEqualTo("Robolectric Rocks!");

}

}

?

?

Robolectric 通過(guò)重寫Android SDK 的實(shí)現(xiàn)類,然后被加載到測(cè)試工程中,然后讓上面的測(cè)試代碼可以在JVM上運(yùn)行。

?

SDK,資源,原生方法的模擬

Robolectric 模擬了界面生成,資源加載,還有大量的基于Android設(shè)備底層C語(yǔ)言提供的原生方法提供的功能。這可以讓測(cè)試模擬到跟真實(shí)設(shè)備一樣的大部分事情。如果對(duì)于一些具體的SDK方法提供自己的實(shí)現(xiàn),也是非常容易的,所以你可以模擬真實(shí)機(jī)器上發(fā)生的一些出錯(cuò)的條件,出錯(cuò)的行為。

?

2.開(kāi)始使用Robolectric

Robolectric在Gradle和Maven上測(cè)試運(yùn)行得很好。

使用Gradle

在build.gradle里添加下面一行:

testCompile “org.robolectric:robolectric:3.0”

在測(cè)試用例代碼中添加Gradle Test的注解

@RunWith(RobolectricGradleTestRunner.class)

@Config(constants = BuildConfig.class)

public class SandwichTest {

}

?

注意,一定要配置constants屬性指向BuildConfig.class, 編譯系統(tǒng)會(huì)自動(dòng)生成這個(gè)類,不用手動(dòng)創(chuàng)建。Robolectric讀取constants配置好的輸出路徑,Gradle生成項(xiàng)目時(shí)會(huì)使用到。如果沒(méi)有這些值,Robolectric就找不到應(yīng)用的manifest, resources還有assets等資源。

在Android Studio 生成

Robolectric支持Android Studio 1.1.0及更高的版本。只需要簡(jiǎn)單的參照上面Gradle的配置。然后在”Build Variants”選項(xiàng)中下拉選擇Unit Tests就可以運(yùn)行了。

在Gradle的Task列表中選擇testDebug運(yùn)行(第一次運(yùn)行需要的時(shí)間很久)。

?

?

3.編寫第一個(gè)例子

創(chuàng)建一個(gè)Activity,顯示一個(gè)登陸界面。

<?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">

?

??? <Button

??????? android:id="@+id/login"

??????? android:text="Login"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"/>

?

</LinearLayout>

?

?

當(dāng)用戶點(diǎn)擊登陸按鈕就跳轉(zhuǎn)到歡迎界面

public class WelcomeActivity extends Activity {

?

??? @Override

??? protected void onCreate(Bundle savedInstanceState) {

??????? super.onCreate(savedInstanceState);

??????? setContentView(R.layout.welcome_activity);

?

??????? final View button = findViewById(R.id.login);

??????? button.setOnClickListener(new View.OnClickListener() {

??????????? @Override

??????????? public void onClick(View view) {

??????????????? startActivity(new Intent(WelcomeActivity.this, LoginActivity.class));

??????????? }

??????? });

??? }

}

?

?

我們希望測(cè)試的是,當(dāng)用戶點(diǎn)擊登陸按鈕后,我們啟動(dòng)了正常的intent。由于Robolectric只是一個(gè)模擬的單元測(cè)試框架,LoginActivity并不會(huì)真正的啟動(dòng),但是我們可以檢查是否準(zhǔn)確的發(fā)出了WelcomActivity的intent。

@RunWith(RobolectricTestRunner.class)

public class WelcomeActivityTest {

?

??? @Test

??? public void clickingLogin_shouldStartLoginActivity() {

??????? WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);

??????? activity.findViewById(R.id.login).performClick();

?

??????? Intent expectedIntent = new Intent(activity, WelcomeActivity.class);

??????? assertThat(Shadows.shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent);

??? }

}

?

?

4.配置Robolectric

有幾種方法來(lái)配置Robolectric的運(yùn)行時(shí)行為。

Config注解

最簡(jiǎn)單的配置Robolectric的方法就是使用@Config注解。這個(gè)注解可以作用于類和方法,如果在類和方法都同時(shí)配置了同一個(gè)屬性,方法的配置會(huì)覆蓋類的配置。

基類的注解對(duì)于所有的子類都是有效的,所以如果你要在很多的類使用同一個(gè)配置,可以創(chuàng)建一個(gè)基類,然后把@Config注解移到基類中。

下面的例子展示了更多的配置內(nèi)容。

配置SDK版本

Robolectric會(huì)使用你在manifest中指定的targetSdkVersion版本來(lái)運(yùn)行測(cè)試代碼。如果你想測(cè)試在其它指定版本的表現(xiàn),可以通過(guò)下面的修改這個(gè)SDK版本:

@Config(sdk = Build.VERSION_CODES.JELLY_BEAN)

public classSandwichTest {

? @Config(sdk = Build.VERSION_CODES.KITKAT)

? public void getSandwich_shouldReturnHamSandwich() {

? }

}

?

配置Application類

Robolectric會(huì)根據(jù)manifest的配置自動(dòng)幫你創(chuàng)建一個(gè)Application類,如果你希望提供一個(gè)自己實(shí)現(xiàn)的類,可以這樣設(shè)置:

@Config(application = CustomApplication.class)

public class SandwichTest {

?

??? @Config(application = CustomApplicationOverride.class)

??? public void getSandwich_shouldReturnHamSandwich() {

??? }

}

?

配置Resource路徑

Robolectric為Gradle和Maven提供了默認(rèn)的設(shè)置,但是也允許你修改這些資源的路徑,包括manifest, resource目錄,assets目錄。如果你有一個(gè)自定義的生成腳本這會(huì)非常有用。示例:

@Config(manifest = "some/build/path/AndroidManifest.xml")

public class SandwichTest {

?

??? @Config(manifest = "other/build/path/AndroidManifest.xml")

??? public void getSandwich_shouldReturnHamSandwich() {

??? }

}

默認(rèn)的,Robolectric會(huì)假定你的resouces和assets都是放在目錄res和assets中。這些目錄都是配置成相對(duì)于manifest的相對(duì)目錄。你也可以在@Config注解中添加resourcesDir和assetsDir選項(xiàng)來(lái)修改資源路徑。

使用屬性配置文件

任何在@Config注解可以配置的屬性也可以寫成一個(gè)全局的properties文件。創(chuàng)建一個(gè)文件robolectric.properties,確認(rèn)在classpath中可以找到。例如:

sdk=18

manifest=some/build/path/AndroidManifest.xml

shadows=my.package.ShadowFoo,my.package.ShadowBar

?

系統(tǒng)屬性

還有以下的選項(xiàng)可以在properties中配置

robolectric.offline設(shè)置true后為離線狀態(tài),不會(huì)在運(yùn)行時(shí)去下載jar文件

robolectric.dependency.idr在離線狀態(tài),提供一個(gè)運(yùn)行時(shí)查找依賴文件的目錄

robolectric.logging.enable設(shè)為true后打開(kāi)debug日志

?

5.控制Activity的生命周期

在Robolectric 2.2版本以前,創(chuàng)建Activity多數(shù)都是直接調(diào)用構(gòu)造函數(shù)(new MyActivity())然后手動(dòng)調(diào)用生命周期的函數(shù)如onCreate()。還有廣泛使用的ShadowActivity(例如ShadowActivity.callOnCreate()),這就是現(xiàn)在ActivityController的設(shè)計(jì)原型。

為了解決調(diào)用的混亂,Robolectric API提供了ActivityController,用它來(lái)簡(jiǎn)化創(chuàng)建Activity還有控制Activity的生命周期。

不需要調(diào)用onCreate這些函數(shù),ActivityController確保了Activity生命周期的一致性,這包括把Activity顯示到Window,還提供了如LayoutInflater這些系統(tǒng)服務(wù)。

具體怎么做

你不要直接new一個(gè)ActivityController,使用Robolectric.buildActivity()來(lái)獲得一個(gè)實(shí)例。對(duì)于大多數(shù)基本的測(cè)試用命 ,你只需要一行代碼就能初始化一個(gè)Activity:

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().get();

這會(huì)創(chuàng)建一個(gè)MyAwesomeActivity,并且已經(jīng)調(diào)用了onCreate()。

想去檢查一些在onCreate()和onResume()之間發(fā)生的事件,這很簡(jiǎn)單:

ActivityController controller = Robolectric.buildActivity(MyAwesomeActivity.class).create().start();

Activity activity = controller.get();

// assert that something hasn't happened

activityController.resume();

// assert it happened!

還有類似的函數(shù)包括start(), pause(), stop()和destroy()。所以如果你想測(cè)試一個(gè)完整的創(chuàng)建周期:

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().start().resume().visible().get();

模擬使用intent來(lái)啟動(dòng)一個(gè)Activity:

Intent intent = new Intent(Intent.ACTION_VIEW);

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).withIntent(intent).create().get();

還有保存狀態(tài)等調(diào)用:

Bundle savedInstanceState = new Bundle();

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class)

??? .create()

??? .restoreInstanceState(savedInstanceState)

??? .get();

需要更多關(guān)于ActivityController的功能可以查看Java Doc文檔。

?

奇怪!調(diào)用visible() 有用嗎?

實(shí)際上一個(gè)Android app, 一個(gè)Activity的視圖會(huì)在onCreate()被調(diào)用后一段時(shí)間才添加到Window上的,在此之前,Activity的控件是不可見(jiàn)的,這意味著你沒(méi)法處理任何的點(diǎn)擊交互。Activity的控件樹在onPostResume()被調(diào)用后才添加到設(shè)備或者模擬器的Window上。與其在猜測(cè)不確定的時(shí)候點(diǎn)Activity會(huì)被顯示,Robolectric給單元測(cè)試的開(kāi)發(fā)者提供了直接控制Activity顯示的功能。

然而我們什么時(shí)候調(diào)用它呢?就是當(dāng)你在Activity內(nèi)部需要操作控件的交互時(shí),調(diào)用類似于Robolectric.clickOn()需要視圖是可見(jiàn)的。注意調(diào)用順序是先onCreate()再調(diào)用visible()。

6.使用額外的子模塊

為了減少測(cè)試時(shí)需要依賴的數(shù)量,Robolectric對(duì)Android的模擬也拆分為很多附加的子模塊,只有在Android SDK的基本包里面的類才包含在Robolectric的主模塊中。其它的如appcompat或者support 依賴庫(kù)是作為附加子模擬提供的。下面的表格中列出了可用的附加包:

SDK包

Robolectric附加包

com.android.support.support-v4

org.robolectric:shadows-support-v4

com.android.support.multidex

org.robolectric:shadows-multidex

com.google.android.gms:play-services

org.robolectric:shadows-play-services

com.google.android.maps:maps

org.robolectric:shadows-maps

org.apache.httpcomponents:httpclient

org.robolectric:shadows-httpclient

注意附加包的功能需要在build.gradle或者pom.xml里添加后才能使用。

?

?

參考:http://robolectric.org/getting-started/

?

?

?

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的Robolectric测试框架使用文档的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。