中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

SpringBoot | 第十三章:測試相關(guān)(單元測試、性能測試)

2018-08-28    來源:importnew

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

前言

前面寫了這么多章節(jié),都是通過瀏覽器訪問的形式,進(jìn)行接口方法訪問進(jìn)而驗(yàn)證方法的正確與否。顯然在服務(wù)或者接口比較少時(shí),這么做沒有啥問題,但一旦一個(gè)項(xiàng)目稍微復(fù)雜或者接口方法比較多時(shí),這么驗(yàn)證就有點(diǎn)不符合程序猿的懶人的特性了。所以這章節(jié),講述下SpringBoot中的單元測試及基于Contiperf壓測工具進(jìn)行性能測試相關(guān)方面的知識(shí)點(diǎn)。

單元測試

是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證。一般上在開發(fā)階段或者程序發(fā)布時(shí),都會(huì)利用像Maven這樣的打包工具進(jìn)行打包前的測試,避免不必要的bug程序被打包部署。

題外話:在開發(fā)階段,都應(yīng)該要求編寫單元測試,核心的模塊還需要進(jìn)行覆蓋測試,覆蓋率至少要95%以上。

SpringBoot的單元測試

對于java開發(fā)者而言,Junit應(yīng)該無人不知了。所以SpringBoot也是基于Junit進(jìn)行單位測試的。

0.加入pom依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

1.這里為了演示,編寫了一個(gè)簡單的測試接口及編寫對應(yīng)的測試類。

UnitTestService.java

/**
 * 測試接口類
 * @author oKong
 *
 */
public interface UnitTestService {
    
    public String process(String msg);

}

實(shí)現(xiàn)類:UnitTestServiceImpl.java

@Service
public class UnitTestServiceImpl implements UnitTestService{

    /**
     * 為了測試,這里直接返回傳入的值
     */
    @Override
    public String process(String msg) {
        // TODO Auto-generated method stub
        return msg;
    }
}

測試類:UnitTestServiceTest.java

題外話:個(gè)人建議,每個(gè)測試類都應(yīng)該和對應(yīng)的被測試類包路徑一致。同時(shí)測試類的名稱是被測試的類名+Test,如本例所示的:

示例

/**
 * 編寫接口測試類
 * @author oKong
 *
 */
@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于測試的注解,可指定啟動(dòng)類或者測試環(huán)境等,這里直接默認(rèn)。
@SpringBootTest 
public class UnitTestServiceTest {
    
    @Autowired
    UnitTestService testService;
    
    public void test() {
        String msg = "this is a test";
        String result = testService.process(msg);
        //斷言 是否和預(yù)期一致
        Assert.assertEquals(msg, result);
    }
}

 

  1. 運(yùn)行右擊,選擇?run As?–>?Junit Test?或者需要debug時(shí),選擇Debug As?–>?Junit Test,運(yùn)行即可。

測試結(jié)果

3.至此,一個(gè)簡單的單元測試就結(jié)束了。簡單來說,寫一個(gè)單元測試是容易的,但寫好一個(gè)單元測試是難的。畢竟,每個(gè)程序猿都覺得自己的代碼是沒有問題的,難道不是嗎?哈哈!

RESTful API 單元測試

對于服務(wù)類而言,編寫單元測試是相對簡單的,只需要像控制層自動(dòng)引入接口類一樣。但編寫控制層即RESTful API 單元測試時(shí),一般上就需要利用Mock技術(shù)進(jìn)行測試了。當(dāng)然也可以使用像Swagger或者PostMan這樣的api測試工具進(jìn)行測試(或者使用RestTemplate測試也是可行的),它可進(jìn)行自動(dòng)化測試,關(guān)于Postman會(huì)在之后的章節(jié)進(jìn)行更新,作者也沒有過多研究過,也只是用到了它的最基本的發(fā)起http請求的功能,之后會(huì)整理相關(guān)資料的。

0.創(chuàng)建一個(gè)RESTful接口服務(wù)。

/**
 * 編寫mock測試服務(wù)
 * @author oKong
 *
 */
@RestController
public class DemoController {

    @GetMapping("/mock")
    public String demo(String msg) {
        return msg;
    }
}

