国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android下單元測(cè)試實(shí)踐——測(cè)試框架簡(jiǎn)介

這篇具有很好參考價(jià)值的文章主要介紹了Android下單元測(cè)試實(shí)踐——測(cè)試框架簡(jiǎn)介。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

android單元測(cè)試private變量,軟件測(cè)試,單元測(cè)試,軟件測(cè)試,功能測(cè)試,自動(dòng)化測(cè)試,程序人生,職場(chǎng)和發(fā)展

前言

測(cè)試代碼的寫法可以歸納為三部分

第一部分: 準(zhǔn)備測(cè)試數(shù)據(jù)和定義mock行為

第二部分: 調(diào)用真實(shí)的函數(shù)

第三部分: 調(diào)用驗(yàn)證函數(shù)進(jìn)行結(jié)果的驗(yàn)證

Junit4

在模塊的test路徑下編寫測(cè)試案例。在類中使用@Test注解,就可以告訴Junit這個(gè)方法是測(cè)試方式。同時(shí)使用assert*方法,可以調(diào)用Junit進(jìn)行結(jié)果的驗(yàn)證。

@Test
public void test() {
    assertEquals("abc", getActual());
}

Junit常用注解

除了@Test注解,還有以下常見的注解可供使用

android單元測(cè)試private變量,軟件測(cè)試,單元測(cè)試,軟件測(cè)試,功能測(cè)試,自動(dòng)化測(cè)試,程序人生,職場(chǎng)和發(fā)展

可選使用Junit的Rule簡(jiǎn)化代碼

和Junit的@Before和@After分別作用于每一個(gè)單元測(cè)試案例的開始和結(jié)束類似,@Rule注解提供了同樣的能力,但有一個(gè)好處就是執(zhí)行前,執(zhí)行單元測(cè)試和執(zhí)行后在同一個(gè)方法中,包含在同一個(gè)上下文中,這能讓我們更加靈活的處理單元測(cè)試。

使用起來(lái)也比較簡(jiǎn)單:

第一步:實(shí)現(xiàn)TestRule接口

public class MethodNameExample implements TestRule {
 
    @Override
 
    public Statement apply(Statement base, Description description) {
 
        //想要在測(cè)試方法運(yùn)行之前做一些事情,就在base.evaluate()之前做
 
        String className = description.getClassName();
 
        String methodName = description.getMethodName();
 
        base.evaluate();  //這其實(shí)就是運(yùn)行測(cè)試方法
 
        //想要在測(cè)試方法運(yùn)行之后做一些事情,就在base.evaluate()之后做
 
        System.out.println("Class name: "+className +", method name: "+methodName);
 
        return base;
 
    }
 
}

第二步:在Test類中使用。加上@Rule注解即可

@Rule
public MethodNameExample methodNameExample = new MethodNameExample();
使用Parameterized特性減少重復(fù)測(cè)試用例(Junit5自帶,Junit4需額外引入依賴)

根據(jù)不同的輸入,待測(cè)試函數(shù)會(huì)有不同的輸出結(jié)果,那么我們就需要針對(duì)每一類的輸入,編寫一個(gè)測(cè)試用例,這樣才能覆蓋待測(cè)函數(shù)的所有邏輯分支。(寫多少個(gè)測(cè)試用例能夠覆蓋全所有的邏輯分支可稱之為待測(cè)函數(shù)的圈復(fù)雜度).

使用Junit4提供的Parameterized Tests特性,可以幫助我們減少用例編寫的代碼,使測(cè)試類更清晰簡(jiǎn)單,而且數(shù)據(jù)可以從CSV文件導(dǎo)入。以下提供一個(gè)例子?(?官方例子見參考資料?[11]?)?:

第一步:引入依賴

testImplementation(rootProject.ext.dependencies.jupiter)

第二步:測(cè)試類中添加注解

@RunWith(Parameterized.class)
 
public class BioTest {
 
}

第三步:可以定義實(shí)例變量,明確輸入和輸出。比如這里,我們定義了2個(gè)變量,一個(gè)是預(yù)期的輸出結(jié)果,一個(gè)是輸入的參數(shù)。

