亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

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

2024-07-14 08:40:06
字體:
來源:轉載
供稿:網友

如果希望很方便針對API進行測試,并且方便的集成到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時的一些配置,上述代碼是用了隨機端口,當然也可以預定義端口,像這樣

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

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

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

測試一個Rest API

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

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

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

@Sql(scripts = "/testdata/users.sql")@Testpublic 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 用于在測試前執行sql插入測試數據。注意 given().body() 中傳入的是一個java對象 JwtAuthenticationRequest ,因為rest-assured會自動幫你用 jackson 將對象序列化成json字符串。當然也可以將轉換好的json放到body,效果是一樣的。

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

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

一些復雜的情況

數據混雜

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

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

@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執行了一個CleanDB.sql,通過這種方式清除所有測試數據。

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

共有數據怎么處理

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

我們耍了個小聰明,借助了 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;  }}

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

小結

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

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


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成aaa人片免费看| 久久影院在线观看| 亚洲欧美日韩中文视频| 亚洲乱码国产乱码精品精天堂| 久热精品视频在线观看| 91九色综合久久| 久久久久久久久久av| 午夜免费在线观看精品视频| 日韩一区二区三区xxxx| 亚洲国产精品福利| 欧美极度另类性三渗透| 亚洲成人激情小说| 久久艳片www.17c.com| 欧美福利视频网站| 人妖精品videosex性欧美| 亚洲高清色综合| 亚洲欧美国产高清va在线播| 欧美成人合集magnet| 欧美午夜精品伦理| 成人激情视频小说免费下载| 亚洲国产成人在线播放| 亚洲日韩欧美视频| 欧美片一区二区三区| 国模gogo一区二区大胆私拍| 亚洲精品动漫100p| 秋霞av国产精品一区| 丝袜亚洲另类欧美重口| 日韩av在线网页| 国产精品网站视频| 亚洲欧美激情在线视频| 91精品久久久久久久久| 日韩av三级在线观看| 欧美在线精品免播放器视频| 久久免费视频网站| 精品国产依人香蕉在线精品| 国产精品av电影| 亚洲无限av看| 91九色精品视频| 色播久久人人爽人人爽人人片视av| 亚洲性猛交xxxxwww| 久久伊人91精品综合网站| 亚洲欧美一区二区三区在线| 日本精品久久久久久久| 日韩在线视频一区| 国产精品91在线观看| 57pao成人国产永久免费| 亚洲成人网在线观看| 亚洲福利在线播放| 国产欧美精品在线播放| 欧洲中文字幕国产精品| 亚洲免费视频网站| 欧美激情一区二区三区久久久| 亚洲国产天堂久久综合网| 国产视频亚洲视频| 亚洲网站视频福利| 欲色天天网综合久久| 国产精品一区二区久久久| 日韩免费观看在线观看| 日本19禁啪啪免费观看www| 精品国产自在精品国产浪潮| 一本大道亚洲视频| 国产精品高潮粉嫩av| 日韩电影中文字幕| 91人人爽人人爽人人精88v| 亚洲专区在线视频| 亚洲另类xxxx| 日韩av中文字幕在线免费观看| 国产人妖伪娘一区91| 国产国语刺激对白av不卡| 国产美女搞久久| 国产精品aaa| 国产精品678| 国产亚洲精品美女久久久久| 欧美精品在线免费| 欧美疯狂做受xxxx高潮| 国产精品亚洲综合天堂夜夜| 在线播放国产精品| 欧美日韩一区免费| 亚洲视频综合网| 亚洲一级一级97网| 狠狠躁夜夜躁久久躁别揉| 日本不卡高字幕在线2019| 草民午夜欧美限制a级福利片| 日本一区二区三区四区视频| 色综合伊人色综合网站| 亚洲大胆人体在线| 国产亚洲aⅴaaaaaa毛片| 久久的精品视频| 欧美一级高清免费播放| 91沈先生作品| 久久精品美女视频网站| 日韩电影中文字幕一区| 久久99久久久久久久噜噜| 成人福利网站在线观看11| 亚洲色图色老头| 国产精品久久久| 日韩影视在线观看| 欧美极品少妇xxxxⅹ免费视频| 日韩极品精品视频免费观看| 国产成人精品久久二区二区| 久久色精品视频| 91亚洲国产成人精品性色| 亚洲女人被黑人巨大进入| 国外色69视频在线观看| 日韩综合中文字幕| 亚洲理论片在线观看| 亚洲视频在线播放| 97香蕉久久夜色精品国产| 久久人体大胆视频| 国产精品久久久久久搜索| 成人av色在线观看| 国产成人精品久久二区二区91| 亚洲人成毛片在线播放| 色偷偷噜噜噜亚洲男人| yellow中文字幕久久| 日韩一区二区久久久| 中文字幕国产精品久久| 国产精品91免费在线| 国产日韩在线观看av| 久久久精品一区二区三区| 亚洲国产精品高清久久久| 亚洲午夜色婷婷在线| 91精品啪在线观看麻豆免费| 成人av.网址在线网站| 亚洲成色999久久网站| 欧美夫妻性生活xx| 欧美怡红院视频一区二区三区| 美女福利精品视频| 日韩欧美一区二区三区久久| 欧美老肥婆性猛交视频| 亚洲小视频在线观看| 欧美日韩亚洲视频一区| 成人激情在线观看| 中文字幕在线看视频国产欧美在线看完整| 成人444kkkk在线观看| 亚洲国产精品悠悠久久琪琪| 国产精品丝袜久久久久久不卡| 国产一区二区三区在线播放免费观看| 国产成人在线播放| 久久亚洲精品中文字幕冲田杏梨| 国产精品综合不卡av| 日韩欧美在线看| 欧美激情区在线播放| 97涩涩爰在线观看亚洲| 日韩欧美主播在线| 岛国av在线不卡| xxx一区二区| 亚洲网址你懂得| 北条麻妃一区二区在线观看| 亚洲精品国产品国语在线| 久久久成人av| 日韩精品在线免费观看视频| 精品国产1区2区| 国产精品video| 精品中文字幕久久久久久| 亚洲欧美国内爽妇网| 国产精品永久免费观看| 国产精品一久久香蕉国产线看观看| 国产精品高清在线观看| 精品久久久一区| 91在线中文字幕| 国产主播喷水一区二区| 亚洲肉体裸体xxxx137| 久久久久久久久久国产|