1.編寫對應(yīng)測試類

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于測試的注解,可指定啟動(dòng)類或者測試環(huán)境等,這里直接默認(rèn)。
//因?yàn)槭莔ock測試,在實(shí)際開發(fā)過程中,可指定其測試啟動(dòng)時(shí)為隨機(jī)端口,避免了不必要的端口沖突。
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 
//測試單一接口時(shí) ,也可利用注解@WebMvcTest 進(jìn)行單一測試
//@WebMvcTest(DemoController.class)
public class DemoControllerTest {

    //使用 WebMvcTest 時(shí)使用 
    //@autowired mockMvc 是可自動(dòng)注入的。
    //當(dāng)直接使用SpringBootTest 會(huì)提示 注入失敗  這里直接示例利用 MockMvcBuilders工具創(chuàng)建
    //@Autowired
    MockMvc mockMvc;
    
    @Autowired
    WebApplicationContext wc;
    
    @Before
    public void beforeSetUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wc).build();
    }
    
    @Test
    public void testDemo() throws Exception {
        String msg = "this is a mock test";
        MvcResult result = this.mockMvc.perform(get("/mock").param("msg", msg)).andDo(print()).andExpect(status().isOk())
        .andReturn();
        
        //斷言 是否和預(yù)期相等
        Assert.assertEquals(msg, result.getResponse().getContentAsString());

    }
}

2.運(yùn)行右擊,選擇?run As?–>?Junit Test?或者需要debug時(shí),選擇Debug As?–>?Junit Test,運(yùn)行即可。(也可以看見每次啟動(dòng)測試時(shí),每次端口號(hào)都是不同的。)

2018-07-25 23:16:28.733  INFO 13000 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 59999 (http)
2018-07-25 23:16:28.754  INFO 13000 --- [           main] c.l.l.s.c.controller.DemoControllerTest  : Started DemoControllerTest in 5.673 seconds (JVM running for 6.769)

測試結(jié)果

由于配置了print()這個(gè)ResultHandler,所以控制臺(tái)會(huì)打印相關(guān)參數(shù)信息。建議設(shè)置此屬性,這樣就算測試有問題,也能看下具體的參數(shù)信息。其他相關(guān)mock的用法,此處就不舉例了,大家可自行搜索下,比較本章節(jié)只是簡單示例下用法~

請求參數(shù)信息

  1. 鑒于每次編寫控制層測試類時(shí),都需要?jiǎng)?chuàng)建MockMvc對象,故可創(chuàng)建一個(gè)基類,這樣省得每次都寫。

BaseMockTest.java

/**
 * mock 基類
 * @author oKong
 *
 */
public abstract class BaseMockTest {
    
    @Autowired
    private WebApplicationContext wc;

    protected MockMvc mockMvc;
    
    @Before
    public void beforeSetUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wc).build();
    }

}

 

這樣編寫mock測試類時(shí),還需要繼承此基類即可。

Junit常用注解說明

  • @Test 加在待測試的方法前面
  • @Before 帶上@Test的方法執(zhí)行前會(huì)執(zhí)行該方法
  • @After 帶上@Test的方法執(zhí)行完畢后會(huì)執(zhí)行該方法
  • @BeforeClass 加上這個(gè)注解,則該方法會(huì)第一個(gè)執(zhí)行(在所有方法中),且方法要加上關(guān)鍵詞static,是一個(gè)static方法
  • @AfterClass 加上這個(gè)注解,則該方法最后一個(gè)執(zhí)行(在所有方法中),同樣,方法要加上關(guān)鍵詞static,是一個(gè)static方法

詳細(xì)的使用,大家可自行谷歌下,畢竟常用的也就前面三個(gè)了,(┬_┬)

基于ContiPerf的性能測試

ContiPerf是一個(gè)輕量級(jí)的測試工具,基于JUnit 4 開發(fā),可用于效率測試等?梢灾付ㄔ诰程數(shù)量和執(zhí)行次數(shù),通過限制最大時(shí)間和平均執(zhí)行時(shí)間來進(jìn)行性能測試。

性能測試示例

0.加入pom依賴包。

