欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring boot系列之集成測試(推薦)

 更新時間:2018年03月23日 15:13:15   作者:大名Dean鼎  
這篇文章主要介紹了spring boot系列集成測試,需要的朋友可以參考下

如果希望很方便針對API進(jìn)行測試,并且方便的集成到CI中驗證每次的提交,那么spring boot自帶的IT絕對是不二選擇。

迅速編寫一個測試Case

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({Profiles.ENV_IT})
public class DemoIntegrationTest{
  @Autowired
  private FooService fooService;
  @Test
  public void test(){
    System.out.println("tested");
  }
}

其中 SpringBootTest 定義了跑IT時的一些配置,上述代碼是用了隨機端口,當(dāng)然也可以預(yù)定義端口,像這樣

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port=9990"})

ActiveProfiles 強制使用了IT的Profile,從最佳實踐上來說IT Profile所配置的數(shù)據(jù)庫或者其他資源組件的地址,應(yīng)該是與開發(fā)或者Staging環(huán)境隔離的。因為當(dāng)一個IT跑完之后很多情況下我們需要清除測試數(shù)據(jù)。

你能夠發(fā)現(xiàn)這樣的Case可以使用 Autowired 注入任何想要的Service。這是因為spring將整個上下文都加載了起來,與實際運行的環(huán)境是一樣的,包含了數(shù)據(jù)庫,緩存等等組件。如果覺得測試時不需要全部的資源,那么在profile刪除對應(yīng)的配置就可以了。這就是一個完整的運行環(huán)境,唯一的區(qū)別是當(dāng)用例跑完會自動shutdown。

測試一個Rest API

強烈推薦一個庫,加入到gradle中

testCompile 'io.rest-assured:rest-assured:3.0.3'

支持JsonPath,十分好用,具體文檔戳 這里

@Sql(scripts = "/testdata/users.sql")
@Test
public void test001Login() {
  String username = "demo@demo.com";
  String password = "demo";
  JwtAuthenticationRequest request = new JwtAuthenticationRequest(username, password);
  Response response = given().contentType(ContentType.JSON).body(request)
      .when().post("/auth/login").then()
      .statusCode(HttpStatus.OK.value())
      .extract()
      .response();
  assertThat(response.path("token"), is(IsNull.notNullValue()));
  assertThat(response.path("expiration"), is(IsNull.notNullValue()));
}

@Sql 用于在測試前執(zhí)行sql插入測試數(shù)據(jù)。注意 given().body() 中傳入的是一個java對象 JwtAuthenticationRequest ,因為rest-assured會自動幫你用 jackson 將對象序列化成json字符串。當(dāng)然也可以將轉(zhuǎn)換好的json放到body,效果是一樣的。

返回結(jié)果被一個Response接住,之后就可以用JsonPath獲取其中數(shù)據(jù)進(jìn)行驗證。當(dāng)然還有一種更直觀的辦法,可以通過 response.asString() 獲取完整的response,再反序列化成java對象進(jìn)行驗證。

至此,最基本的IT就完成了。 在Jenkins增加一個step gradle test 就可以實現(xiàn)每次提交代碼都進(jìn)行一次測試。

一些復(fù)雜的情況

數(shù)據(jù)混雜

這是最容易發(fā)生,一個項目有很多dev,每個dev都會寫自己的IT case,那么如果數(shù)據(jù)之間產(chǎn)生了影響怎么辦。很容易理解,比如一個測試批量寫的場景,最后驗證方式是看寫的數(shù)據(jù)量是不是10w行。那么另外一個dev寫了其他的case恰好也新增了一條數(shù)據(jù)到這張表,結(jié)果變成了10w+1行,那么批量寫的case就跑不過了。

為了杜絕這種情況,我們采用每次跑完一個測試Class就將數(shù)據(jù)清空。既然是基于類的操作,可以寫一個基類解決。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({Profiles.ENV_IT})
public abstract class BaseIntegrationTest {
  private static JdbcTemplate jdbcTemplate;
  @Autowired
  public void setDataSource(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
  }
  @Value("${local.server.port}")
  protected int port;
  @Before
  public void setupEnv() {
    RestAssured.port = port;
    RestAssured.basePath = "/api";
    RestAssured.baseURI = "http://localhost";
    RestAssured.config = RestAssured.config().httpClient(HttpClientConfig.httpClientConfig().httpMultipartMode(HttpMultipartMode.BROWSER_COMPATIBLE));
  }
  public void tearDownEnv() {
    given().contentType(ContentType.JSON)
        .when().post("/auth/logout");
  }
  @AfterClass
  public static void cleanDB() throws SQLException {
    Resource resource = new ClassPathResource("/testdata/CleanDB.sql");
    Connection connection = jdbcTemplate.getDataSource().getConnection();
    ScriptUtils.executeSqlScript(connection, resource);
    connection.close();
  }
}

@AfterClass 中使用了jdbcTemplate執(zhí)行了一個CleanDB.sql,通過這種方式清除所有測試數(shù)據(jù)。

@Value("${local.server.port}") 也要提一下,因為端口是隨機的,那么Rest-Assured不知道請求要發(fā)到losthost的哪個端口上,這里使用 @Value 獲取當(dāng)前的端口號并設(shè)置到 RestAssured.port 就解決了這個問題。

