快速测试 SpringMvc 接口, 跟 PostMan 说再见! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cweijan
V2EX    Java

快速测试 SpringMvc 接口, 跟 PostMan 说再见!

  •  
  •   cweijan
    cweijan 2020-06-01 14:52:05 +08:00 4796 次点击
    这是一个创建于 2034 天前的主题,其中的信息可能已经有所发展或发生改变。

    做 Java 开发 3 年了, 每次想要测试开发完的接口总是有点头疼, 要复制 url, 又要写测试参数, 为了解决这些烦恼, 我开发了一个快速测试的工具, 直接面向 controller 测试. 项目地址 https://github.com/cweijan/http-test

    example:

    1. 增加依赖
    <dependency> <groupId>io.github.cweijan</groupId> <artifactId>http-test</artifactId> <version>0.0.3</version> <scope>test</scope> </dependency> 
    1. 假设有以下 controller, 启动 springboot 应用
    @RestController @RequestMapping("/user") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @PostMapping("/save") public UserVo saveUser(@RequestBody SaveUserDTO saveuserDTO) { return userService.saveUser(saveuserDTO); } @PostMapping("/update") public UserVo updateUser(@RequestBody UpdateUserDTO updateuserDTO) { return userService.updateUser(updateuserDTO); } @GetMapping("/{userId}") public UserVO getUser(@PathVariable Integer userId) { return userService.getUser(userId); } @DeleteMapping("/{userId}") public void deleteByUserId(@PathVariable Integer userId) { userService.deleteByUserId(userId); } } 
    1. 创建测试用例, 开始测试
    import io.github.cweijan.mock.Asserter; import io.github.cweijan.mock.jupiter.HttpTest; import io.github.cweijan.mock.request.Generator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import javax.annotation.Resource; @HttpTest(host = "localhost",port = 8080) public class UserControllerTest { //仅支持注入 controller 和 feignClient @Resource private UserController userController; @BeforeAll public static void addToken(){ //配置全局拦截器 Mocker.addRequestInterceptor(template -> { template.header("token","c2f678d4873c472c8f99940e8cf39fe4"); }); } // 注意, 必须使用 junit5: org.junit.jupiter.api.Test @Test void saveUser() { //创建 mock 数据 SaveUserDTO saveUserDTO = Generator.request(SaveUserDTO.class); // 当调用方法时会直接发送 http 请求 UserVo userVo=userController.saveUser(saveUserDTO); UserVO user = userController.getUser(userVo.getId()); Asserter.assertSame(userVo,user); userController.deleteByUserId(userVo.getId()); } } 

    SpringBootTest 也可以实现该测试, 但需要启动 spring 容器, 耗时实在太久, 该方式毫秒级即可运行完测试.

    19 条回复    2020-06-02 16:15:52 +08:00
    zoharSoul
        1
    zoharSoul  
       2020-06-01 15:09:04 +08:00
    感觉挺有意思的...
    gengz
        2
    gengz  
       2020-06-01 15:11:10 +08:00   2
    我选择 swagger
    zhazi
        3
    zhazi  
       2020-06-01 15:13:00 +08:00 via Android
    这东西需要启动项目,就是个 httpclient,完全没达到测试的目的,不能保证可重复性,测试完数据库一堆脏数据,那你这就是不合格的测试工具啊
    cweijan
        4
    cweijan  
    OP
       2020-06-01 15:15:36 +08:00
    @gengz 我们公司现在是有用 yapi 搭建文档, 存在以下问题:
    1. 无法快速定位到接口进行调用
    2. 创建测试用例组太麻烦, 比如我要保存用户后立刻测试更新用户
    3. 对接口结果进行断言验证
    你可以试下, 很方便的
    zhazi
        5
    zhazi  
       2020-06-01 15:15:50 +08:00 via Android
    如果在服务已经启动的情况下 mockmvc 就可以提供 api 访问了,不需要对 spring 容器初始化
    cweijan
        6
    cweijan  
    OP
       2020-06-01 15:16:13 +08:00
    @zhazi 就是给后端人员进行接口自测的
    cweijan
        7
    cweijan  
    OP
       2020-06-01 15:17:44 +08:00
    @zhazi mockmvc 我也是有看过, 构建太麻烦, 写这个主要是为了减少学习成本并能够快速进行接口自测
    chendy
        8
    chendy  
       2020-06-01 15:19:18 +08:00
    因为要拉应用起来,然后跑测试去调用,所以已经不是单元测试而是集成测试了…
    当然如果 lz 是针对自己的使用场景开发的工具,那也是极好的,就是不一定适合别人了
    cweijan
        9
    cweijan  
    OP
       2020-06-01 15:30:00 +08:00
    @chendy 确实属于集成测试, 主要是没有更好的接口自测方案, 都是人肉调用 http, 而这个可以让后端人员直接面向 controller 进行测试
    efaun
        10
    efaun  
       2020-06-01 16:17:33 +08:00
    JB 有个插件更方便,RestfulToolkit
    hantsy
        11
    hantsy  
       2020-06-01 17:03:10 +08:00   2
    一年到头,难得 V 站上有人讨论测试。

    Spring Boot 默认 test-starter 除了自己提供对 JUnit 等集成外,还包括大量第三方测试工具。
    用于 REST APIs 的 包括 MockMVc,TestRestTemplate,WebTestClient,这个 starter 加入流行的测试工具的 Dep,Mockito, AssertJ,JSONPath 等,另外自己可以添加 RestAssured 提供 REST APIs 的 BDD 测试体验。

    对于环境依赖,Spring 提供一系列 @AutoConfigure/@DataJpaTest 等测试 Slices 等,不必加载个 Context 。对于外部数据库等依赖,现在 TestContainers 是不错的选择,将来 Spring Boot 会它代替 embedded mongo 等。

    对于服务与之间测试,Spring WebMvc 提供了 MockServer ( Mock 远程服务),另外 Spring Cloud Contract 提供了 CDC 模式测试。

    不得不说 Spring Security 5 在测试 OAuth2,Oidc 很大的改进,现在 resource server 可以在 Mock 环境下测试。

    @cweijan 如果说速度,集成环境加载的资源太多, 什么方法快不了(跑整个集成测试的任务,应该在 CI 上进行)。只有 Mock 环境可以加快测试运行速度。

    集成测试: https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/test/java/com/example/demo/IntegrationTests.java

    单独测试 Controller ( Mock 环境): https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/test/java/com/example/demo/PostControllerTest.java

    从你的代码片断,我没看出来你这个项目有多少实用性。当然任何创作值得鼓励。
    hantsy
        12
    hantsy  
       2020-06-01 17:07:51 +08:00
    https://github.com/hantsy/spring-microservice-sample/tree/master/post-service/src/test/java/com/hantsylabs/sample/springmicroservice/post 提供了传统 Spring WebMvc 的测试,包括大部分 Spring Boot 提供的测试工具。
    hantsy
        13
    hantsy  
       2020-06-01 17:18:13 +08:00
    你这个项目 https://github.com/cweijan/http-test 的测试代码呢?没有提交?
    cweijan
        14
    cweijan  
    OP
       2020-06-01 17:26:18 +08:00
    @hantsy 看来你对测试研究的很深, 佩服, 我的目的很简单, 想要快速测试我写的 controller, 我使用 @SpringBootTest 之后, 启动太久, 没法快速测试我的接口, 而公司也没有要求要写测试用例, 测试用例仅仅是用来自测的, 这个库其实就是个 http client, 用来替换 postman 和 yapi.
    cweijan
        15
    cweijan  
    OP
       2020-06-01 17:27:14 +08:00
    @hantsy 测试代码我没有提交, 你有兴趣的话在本地试下.
    cweijan
        16
    cweijan  
    OP
       2020-06-01 17:28:14 +08:00
    @hantsy 其实重点就在于快
    hantsy
        17
    hantsy  
       2020-06-01 20:48:11 +08:00
    @cweijan 你这个只是 Client View 来测试,仅仅测试功能而已。从测试金字塔来看,在最顶端。没有大量的基础单元测试,代码质量同样很脆弱。

    https://martinfowler.com/bliki/TestPyramid.html
    CoderGeek
        18
    CoderGeek  
       2020-06-01 20:52:53 +08:00
    从体来说 内部测试与 postman 这种还是不大一样 本身 postman 这种也有扩展工具
    JarvisRay
        19
    JarvisRay  
       2020-06-02 16:15:52 +08:00
    还是 postman 吧,swagger 也集成了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1326 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 17:00 PVG 01:00 LAX 09:00 JFK 12:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86