private boolean expectedResult;
private String inputTime;

第四步:定義構(gòu)造函數(shù),在構(gòu)造函數(shù)中對(duì)變量賦值

public BioPayProviderTest2(boolean expectedResult, String time) {
    this.expectedResult = expectedResult;
    this.time = time;
}

第五步:定義數(shù)據(jù)集,使用注解標(biāo)注,返回一個(gè)數(shù)組,數(shù)組代表的就是Junit4需要提供給構(gòu)造函數(shù)進(jìn)行實(shí)例化的數(shù)據(jù)集。

@Parameterized.Parameters
public static Collection<Object[]> data() {
    return Arrays.asList(new Object[][]{
        {true, null},
        {false, System.currentTimeMillis() + ":"},
        {true, (System.currentTimeMillis() - 73 * 3600) + ":"}
    });
}

第六步:編寫測(cè)試用例。對(duì)于以下的測(cè)試用例,Junit4會(huì)使用第五步的數(shù)據(jù)進(jìn)行填充,執(zhí)行3次。

@Test
public void test() throws Exception {
    boolean ret = needShowDialog(time, mockWalletId);
    Assert.assertEquals(expectedResult, ret);
}

Mockito

Mockito是目前使用比較廣泛的Mock框架,他可以根據(jù)需要mock出虛假的對(duì)象,在測(cè)試環(huán)境中,可以用來(lái)替換掉真實(shí)的最像,達(dá)到兩大目的:

  1. 驗(yàn)證這個(gè)對(duì)象的某些方法的調(diào)用情況,調(diào)用了多少次,參數(shù)是什么等等
  2. 指定這個(gè)對(duì)象的某些方法的行為,返回特定的值,或者是執(zhí)行特定的動(dòng)作

使用Mockito mock對(duì)象的某些方法的行為

// 使用mock函數(shù)即可模擬一個(gè)對(duì)象,這個(gè)對(duì)象的實(shí)例變量均為默認(rèn)值
BioGuidePresenter presenter = Mockito.mock(BioGuidePresenter.class);
 
// 設(shè)定這個(gè)mock對(duì)象被調(diào)用某一方法時(shí),應(yīng)該返回的結(jié)果
Mockito.when(presenter.checkIsEnrolled(1)).thenReturn(true);

使用Mockito Spy對(duì)象

// 使用spy函數(shù)即可模擬一個(gè)對(duì)象,這個(gè)對(duì)象的實(shí)例變量均為默認(rèn)值
BioGuidePresenter presenter = Mockito.spy(BioGuidePresenter.class);
 
// 設(shè)定這個(gè)mock對(duì)象被調(diào)用某一方法時(shí),應(yīng)該返回的結(jié)果
Mockito.when(presenter.checkIsEnrolled(1)).thenReturn(true);

spy()和mock()的區(qū)別在于,未指定mock方法的返回值時(shí),默認(rèn)返回null,而為指定spy方法的返回值時(shí),默認(rèn)執(zhí)行目標(biāo)方法的邏輯,并返回對(duì)應(yīng)邏輯執(zhí)行的結(jié)果。另外有一個(gè)很重要的區(qū)別在于,使用spy的情況下,雖然提供了函數(shù)的模擬實(shí)現(xiàn),但Mockito框架仍然會(huì)調(diào)用真實(shí)的代碼,所以如果真實(shí)代碼無(wú)法在單測(cè)下運(yùn)行,則使用spy模擬會(huì)導(dǎo)致測(cè)試失敗。

使用Mockito驗(yàn)證結(jié)果

// 驗(yàn)證mock的database對(duì)象,調(diào)用setUniqueId方法時(shí)的入?yún)⑹欠駷?2
verify(database).setUniqueId(ArgumentMatchers.eq(12));
 
// 驗(yàn)證mock的database對(duì)象的getUniqueId方法是否被調(diào)用2次
verify(database, times(2)).getUniqueId();
 
// 驗(yàn)證mock的database對(duì)象的getUniqueId方法是否被調(diào)用1次
verify(database).getUniqueId();
 