共有數(shù)據(jù)怎么處理

跑一次完整的IT,可能需要經(jīng)歷數(shù)十個Class,數(shù)百個method,那么如果一些數(shù)據(jù)是所有case都需要的,只有在所有case都跑完才需要清除怎么辦?換句話說,這種數(shù)據(jù)清理不是基于 類 的,而是基于一次 運行 。比如初始用戶數(shù)據(jù),城市庫等等

我們耍了個小聰明,借助了 flyway

@Configuration
@ConditionalOnClass({DataSource.class})
public class UpgradeAutoConfiguration {
  public static final String FLYWAY = "flyway";
  @Bean(name = FLYWAY)
  @Profile({ENV_IT})
  public UpgradeService cleanAndUpgradeService(DataSource dataSource) {
    UpgradeService upgradeService = new FlywayUpgradeService(dataSource);
    try {
      upgradeService.cleanAndUpgrade();
    } catch (Exception ex) {
      LOGGER.error("Flyway failed!", ex);
    }
    return upgradeService;
  }
}

可以看到當(dāng)Profile是IT的情況下, flyway 會drop掉所有表并重新依次執(zhí)行每次的upgrade腳本,由此創(chuàng)建完整的數(shù)據(jù)表,當(dāng)然都是空的。在項目的test路徑下,增加一個版本極大的sql,這樣就可以讓 flyway 在最后插入共用的測試數(shù)據(jù),例如 src/test/resources/db/migration/V999.0.1__Insert_Users.sql ,完美的解決各種數(shù)據(jù)問題。

小結(jié)

用Spring boot內(nèi)置的測試服務(wù)可以很快速的驗證API,我現(xiàn)在都不用把服務(wù)啟動再通過人工頁面點擊來測試自己的API,直接與前端同事溝通好Request的格式,寫個Case就可以驗證。

當(dāng)然這種方式也有一個不足就是不方便對系統(tǒng)進(jìn)行壓力測試,之前在公司的API測試用例都是Jmeter寫的,做性能測試的時候會方便很多。

相關(guān)文章

  • Java實現(xiàn)Map遍歷key-value的四種方法

    Java實現(xiàn)Map遍歷key-value的四種方法

    本文主要介紹了Java實現(xiàn)Map遍歷key-value的四種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Ubuntu 使用Jni開發(fā)實例詳解

    Ubuntu 使用Jni開發(fā)實例詳解

    這篇文章主要介紹了Ubuntu 使用Jni開發(fā)實例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 關(guān)于SpringBoot禁止循環(huán)依賴解說

    關(guān)于SpringBoot禁止循環(huán)依賴解說

    這篇文章主要介紹了關(guān)于SpringBoot禁止循環(huán)依賴解說,Spring的Bean管理,文章圍繞主題展開詳細(xì)介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Java ArrayList的基本概念和作用及動態(tài)數(shù)組的機制與性能

    Java ArrayList的基本概念和作用及動態(tài)數(shù)組的機制與性能

    在Java中,ArrayList是一個實現(xiàn)了List接口的動態(tài)數(shù)組,它可以根據(jù)需要自動增加大小,因此可以存儲任意數(shù)量的元素,這篇文章主要介紹了探秘Java ArrayList的基本概念和作用及動態(tài)數(shù)組的機制與性能,需要的朋友可以參考下
    2023-12-12
  • Spring強大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求

    Spring強大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求

    這篇文章主要為大家介紹了Spring強大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • SpringBoot集成Solr實現(xiàn)全文檢索功能

    SpringBoot集成Solr實現(xiàn)全文檢索功能

    solr是一個現(xiàn)成的全文檢索引擎系統(tǒng), 放入tomcat下可以獨立運行, 對外通過http協(xié)議提供全文檢索服務(wù),這篇文章給大家介紹了SpringBoot集成Solr實現(xiàn)全文檢索功能,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • Java定義泛型接口和類的方法實例分析

    Java定義泛型接口和類的方法實例分析

    這篇文章主要介紹了Java定義泛型接口和類的方法,結(jié)合實例形式分析了泛型相關(guān)概念、原理及泛型接口與類的定義實現(xiàn)方法,需要的朋友可以參考下
    2019-08-08
  • 如何使用SpringMVC的消息轉(zhuǎn)換器設(shè)置日期格式

    如何使用SpringMVC的消息轉(zhuǎn)換器設(shè)置日期格式

    這篇文章主要介紹了如何使用SpringMVC的消息轉(zhuǎn)換器設(shè)置日期格式問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java的validation參數(shù)校驗代碼實例

    Java的validation參數(shù)校驗代碼實例

    這篇文章主要介紹了Java的validation參數(shù)校驗代碼實例,Validation參數(shù)校驗是指在程序運行中對傳進(jìn)來的參數(shù)進(jìn)行合法性檢查,以保證程序的正確性和安全性,需要的朋友可以參考下
    2023-10-10
  • Mybatis?Plus?QueryWrapper復(fù)合用法詳解

    Mybatis?Plus?QueryWrapper復(fù)合用法詳解

    這篇文章主要介紹了Mybatis?Plus?QueryWrapper復(fù)合用法詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。
    2022-01-01

最新評論