<dependency>
    <groupId>org.databene</groupId>
    <artifactId>contiperf</artifactId>
    <version>2.3.4</version>
    <scope>test</scope>
</dependency>

1.改寫UnitTestServiceTest測試類,進(jìn)入ContiPerfRule
題外話:@RuleJunit提供的一個(gè)擴(kuò)展接口注解,其接口類為:org.junit.rules.MethodRule,注意在Junit5中,已經(jīng)被TestRule所以替代了。這里只是簡單提下,因?yàn)榫唧w的也不是很清楚,也沒有深入了解過。

/**
 * 編寫接口測試類
 * @author oKong
 *
 */
@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于測試的注解,可指定啟動(dòng)類或者測試環(huán)境等,這里直接默認(rèn)。
@SpringBootTest 
public class UnitTestServiceTest {
	
	@Autowired
	UnitTestService testService;
	
	//引入 ContiPerf 進(jìn)行性能測試
	@Rule
	public ContiPerfRule contiPerfRule = new ContiPerfRule();
	
	@Test
	//10個(gè)線程 執(zhí)行10次
	@PerfTest(invocations = 100,threads = 10)
	public void test() {
		String msg = "this is a test";
		String result = testService.process(msg);
		//斷言 是否和預(yù)期一致
		Assert.assertEquals(msg, result);
	}
}

 

  1. 控制臺(tái)會(huì)有性能報(bào)告,同時(shí)訪問:target/contiperf-report/index.html,會(huì)有圖表提示。

控制臺(tái)輸出:

cn.lqdev.learning.springboot.chapter13.service.UnitTestServiceTest.test
samples: 100
max:     403
average: 41.5
median:  15

測試報(bào)告:

測試報(bào)告測試報(bào)告

注解參數(shù)說明

@PerfTest

  • invocations:執(zhí)行次數(shù)n,與線程數(shù)量無關(guān),默認(rèn)值為1
  • threads:線程池?cái)?shù)量n,并發(fā)執(zhí)行n個(gè)線程
  • duration:重復(fù)地執(zhí)行時(shí)間n,測試至少執(zhí)行n毫秒

@Required

  • throughput:吞吐要求n,要求每秒至少執(zhí)行n個(gè)測試
  • average:平均執(zhí)行時(shí)間n,要求平均執(zhí)行時(shí)間不超過n毫秒
  • max:最大執(zhí)行時(shí)間n,要求最大的執(zhí)行時(shí)間不超過n毫秒
  • totalTime:總執(zhí)行時(shí)間n,要求總的執(zhí)行時(shí)間不超過n毫秒
  • median:50%平均執(zhí)行時(shí)間n,要求所有執(zhí)行的50%測試平均執(zhí)行時(shí)間不超過n毫秒
  • percentile90:90%平均執(zhí)行時(shí)間n,要求所有執(zhí)行的90%測試平均執(zhí)行時(shí)間不超過n毫秒
  • percentile95:95%平均執(zhí)行時(shí)間n,要求所有執(zhí)行的95%測試平均執(zhí)行時(shí)間不超過n毫秒
  • percentile99:99%平均執(zhí)行時(shí)間n,要求所有執(zhí)行的99%測試平均執(zhí)行時(shí)間不超過n毫秒
  • percentiles:表達(dá)式”a:n,b:m”,要求a%的測試不超過n毫秒,b%的測試不超過m毫秒

總結(jié)

本章節(jié)主要是對JunitContiPerf的使用簡單的示例,像MockMvc的詳細(xì)用法并沒有深入,大家可自行搜索下,畢竟我也用的不多呀。

最后

目前互聯(lián)網(wǎng)上很多大佬都有SpringBoot系列教程,如有雷同,請多多包涵了。本文是作者在電腦前一字一句敲的,每一步都是實(shí)踐的。若文中有所錯(cuò)誤之處,還望提出,謝謝。

標(biāo)簽: 代碼 谷歌 互聯(lián)網(wǎng) 開發(fā)者 搜索

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:SpringBoot | 第十四章:基于Docker的簡單部署

下一篇:iOS 利用AFNetworking實(shí)現(xiàn)大文件分片上傳