// 也可以使用傳統(tǒng)的Junit判斷方法判斷結(jié)果是否符合預(yù)期
assertEquals("foo", spy.get(0));

使用Mockito-inline模擬靜態(tài)方法

Mockito版本升級(jí)之后,支持對(duì)Static?Method做Hook。前提是在build.gradle中引入Mockito-inline。

org.mockito:mockito-inline:${version}

以下是實(shí)例被測(cè)代碼,當(dāng)我們?cè)跍y(cè)試類中調(diào)用doSomethings(),很可能無(wú)法通過(guò)調(diào)整MemoryService的返回值,控制doSomthing2的入?yún)ⅲ瑥亩采w更多的邏輯分支。此時(shí)我們就需要Hook DataEngine甚至是MemoryService,獲取我們想要的返回值。

public void doSomethings() {
    DataEngine.getMemoryService().saveCacheObject("key", "abc");
    ...
    String a = DataEngine.getMemoryService().getCacheObject("key");
    doSomething2(a);
}

下面給出使用mockito-inline對(duì)靜態(tài)方法的處理步驟。

一.Hook靜態(tài)方法。 使用Java7的try-with-resource語(yǔ)法,模擬觸發(fā)靜態(tài)方法 (DataEngine .getMemoryService ) 的行為。

需要注意的是:mockService可以是通過(guò)Mockito mock出來(lái)的,也可以是我們創(chuàng)建的一個(gè)真實(shí)的MemoryService子類,區(qū)別在于,使用Mockito mock的MemoryService我們不需要實(shí)現(xiàn)所有的方法,只需要mock我們測(cè)試類中可能調(diào)用到的方法。

MemoryStoreService mockService = Mockito.mock(MemoryStoreService.class);
try (MockedStatic<DataEngine> service = Mockito.mockStatic(DataEngine.class)) {
    service.when(DataEngine::getMemoryService).thenReturn(mockService);
}

二. 使用更加智能的模擬返回方法。

我們使用較多的是thenReturn()方法,但是在本案例的場(chǎng)景下,我們需要功能更強(qiáng)大的返回方法。因?yàn)椋禾幚砟M的入?yún)ⅲ?/p>

1. MemoryService::saveCacheObject返回值是Void,所以無(wú)法使用thenReturn()

2. 我們需要處理入?yún)ⅲ槍?duì)每一個(gè)saveCacheObject的模擬調(diào)用,我們都需要真實(shí)的將其保存到Map中

final Map<String, Object> pools = new HashMap<>();
 
//當(dāng)觸發(fā)了mockService的saveCacheObject方法,就會(huì)回調(diào)answer(),從而將入?yún)⒌腒ey和Value保存到Map中
Mockito.doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        pools.put((String) invocation.getArgument(0), invocation.getArgument(1));
        return null;
    }
}).when(mockService).saveCacheObject(Mockito.anyString(), Mockito.any());

當(dāng)我們使用doAnswer模擬了saveCacheObject,那我們很有可能需要使用同樣的策略模擬getCacheObject。就像這樣:

Mockito.when(mockService.containsCachedObject(Mockito.anyString()))
    .thenAnswer(invocation -> pools.containsKey(invocation.getArgument(0)));

使用Mockito測(cè)試異步代碼段

假如需要測(cè)試一段異步代碼,可以使用標(biāo)準(zhǔn)的異步代碼測(cè)試步驟進(jìn)行。舉例如下:

public void update(List<Demo> demos) {
    repo.refresh(demos, () -> {
        doSomething();
    });
}

針對(duì)上述代碼,測(cè)試的基本思路是:

步驟一:?模擬一個(gè)異步回調(diào)函數(shù)

//1.判斷需要的回調(diào)函數(shù)的類型,創(chuàng)建ArgumentCaptor
ArgumentCaptor<Repo.OnRefreshListener> captor =
ArgumentCaptor.forClass(Repo.OnRefreshListener.class);
 
//2.主動(dòng)調(diào)用相應(yīng)函數(shù),觸發(fā)Mockito框架的執(zhí)行流進(jìn)行到回調(diào)函數(shù),同時(shí)將captor.capture()作為入?yún)魅搿?Mockito.verify(repo).refresh(Mockito.anyList(), captor.capture());
 
