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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单元测试汇总

發布時間:2025/5/22 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单元测试汇总 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:https://blog.csdn.net/u012933335/rss/list

[原]Android單測調研篇

1. 為什么做單測

單測的好處

減少bug 快速定位bug 提高代碼質量 減少調試時間 放心重構

不得不寫單測的原因

在成為大牛的路上,單測是必備技能 單測可以給你信心 保住面子

難處

難于堅持,在快速迭代開發過程中,可供寫單測的時間過少

擴展

TDD(Test Drive Develop):測試驅動開發,是一種非常高效的開發方式

2. 測試框架

2.1 概述

junit4.12 (單測框架)mockito1.9.5(mock工具)robolectric3.1.2 (模擬Android虛擬機)

2.2 junit4.12

Junit測試是程序員測試,即所謂白盒測試,因為程序員知道被測試的軟件如何(How)完成功能和完成什么樣(What)的功能。Junit是一套框架,繼承TestCase類,就可以用Junit進行自動測試了。

示例代碼:

@Before: 執行單測之前的初始化操作。

@After:單測完成后收尾工作。

@Beforepublic void setUp() throws Exception {}@Afterpublic void tearDown() throws Exception {}

assume: 用于判斷測試用例的入參是否有業務含義的工具,如果入參不符合預期時會拋出

assumptionViolatedException、assumeTrue/assumeFalse、 assumeNotNull、 assumeThat、 assumeNoException

@RunWith(Theories.class) public class AssumeTest {@DataPointspublic static String[] names = {"LiLei", "HanMeiMei"};@DataPointspublic static int[] ages = {10, -2, 12};@Theorypublic void printAge(String name, int age){Assume.assumeTrue(age > 0);System.out.println(String.format("%s's Name is %s.", name, age));} }

assert?:用于常用的測試結果驗證

AssertTrue、AssertFalse:結果的true、false。

AssertThat:使用Matcher做自定義的校驗。

AssertEquals、AssertNotEquals:判斷兩個對象是否相等。

AssertNull、AssertNotNull:判斷對象是否為空。

AssertSame:判斷兩個對象是否為同一個,不同于equals這里是使用“==”判斷。

AssertArrayEquals:判斷兩個數組是否相等。

@Testpublic void sum() throws Exception {assertEquals(mCalculator.sum(3, 4), 7);}

verify?: 主要用于驗證方法是否執行