//3.通過(guò)captor.getValue()模擬異步回調(diào)函數(shù)
Repo.OnRefreshListener mockListener = captor.getValue();

步驟二:?主動(dòng)調(diào)用異步回調(diào)接口,從而使執(zhí)行流進(jìn)入回調(diào)函數(shù)中

//主動(dòng)調(diào)用異步函數(shù)接口,使得測(cè)試執(zhí)行流進(jìn)入函數(shù)體
mockListener.onResult();

步驟三:?判斷是否執(zhí)行了doSomething()方法,或者執(zhí)行結(jié)果是否符合預(yù)期的其他判斷方式。

使用Mockito-inline測(cè)試靜態(tài)方法的異步代碼段

假如需對(duì)以下代碼進(jìn)行單元測(cè)試,我們就需要用到mockito-inline.可以看到,RPC請(qǐng)求是通過(guò)一個(gè)靜態(tài)方法發(fā)出,并且通過(guò)異步回調(diào)的形式返回結(jié)果。

public void demo(String id) {
    RpcService.send(new DemoReq(id), new RpcCallback<DemoResp>() {
        @Override
        public void onFailure(BaseReq call, String msg, String procCd, String procSts, Exception e) {
            if(listener != null){
                listener.onFailure(msg, procCd, procSts);
            }
        }
        @Override
        public void onResponse(BaseReq call, WalletDetailRespMsg response) {
            if(listener != null){
                listener.onSuccess(response);
            }
        }
    });
}

具體寫法關(guān)鍵在定義攔截后的行為,invacation保留了調(diào)用信息,根據(jù)序號(hào)獲取入?yún)?,可以?duì)入?yún)⑦M(jìn)行判斷,之后就可以主動(dòng)調(diào)用回調(diào)函數(shù)。

try (MockedStatic<RpcService> rpcMock = Mockito.mockStatic(RpcService.class)) {
    //告訴mockito,遇到RpcService.send(參數(shù)任意,參數(shù)任意)的時(shí)候,攔截
    rpcMock.when(() -> RpcManager.sendFromNative(Mockito.any(), Mockito.any()))
        .then(invocation -> {
            //攔截之后,會(huì)進(jìn)入到這里。
            //invocation會(huì)保留調(diào)用的信息。通過(guò)getArgument可以獲取入?yún)?            RpcCallback callback1 = invocation.getArgument(1, RpcCallback.class);
            //主動(dòng)調(diào)用callback,可以指定回調(diào)入?yún)?            callback1.onResponse(Mockito.mock(BaseReq.class),
            Mockito.mock(WalletDetailRespMsg.class));
            return null;
        });
 
        //主動(dòng)調(diào)用被測(cè)方法
        presenter.refreshWalletDetail(testWalletId, callback);
        Mockito.verify(callback).onSuccess(Mockito.any());
}

使用Kotlin封裝Mockito-inline單測(cè)公用方法

如上,我們?nèi)羰褂胘ava的try-catch-resources會(huì)顯得代碼臃腫,于是我們可以嘗試Kotlin簡(jiǎn)化。 對(duì)于try-catch-resources,kotlin中的等價(jià)寫法是使用use

//mock了Apps.getApp()這個(gè)靜態(tài)方法的返回結(jié)果。傳入一個(gè)高階函數(shù),易于進(jìn)行串聯(lián)調(diào)用。
fun getAppMock(action: () -> Any?) {
    Mockito.mockStatic(Apps::class.java).use { appUtilsMock ->
        appUtilsMock.`when`<Void> { Apps.getApp() }.thenReturn(null)
        action()
    }
}

如果我們封裝了大量的公用mock代碼,那么一段測(cè)試代碼就長(zhǎng)這樣:

@Test
fun reduceWithUserRejectTest() {
    val change = HceDefaultChange(true)
    getAppMock {
        isNfcDefaultPaymentMockStatic(true) {
            checkNetMockStatic(true) {
                val actual: PaymentPageState = change.reduce(PaymentPageState())
                Assert.assertTrue(actual.showWaving)
            }
        }
    }
}

是不是和寫Flutter或者Compose的UI頁(yè)面一樣啦~

Roboletric

如果不測(cè)試Activity頁(yè)面,則不建議使用Roboletric,一是因?yàn)閙ockito已經(jīng)能夠完成幾乎全部的工作,并不需要用到Roboletric,二是用Roboletric影響測(cè)試執(zhí)行速度。

編寫可運(yùn)行的Roboletric單元測(cè)試方法

// 首先需要添加RobolectricTestRunner,作為運(yùn)行Roboletric的啟動(dòng)器
 
@RunWith(RobolectricTestRunner.class)
 
// 其次需要使用Config配置本次單元測(cè)試的基礎(chǔ)配置。
 
// 1. 如果你的電腦上運(yùn)行的JAVA版本不是11以上,則需要指定sdk版本為Android 9.0以下
 
// 2. 可以指定shadows。shadows下文會(huì)詳細(xì)解析,這里可配置可不配置,取決于具體場(chǎng)景
 
// 3. qualifiers可以配置機(jī)器的尺寸,多語(yǔ)言環(huán)境等,可配置可不配置,取決于具體場(chǎng)景。例子中指定了中文環(huán)境
 
@Config(sdk = {Build.VERSION_CODES.O_MR1},
 
        shadows = {DemoShadow.class},
 
        qualifiers = "zh"
 
)
public class DemoTest {
}

使用Roboletric模擬Activity

Roboletric的一大特點(diǎn)就是可以模擬Android的context。 我們可以再@Before注解的方法中使用Roboletric創(chuàng)建一個(gè)Activity,

@Before
public void initActivity() {
    //Intent可選
    Intent faceIntent = new Intent();
    faceIntent.putExtra(DEMO, uri.toString());
    activity = Robolectric.buildActivity(VerificationBioGuideActivity.class, faceIntent)
            .create().resume().get();
}

Roboletric調(diào)用buildActivity即可模擬一個(gè)Activity,調(diào)用create可以觸發(fā)onCreate回調(diào),調(diào)用resume可以觸發(fā)onResume回調(diào),最后調(diào)動(dòng)get就可以拿到這個(gè)activity對(duì)象。拿到activity的對(duì)象之后,我們就可以通過(guò)activity進(jìn)行一些操作了。例如,獲取View的控件,獲取字符串等。

// 獲取View控件
TitleBar titleBar = (TitleBar) activity.findViewById(R.id.title_bar);
 
// 獲取字符串
activity.getString(R.string.verification_bio_pay_title_finger_success_tips)

可以使用Roboletric模擬出來(lái)的activity作為context,如果只需要用到applicaitonContext,可以使用

RuntimeEnvironment.getApplication()

Roboletric的殺手锏——Shadows

Robolectric的本質(zhì)是在Java運(yùn)行環(huán)境下,采用Shadow的方式對(duì)Android中的組件進(jìn)行模擬測(cè)試,從而實(shí)現(xiàn)Android單元測(cè)試。

Shadows的作用就是使用自定義的方法和類替換原先業(yè)務(wù)的方法和類,原理就是使用字節(jié)碼修改技術(shù)進(jìn)行動(dòng)態(tài)的修改。例如,業(yè)務(wù)中A.class原先要調(diào)用B.class的C()函數(shù),我們使用Shadows,并定義一個(gè)函數(shù)簽名一樣的函數(shù)D()將其作用于C()函數(shù)上。當(dāng)觸發(fā)A.class的調(diào)用后,程序執(zhí)行流程會(huì)進(jìn)入D()函數(shù)中。

自定義Shadows簡(jiǎn)介

第一步: 使用@Implements類定義需要被替換的目標(biāo)類。Shadows類本身也是一個(gè)普通的Java類,只不過(guò)多了@Implements注解,所以他也可以實(shí)現(xiàn)接口,繼承等功能。

// 表明這個(gè)Shadow期望模擬ActualClass類的行為
@Implements(ActualClass.class)
@RequiresApi(api = Build.VERSION_CODES.N)
public class ActualClassShadow {
 
}