@Testpublic void testVerify() {List mockedList = mock(List.class);mockedList.add("one");mockedList.clear();mockedList.add("3");// verificationverify(mockedList).add("one");verify(mockedList).clear();}

其他高級用法:

@Test(timeout = 1000): 限時操作,若超過制定時間,強制停止

@Test(expected = ArithmeticException.class): 預測拋出指定異常

2.3 mockito1.9.5

創建mock對象不能對final,Anonymous ,primitive類進行mock。?
用法:

when… thenRetrun; when… thenThrow

doNothing().doRetrun();

doNothing.doThrow()

anyInt、anyString、anyMap…..(參數匹配器)

@Testpublic void argumentMatcherTest2(){Map

2.4 robolectric3.1.2

實現一套JVM能運行的Android代碼,從而做到脫離Android環境進行測試

1.測試跳轉

/*** Activity跳轉測試*/@Testpublic void testStartActivity() {//按鈕點擊后跳轉到下一個ActivityforwardBtn.performClick();Intent expectedIntent = new Intent(sampleActivity, LoginActivity.class);Intent actualIntent = ShadowApplication.getInstance().getNextStartedActivity();assertEquals(expectedIntent.getComponent(), actualIntent.getComponent());}

2.模擬activity

sampleActivity = Robolectric.setupActivity(SampleActivity.class);
  • UI測試:
  • /*** Toast的測試*/@Testpublic void testToast() {//點擊按鈕,出現吐司toastBtn.performClick();assertEquals(ShadowToast.getTextOfLatestToast(), "we love UT");}/*** Dialog的測試*/@Testpublic void testDialog() {//點擊按鈕,出現對話框dialogBtn.performClick();AlertDialog latestAlertDialog = ShadowAlertDialog.getLatestAlertDialog();assertNotNull(latestAlertDialog);}/*** 測試控件狀態*/@Testpublic void testViewState() {CheckBox checkBox = (CheckBox) sampleActivity.findViewById(R.id.checkbox);Button inverseBtn = (Button) sampleActivity.findViewById(R.id.btn_inverse);assertTrue(inverseBtn.isEnabled());checkBox.setChecked(true);//點擊按鈕,CheckBox反選inverseBtn.performClick();assertTrue(!checkBox.isChecked());inverseBtn.performClick();assertTrue(checkBox.isChecked());}/*** 資源文件訪問測試*/@Testpublic void testResources() {Application application = RuntimeEnvironment.application;String appName = application.getString(R.string.app_name);String activityTitle = application.getString(R.string.title_activity_simple);assertEquals("LoveUT", appName);assertEquals("SimpleActivity", activityTitle);}/*** 測試廣播*/@Testpublic void testBoradcast() {ShadowApplication shadowApplication = ShadowApplication.getInstance();String action = "com.geniusmart.loveut.login";Intent intent = new Intent(action);intent.putExtra("EXTRA_USERNAME", "geniusmart");//測試是否注冊廣播接收者assertTrue(shadowApplication.hasReceiverForIntent(intent));//以下測試廣播接受者的處理邏輯是否正確MyReceiver myReceiver = new MyReceiver();myReceiver.onReceive(RuntimeEnvironment.application, intent);SharedPreferences preferences = RuntimeEnvironment.application.getSharedPreferences("account", Context.MODE_PRIVATE);assertEquals("geniusmart", preferences.getString("USERNAME", ""));}/*** 測試Fragment*/@Testpublic void testFragment() {SampleFragment sampleFragment = new SampleFragment();//此api可以主動添加Fragment到Activity中,因此會觸發Fragment的onCreateView()SupportFragmentTestUtil.startFragment(sampleFragment);assertNotNull(sampleFragment.getView());}4.登錄場景測試@Testpublic void loginSuccess() {emailView.setText("zhangzhan35@gmail.com");passwordView.setText("123");button.performClick();ShadowApplication application = ShadowApplication.getInstance();assertThat("Next activity has started", application.getNextStartedActivity(), is(notNullValue()));}@Testpublic void loginWithEmptyUsernameAndPassword() {button.performClick();ShadowApplication application = ShadowApplication.getInstance();assertThat("Next activity should not started", application.getNextStartedActivity(), is(nullValue()));assertThat("Show error for Email field ", emailView.getError(), is(notNullValue()));assertThat("Show error for Password field ", passwordView.getError(), is(notNullValue()));assertEquals(emailView.getError().toString(), RuntimeEnvironment.application.getString(R.string.error_field_required));}@Testpublic void loginFailure() {emailView.setText("invalid@email");passwordView.setText("invalidpassword");button.performClick();ShadowApplication application = ShadowApplication.getInstance();assertThat("Next activity should not started", application.getNextStartedActivity(), is(nullValue()));assertThat("Show error for Email field ", emailView.getError(), is(notNullValue()));assertThat("Show error for Password field ", passwordView.getError(), is(notNullValue()));}

    更多場景還需探索。。。

    與espresso的對比

    Google 官方提供的一個易于測試 Android UI 的開源框架 , 于2013年10月推出它的 released 版本 , 目前最新版本已更新到2.x . 并且在AndroidStudio 2.2 預覽版中已經默認集成該測試庫 。

    ViewMatchers - 在當前View層級去匹配指定的View .

    ViewActions - 執行Views的某些行為,如點擊事件 .

    ViewAssertions - 檢查Views的某些狀態,如是否顯示 .

    @RunWith(AndroidJUnit4.class) public class LoginUITest {@Rulepublic ActivityTestRule rule=new ActivityTestRule(LogingActivity.class,true);@Testpublic void login(){//loginonView(withId(R.id.userName)).perform(typeText("Jack"),closeSoftKeyboard());onView(withId(R.id.password)).perform(typeText("1234"),closeSoftKeyboard());onView(withText("登錄")).perform(click());//verifyonView(withId(R.id.content)).check(matches(isDisplayed()));} }

    espresso更偏向于自動化測試,集成后執行單元測試需要跑在Android手機上,其有個高級功能,根據你的點擊軌跡,自動生成自動測試代碼。

    3. 覆蓋率

    jacoco:Android Studio自帶的生成單元測試覆蓋率報告的工具。

    行覆蓋率:度量被測程序的每行代碼是否被執行,判斷標準行中是否至少有一個指令被執行。

    類覆蓋率:度量計算class類文件是否被執行。

    分支覆蓋率:度量if和switch語句的分支覆蓋情況,計算一個方法里面的

    總分支數,確定執行和不執行的 分支數量。

    方法覆蓋率:度量被測程序的方法執行情況,是否執行取決于方法中是否有至少一個指令被執行。

    指令覆蓋:計數單元是單個java二進制代碼指令,指令覆蓋率提供了代碼是否被執行的信息,度量完全 獨立源碼格式。

    圈復雜度:在(線性)組合中,計算在一個方法里面所有可能路徑的最小數目,缺失的復雜度同樣表示測試案例沒有完全覆蓋到這個模塊。

    參考自:http://blog.csdn.net/tmq1225/article/details/52221187

    集成配置:

    apply plugin: 'jacoco' android {buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug{testCoverageEnabled true}} } jacoco {toolVersion = "0.7.5.201505241946" }

    jacoco覆蓋率報告分為兩種:

    1. 只生成java層代碼覆蓋率報告2. 在運行app期間執行的覆蓋率報告 task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") {println("=========jacocoTestReport start");group = "Reporting"description = "Generate Jacoco coverage reports"classDirectories = fileTree(dir: "${project.buildDir}/intermediates/classes/debug",excludes: ['**/R.class','**/R$*.class','**/*$ViewInjector*.*','**/BuildConfig.*','**/Manifest*.*'])println("path==========>>" + "${project.buildDir}/intermediates/classes/debug")def coverageSourceDirs = "${project.projectDir}/src/main/java"println("coverageSourceDirs==========>>" + coverageSourceDirs)additionalSourceDirs = files(coverageSourceDirs)sourceDirectories = files(coverageSourceDirs)executionData = fileTree(dir: project.projectDir, includes:['**/*.exec', '**/*.ec'])reports {xml.enabled = truehtml.enabled = true} }task jacocoAndroidTestReport(type:JacocoReport,dependsOn:"connectedAndroidTest"){group = "Reporting"description = "Generate Jacoco coverage reports after running tests."reports{xml.enabled = truehtml.enabled = truecsv.enabled = false}classDirectories = fileTree(dir : "$buildDir/intermediates/classes/debug",excludes : ['**/*Test.class','**/R.class','**/R$*.class','**/BuildConfig.*','**/Manifest*.*'])def coverageSourceDirs = ['src/main/java']additionalSourceDirs = files(coverageSourceDirs)sourceDirectories = files(coverageSourceDirs)additionalClassDirs = files(coverageSourceDirs)executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec") }

    結果展示

    總結

    單元測試的一些原則

  • 在最低的功能/參數上驗證程序的正確性
  • 單元測試過后,機器狀態保持不變。(數據庫,sp等)
  • 單元測試應該產生可重復、一致的結果。(盡量減少一切隨機)
  • 獨立性,單元測試的運行/通過/失敗不依賴于別的測試,可以人為構造數據,以保持單元測試的獨立性
  • 單元測試應該覆蓋所有代碼路徑,包括錯誤處理路徑,為了保證單元測試的代碼覆蓋率,單元測試必須測試公開的和私有的函數/方法
  • 單元測試必須和產品代碼一起保存和維護。
  • 單元測試要快(一個測試運行時間是幾秒鐘,而不是幾分鐘)
  • 作者:u012933335 發表于 2018/02/24 09:51:48?原文鏈接?https://blog.csdn.net/u012933335/article/details/79358869 閱讀:15
    ?
    [原]Android單測踩坑篇

    在開始寫單測之前,已經調研了很久Android單測的框架以及demo,正好換了一個新的項目組,就從頭開始將單測框架應用到開發過程中,后續也方便可以使用TDD。

    調研的框架:junit,mockito, roboletric,espresso,jacoco(覆蓋率報告)

    具體場景:網絡請求,todomvp的單測方式,UI測試等

    理想永遠是美好的,擼起袖子開始干的時候,就會發現還有很多崎嶇需要去踏平。

    首先,我放棄了espresso(雖然是google官方出的測試框架),主要原因是espresso依賴真機或模擬器。我相信大部分應用應該都有模擬器判斷,在模擬器環境下禁止啟動app,為了寫單測,還得改代碼,很難受;另外多數開發團隊應該都是持續集成,跑espresso,還需要有一臺手機常年插在構建機上,很麻煩。這并不是說espresso毫無用處,espresso對于Android框架支持非常完善,基本上所有UI的測試都可以實現。另外,espresso還有一個非常強大的功能,適合測試人員手工測試:錄制測試過程,自動生成測試代碼。比方說:你進入app后,按照正確測試流程點擊一遍后,保存下來,下一次開發人員有了些許改動,你只需要運行一次之前自動生成的測試代碼,應用便會按照之前的流程進行測試,如出現異常,則測試不通過!非常強大(據團隊的IOS工程師說,ios也有一樣的測試框架,個人覺得測試人員可以考慮一下這個)。

    所以最初我采用的Android單測框架就是:junit + mockito + roboletric + jacoco

    junit和mockito就不要多講了,都是java單元測試最基本的框架。在說roboletric之前,得先說一下powerMock,mockito無法mock static方法,而powermock則解決了這個問題。所以powermock和mockito配合使用,基本就可以覆蓋絕大部分情況。不過由于powermock和mockito是兩個團隊實現的,經常出現版本不兼容的情況,建議直接使用powermock內部引用的mockito,這樣就不會沖突了。?
    roboletric簡單來說就是實現了一套JVM能運行Android代碼的框架,從而做到脫離Android環境進行測試。powermock和roboletric在版本上有些不太兼容,roboletric的github的wiki上有官方出的powermock和roboletric的集成方式:

    貼上地址:

    https://github.com/robolectric/robolectric/wiki/Using-PowerMock

    在使用框架時,注意對應版本。頁面中的第一句話:

    NOTE: PowerMock integration is broken in Robolectric 3.1 and 3.2, but fixed in 3.3.

    我使用的完整配置如下:

    apply plugin: 'com.android.library' apply plugin: 'android-apt' apply plugin: 'com.jakewharton.butterknife' apply plugin: 'jacoco'android {buildTypes {debug {testCoverageEnabled true } } } /** * 生成jacoco測試報告 */ task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") { println("=========jacocoTestReport start"); group = "Reporting" description = "Generate Jacoco coverage reports" classDirectories = fileTree( dir: "${project.buildDir}/intermediates/classes/debug", excludes: ['**/R.class', '**/R$*.class', '**/*$ViewInjector*.*', '**/BuildConfig.*', '**/Manifest*.*'] ) println("path==========>>" + "${project.buildDir}/intermediates/classes/debug") def coverageSourceDirs = "${project.projectDir}/src/main/java" println("coverageSourceDirs==========>>" + coverageSourceDirs) additionalSourceDirs = files(coverageSourceDirs) sourceDirectories = files(coverageSourceDirs) println("executionData==========>>" + "$buildDir/jacoco/testDebugUnitTest.exec") executionData = files("$buildDir/jacoco/testDebugUnitTest.exec") reports { xml.enabled = true html.enabled = true } } jacoco { toolVersion = "0.7.1.201405082137" } dependencies { compile files('libs/fastjson-1.1.51.android.jar') compile 'com.android.support:appcompat-v7:24.2.1' compile 'com.cmbchina.ccd.pluto:CMBCore:1.0.0-SNAPSHOT@aar' compile 'com.jakewharton:butterknife:8.4.0' apt 'com.jakewharton:butterknife-compiler:8.4.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' testCompile 'junit:junit:4.12' testCompile 'org.robolectric:robolectric:3.6.1' testCompile 'org.powermock:powermock-api-mockito:1.6.6' testCompile 'org.powermock:powermock-module-junit4:1.6.6' testCompile 'org.powermock:powermock-module-junit4-rule:1.6.6' testCompile 'org.powermock:powermock-classloading-xstream:1.6.6' }

    原本使用powermock的版本是1.7.X,發現使用的過程中各種報錯,還是使用了官方的1.6.6版本,不知道這兩個團隊什么時候兼容能做的很完善。

    附上使用BaseTest:

    @RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class , sdk = 21) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "org.json.*", "sun.security.*", "javax.net.*"}) @PrepareForTest({CPSNetUtils.class, Common.class}) public abstract class CPSBaseTest { @Rule public PowerMockRule rule = new PowerMockRule(); @Before public void setUp() { // 將log日志打印到控制臺 ShadowLog.stream = System.out; initLog(); //mockito 初始化 MockitoAnnotations.initMocks(this); //mock靜態方法所在類 PowerMockito.mockStatic(CPSNetUtils.class, Common.class); Common.application = getApplication(); new FoundationBuildConfig().init(); initNetMock(); mockCommon(); } }

    @Config(constants = BuildConfig.class , sdk = 21):原本想使用23的sdk版本,會有不兼容問題。

    @PowerMockIgnore({“org.mockito.“, “org.robolectric.“, “android.“, “org.json.“, “sun.security.“, “javax.net.“}):根據我的理解:powermock類加載器忽略以上類的加載。

    @PrepareForTest({CPSNetUtils.class, Common.class}):想mock static的方法,必須加上此注解。

    基本配置如上,若上述配置都沒問題了,就可以真正開始寫單測了。目前Android端的框架使用的是google推薦的mvp框架,優缺點,網上有很多文章,就不在贅述。github地址如下:

    https://github.com/googlesamples/android-architecture/tree/todo-mvp/

    不可否認的一點,使用mvp框架后單測實現會簡單很多,極大程度減少了對view的測試。貼上一段業務測試代碼:

    public class FeedbackPresenterTest extends CPSBaseTest { @InjectMocks private FeedbackPresenter mPresenter; @Mock private FeedbackContract.View mView; @Before public void setUp() { super.setUp(); mPresenter = new FeedbackPresenter(); mPresenter.attachView(mView); } @Test public void feedbackFailTest() { when(mView.getFeedback()).thenReturn(""); when(mView.getContact()).thenReturn("15012341234"); mPresenter.uploadFeedback(); verify(mView).showToastInBottom("反饋信息不能為空!"); } @Test @Config(shadows = {ShadowCommon.class}) public void feedbackSuccessTest() { when(mView.getFeedback()).thenReturn("閃退!"); when(mView.getContact()).thenReturn("15012341234"); mPresenter.uploadFeedback(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } verify(mView).showToastInBottom("操作成功"); } }

    細心的讀者會發現在feedbackSuccessTest測試方法中,我開了個線程睡了半秒鐘,這時候就要說到網絡請求的單元測試了。網絡交互是客戶端最頻繁的場景,而網絡的不穩定,會導致客戶端出現很多難以預知的情況,崩潰,閃退都有可能發生。所以對于網絡請求的單測是重中之重。我使用的網絡庫是okhttp,而okhttp有一個很強大的功能:Interceptor。interceptor可以攔截網絡請求,可以處理完后繼續發送,也可以直接直接返回。廢話不多說,上代碼:

    public class MockInterceptor implements CMBHttpInterceptor { @Override public Response intercept(Chain chain) throws IOException { Response response; String json = ""; if (chain.request().url().toString().equals(FoundationHostConst.LOGIN)) { // login json = "{\"respMsg\": \"用戶名或密碼錯誤[CD1105]\",\"respCode\": \"1001\"}"; } else if (chain.request().url().toString().equals(FoundationHostConst.REGISTER)) { //register json = "{\n" + " \"data\": {\n" + " \"sessionId\": \"c742f1a3915a445d997735413ca12a78\",\n" + " \"userId\": \"7ac3960080e94be38c79ac83808b579a\",\n" + " \"channel\": \"MOB\"\n" + " },\n" + " \"respMsg\": \"操作成功\",\n" + " \"respCode\": \"1000\"\n" + " }"; } else if (chain.request().url().toString().equals(FoundationHostConst.FEEDBACK)) { //feedback json = "{\n" + " \"respMsg\": \"操作成功\",\n" + " \"respCode\": \"1000\"\n" + " }"; } response = setResponse(chain, json); return response; } /** * 設置指定返回報文 * * @param chain * @param response * @return */ private Response setResponse(Chain chain, String response) { return new Response.Builder() .code(200) .addHeader("Content-Type", "multipart/form-data") .body(ResponseBody.create(MediaType.parse("multipart/form-data"), response)) .message(response) .request(chain.request()) .protocol(Protocol.HTTP_2) .build(); } }

    當然也可以模擬異常返回,404什么的都可以。另外okhttp使用的是建造者模式,客戶端網絡請求OkHttpClient都是一致的,故可以使用類似代碼直接mock返回:

    CMBHttpClient.Builder builder CMBHttpUtils.getDefaultClientBuilder().addInterceptor(new CPSInterceptor()).addInterceptor(new CMBLogInterceptor()).addInterceptor(new MockInterceptor()); PowerMockito.when(CPSNetUtils.getCPSDefaultBuilder()).thenReturn(builder);

    單測寫完,總得看到點數據報告吧。這時候就需要覆蓋率報告了。Android studio自帶了jacoco 插件生成覆蓋率報告。?
    jacoco數據含義:

    行覆蓋率:度量被測程序的每行代碼是否被執行,判斷標準行中是否至少有一個指令被執行。

    類覆蓋率:度量計算class類文件是否被執行。

    分支覆蓋率:度量if和switch語句的分支覆蓋情況,計算一個方法里面的總分支數,確定執行和不執行的分支數量。

    方法覆蓋率:度量被測程序的方法執行情況,是否執行取決于方法中是否有至少一個指令被執行。

    指令覆蓋:計數單元是單個java二進制代碼指令,指令覆蓋率提供了代碼是否被執行的信息,度量完全 獨立源碼格式。

    圈復雜度:在(線性)組合中,計算在一個方法里面所有可能路徑的最小數目,缺失的復雜度同樣表示測試案例沒有完全覆蓋到這個模塊。

    參考自:http://blog.csdn.net/tmq1225/article/details/52221187

    jacoco的覆蓋率報告分為兩種:

    1. 只生成java層代碼覆蓋率報告2. 在運行app期間執行的覆蓋率報告

    方法也不盡相同。生成java層代碼的任務在前面代碼中已經貼出。

    生成運行app期間執行的覆蓋率報告代碼如下:

    //task jacocoAndroidTestReport(type:JacocoReport,dependsOn:"connectedAndroidTest"){group = "Reporting"description = "Generate Jacoco coverage reports after running tests."reports{xml.enabled = true html.enabled = true csv.enabled = false } classDirectories = fileTree( dir : "$buildDir/intermediates/classes/debug", excludes : [ '**/*Test.class', '**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*' ] ) def coverageSourceDirs = ['src/main/java'] additionalSourceDirs = files(coverageSourceDirs) sourceDirectories = files(coverageSourceDirs) additionalClassDirs = files(coverageSourceDirs) executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec") }

    以上代碼并未測試過,點擊執行測試后,會啟動app,并在會生成.ec文件,通過解析.ec文件, 可以生成覆蓋率報告。因為前面放棄esspreso時就說過放棄真機測試,所以此方法也未使用。?
    注意事項:testCoverageEnabled 得設置成true,否則無法生成覆蓋率報告。

    buildTypes {debug {testCoverageEnabled true} }

    另外,中間遇到一個大坑,被坑了很久。就是jacoco和roboletric也有版本不兼容的問題。。。使用最新的jacoco的版本,發現生成的覆蓋率報告始終為0

    在stackoverflow中找了查了很久,最后在一個帖子里看到,在jacoco 0.7.3以上的版本使用roboletric就始終為0,嘗試了多個版本,發現 0.7.1.201405082137 是OK的。千萬不要隨便升級版本,否則會出現異想不到的問題。。

    好了,下面就看一下覆蓋率報告:

    后續會接入jenkins,等踩完坑,再補一篇文章。

    作者:u012933335 發表于 2018/02/07 18:32:37?原文鏈接?https://blog.csdn.net/u012933335/article/details/79283201 閱讀:86

    轉載于:https://www.cnblogs.com/weizhxa/p/9365595.html

    總結

    以上是生活随笔為你收集整理的单元测试汇总的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。