第二步: 與目標(biāo)函數(shù)使用相同的函數(shù)簽名,并且增加@Implementation注解。可以只替換目標(biāo)類中的部分函數(shù),而其他函數(shù)仍然遵循目標(biāo)類的邏輯。

//表明需要模擬ActualClass中的containsKey方法
@Implementation
public boolean containsKey(String key) {
}

第三步(可選):__constructor__可以替換構(gòu)造函數(shù)

public void __constructor__(int x, int y) {
    realPoint.x = x;
    realPoint.y = y;
}

第四步(可選):使用@RealObject可以獲取目標(biāo)對(duì)象

@RealObject?private?Point?realPoint;

第五步:定義好Shadows之后,我們需要再測(cè)試類的Config注解中進(jìn)行注冊(cè)。

@Config(shadows = {ActualClassShadow.class})

使用Chat-GPT生成單元測(cè)試案例

緊跟時(shí)事??!

我們可以使用Chat-GPT快速生成測(cè)試案例,分為以下幾步:

第一步:讓Chat-GPT知曉該函數(shù)的意圖

第二步:告訴Chat-GPT單元測(cè)試的目標(biāo)

Optional:可以指定Chat-GPT使用Junit4的一些測(cè)試特性簡(jiǎn)化單測(cè)案例

序號(hào)?? ?Chat-GPT?? ?Input
1?? ??? ?java (輸入待測(cè)代碼)what's the author's intentions
2?? ?The author's intention with this Java code is to provide a methodhexStringToByteArray that can convert a hexadecimal string to abyte array. The method takes a single argument data, which is thehexadecimal string to be converted. The code first checkswhether the input string is valid and has an even number ofcharacters, since each pair of characters in the string representsa single byte. If the input string is valid, the code creates a new byte arrayresult with a length equal to half the length of the input string(since each pair of characters represents one byte). It then loopsover the input string in pairs, converting each pair of charactersto a byte and storing it in the result array. If the input string is not valid, the code logs an error message andreturns null. Overall, the intention of this method is to provide a simple andreliable way to convert hexadecimal strings to byte arrays inJava.?? ?
3?? ??? ?A good unit test suite should aim to:- Test the function's behavior for a wide range of possible inputs- Test edge cases that the author may not have foreseen- Take advantage of the features of Parameterized to make thetests easy to write and maintain- Be easy to read and understand, with clean code anddescriptive names- Be deterministic, so that the tests always pass or fail in the same wayJunit has many convenient features that make it easy to write and maintain unit tests. We'll use them to write unit tests for the function above.For this particular function, we'll want our unit tests to handle the following diverse scenarios
4?? ?Since the code provided is in Java, we'll write our unit tests inJava using the JUnit framework. Here are some example unittests we might write for the hexStringToByteArray function: @RunWith(Parameterized.class)public class DesUtilsHexStringToByteArrayTest { ? ?@Parameterized.Parameters ? ?public static Collection<Object[]> data() { ? ? ? ?return Arrays.asList(new Object[][]{ ? ? ? ? ? ? ? ?// Test cases where input is valid ? ? ? ? ? ? ? ?{"00", new byte[]{0x00}}, ? ? ? ? ? ? ? ?{"7f", new byte[]{0x7f}}, ? ? ? ? ? ? ? ?{"deadbeef", new byte[]{(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef}}, ? ? ? ? ? ? ? ?{"0102030405060708090a0b0c0d0e0f", new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}}, ? ? ? ? ? ? ? ?// Test cases where input is invalid ? ? ? ? ? ? ? ?{"", null}, ? ? ? ? ? ? ? ?{"0", null}, ? ? ? ? ? ? ? ?{"1", null}, ? ? ? ? ? ? ? ?{"a", null}, ? ? ? ? ? ? ? ?{"g", null}, ? ? ? ? ? ? ? ?{"gg", null}, ? ? ? ? ? ? ? ?{"000", null}, ? ? ? ? ? ? ? ?{"001", null}, ? ? ? ? ? ? ? ?{"00g", null}, ? ? ? ? ? ? ? ?{"0x00", null}, ? ? ? ? ? ? ? ?{"deadbeef0", null} ? ? ? ?}); ? ?} ? ? private String input; ? ?private byte[] expected; ? ? public DesUtilsHexStringToByteArrayTest(String input, byte[] expected) { ? ? ? ?this.input = input; ? ? ? ?this.expected = expected; ? ?} ? ? @Test ? ?public void testHexStringToByteArray() { ? ? ? ?byte[] actual = hexStringToByteArray(input); ? ? ? ?assertArrayEquals(expected, actual); ? ?}} In this example, we're using JUnit's Parameterized runner togenerate multiple test cases from a single test method. The datamethod returns a collection of test cases, each represented as anarray of input parameters and expected output. We have included test cases for a wide range of possible inputs,including valid input strings with different lengths, as well asinvalid input strings that don't have an even number ofcharacters, contain non-hexadecimal characters, or exceed themaximum length that can be converted to a byte array. We've used descriptive names for our test class, test method,and test parameters to make the tests easy to read andunderstand. Finally, our tests are deterministic, since they will always pass or fail in the same way.

最后感謝每一個(gè)認(rèn)真閱讀我文章的人,禮尚往來(lái)總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:

android單元測(cè)試private變量,軟件測(cè)試,單元測(cè)試,軟件測(cè)試,功能測(cè)試,自動(dòng)化測(cè)試,程序人生,職場(chǎng)和發(fā)展

這些資料,對(duì)于【軟件測(cè)試】的朋友來(lái)說(shuō)應(yīng)該是最全面最完整的備戰(zhàn)倉(cāng)庫(kù),這個(gè)倉(cāng)庫(kù)也陪伴上萬(wàn)個(gè)測(cè)試工程師們走過(guò)最艱難的路程,希望也能幫助到你!??

android單元測(cè)試private變量,軟件測(cè)試,單元測(cè)試,軟件測(cè)試,功能測(cè)試,自動(dòng)化測(cè)試,程序人生,職場(chǎng)和發(fā)展文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-762873.html

到了這里,關(guān)于Android下單元測(cè)試實(shí)踐——測(cè)試框架簡(jiǎn)介的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android 單元測(cè)試之 Mockk

    relaxed : 是否對(duì)其代碼進(jìn)行依賴,默認(rèn)為否,這個(gè)參數(shù)比較關(guān)鍵,后續(xù)會(huì)更細(xì)的講解一下 moreInterfaces : 讓這個(gè)mock出來(lái)的對(duì)象實(shí)現(xiàn)這些聲明的接口 relaxUnitFun :和 relaxed 差不多,但是只針對(duì)于 返回值是Unit 的方法, 后續(xù)會(huì)講解一下 block : 該語(yǔ)句塊表示你在創(chuàng)建完 mock 對(duì)象后

    2024年02月02日
    瀏覽(22)
  • Android 單元測(cè)試之PowerMock

    Android 單元測(cè)試之PowerMock

    class PowerMockClassTest { @Test fun isFileExists() { // Mock 一個(gè) File對(duì)象 val file = PowerMockito.mock(File::class.java) // 創(chuàng)建當(dāng)前類 val powerMockitoClass = PowerMockClass() // 當(dāng)Mock對(duì)象被調(diào)用了 exists() 方法,則返回False PowerMockito. when (file.exists()).thenReturn(false) // 進(jìn)行斷言 assertFalse(file.exists()) } } 對(duì)于這種

    2024年04月23日
    瀏覽(26)
  • Android Studio系列-Activity單元測(cè)試,字節(jié)Android高級(jí)崗

    Android Studio系列-Activity單元測(cè)試,字節(jié)Android高級(jí)崗

    新建Activity單元測(cè)試類 =============== package com.devilwwj.unittestdemo; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.test.suitebuilder.annotation.MediumTest; import android.widget.Button; /** Created by wwj_748 on 2016/2/22.17.12 */ public class LoginActivityTest extends ActivityUnitTestCase { private Inten

    2024年04月25日
    瀏覽(27)
  • 貓耳 Android 播放框架開發(fā)實(shí)踐

    貓耳 Android 播放框架開發(fā)實(shí)踐

    貓耳FM是中國(guó)最大的 95 后聲音內(nèi)容分享平臺(tái),是B站重要平臺(tái)之一,深度合作國(guó)內(nèi)頂級(jí)聲優(yōu)工作室,打造了數(shù)百部精品廣播劇,全站播放總量超過(guò)百億次。 MEPlayer 是貓耳 Android 技術(shù)團(tuán)隊(duì)研發(fā)的一款適用于音視頻、直播、特效播放等多種場(chǎng)景的跨進(jìn)程播放框架。目前支持: 音視

    2024年02月06日
    瀏覽(17)
  • 如何優(yōu)雅地單元測(cè)試 Kotlin/Java 中的 private 方法?

    如何優(yōu)雅地單元測(cè)試 Kotlin/Java 中的 private 方法?

    翻譯自 https://medium.com/mindorks/how-to-unit-test-private-methods-in-java-and-kotlin-d3cae49dccd ?如何單元測(cè)試 Kotlin/Java 中的 private 方法? 首先,開發(fā)者應(yīng)該測(cè)試代碼里的 private 私有方法嗎? 直接信任這些私有方法,測(cè)試到調(diào)用它們的公開方法感覺就夠了吧。 對(duì)于這個(gè)爭(zhēng)論,每個(gè)開發(fā)者都會(huì)

    2024年02月06日
    瀏覽(19)
  • Android單元測(cè)試系列(3)-Mock之PowerMock

    Android單元測(cè)試系列(3)-Mock之PowerMock

    目錄 一、官網(wǎng) 二、Demo示例? 三、PowerMock常用的測(cè)試方法 1. Private 1.1 私有變量 1.2 私有方法 2. Final 3. Static Android單元測(cè)試系列(3)-Mock之Mockito_Chris_166的博客-CSDN博客 Android單元測(cè)試系列(1)-開篇_Chris_166的博客-CSDN博客 這兩篇中已經(jīng)分別介紹過(guò)Mockito的使用和局限性,本篇將介紹P

    2023年04月08日
    瀏覽(23)
  • Android單元測(cè)試系列(3)-Mock之Mockito

    Android單元測(cè)試系列(3)-Mock之Mockito

    目錄 一、官網(wǎng) 二、Demo示例 1. 目錄結(jié)構(gòu) 2. 被測(cè)試的類 3. 測(cè)試類 三、Mockito方法說(shuō)明 1. mock對(duì)象創(chuàng)建 2. Mockito框架中的常見方法說(shuō)明 2.1 常見的打樁方法 2.2 常見的驗(yàn)證行為 2.3 其他方法? 3. Mockito的局限性 Mockito: https://github.com/mockito/mockito Mockito (Mockito 4.4.0 API) 為什么要用mock:

    2023年04月15日
    瀏覽(23)
  • junit單元測(cè)試mock私有private方法和靜態(tài)static方法

    我們知道org.mockito.Mockito功能有限,不能mock 私有private、受保護(hù)的protected方法 org.powermock.api.mockito.PowerMockito更強(qiáng)大,支持對(duì)private和protected和static方法的mock 別忘記,首先要引入maven依賴 有如下私有方法需要mock 這時(shí)候可以利用PowerMockito的spy方法mock出方法所在的對(duì)象,然后利用

    2024年02月12日
    瀏覽(21)
  • 【Android】JUnit和Espresso單元測(cè)試新手快速入門

    引入依賴 Java代碼測(cè)試 點(diǎn)擊被Test標(biāo)注的方法,左側(cè)的運(yùn)行按鈕,就可以執(zhí)行測(cè)試任務(wù) AndroidUI測(cè)試 點(diǎn)擊被Test標(biāo)注的方法,左側(cè)的運(yùn)行按鈕,就可以執(zhí)行測(cè)試任務(wù) 查看測(cè)試報(bào)告 測(cè)試任務(wù)執(zhí)行完畢,會(huì)在app/build/reports目錄下生成測(cè)試報(bào)告 報(bào)告會(huì)統(tǒng)計(jì)所有測(cè)試任務(wù)的執(zhí)行結(jié)果,已

    2024年02月11日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包