前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MeterSphere系列04-通过Multi-Part接口新建用例

MeterSphere系列04-通过Multi-Part接口新建用例

作者头像
Antony
发布2020-12-10 11:08:15
1.8K0
发布2020-12-10 11:08:15
举报
文章被收录于专栏:软件测试那些事

我来给MeterSphere写测试用例04

继续我们的MeterSphere之旅。在本小节中,将介绍如何在MeterSphere中创建测试用例。

源码分析

参考之前文章中介绍的方式,可以找到新建测试用例所对应的后端controller和方法。示例代码如下,

代码语言:javascript
复制
 package io.metersphere.track.controller;
 
 
 @RequestMapping("/test/case")
 @RestController
 @RequiresRoles(value = {RoleConstants.ADMIN, RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER, RoleConstants.ORG_ADMIN}, logical = Logical.OR)
 public class TestCaseController {
 
     @Resource
     TestCaseService testCaseService;
 
     @PostMapping(value = "/add", consumes = {"multipart/form-data"})
     @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
     public void addTestCase(@RequestPart("request") EditTestCaseRequest request, @RequestPart(value = "file") List<MultipartFile> files) {
         testCaseService.save(request, files);
     }
 }

除了URL、POST、角色等等之前已经介绍过的内容之外,这个接口中出现了不同的内容那个。

代码语言:javascript
复制
  @PostMapping(value = "/add", consumes = {"multipart/form-data"})

首先是接口类型的注解中,首次出现了consumes = {"multipart/form-data"}这样的属性。这种接口主要是用于上传文件与等服务器交互的操作 。通过在 MeterSpher 在线体验环境: https://demo.metersphere.com/ (账号:demo 密码:P@ssw0rd123..)上的试验操作,可以发现MeterSphere的确允许在新建用例的同时上传用于进一步描述用例的附件,且可以上传多个。如下图所示,

Multipart/form-data是基于Post的请求,不过与普通Post的请求体不同的是它的构造方式 。普通的Post的请求体是简单的name=value组成的列表 , 而Multipart/form-data则是添加了分隔符等内容的构造体。因此,需要进一步来观察这个接口来了解具体的组成。

在接口的入参中,有如下的两个注解,分别表示一种为字符串类型参数,另一种为文件类型参数。

代码语言:javascript
复制
 @RequestPart("request") EditTestCaseRequest request, @RequestPart(value = "file")

这说明, 这个Multipart的结构体有两部分组成

  • request , 这是一个key=request,value是一个序列化之后的EditTestCaseRequest实例的二进制
  • file, 表示从客户端上传的文件

所以,这个接口的请求体一部分是和普通post一样的JSON对象,用于表述测试用例自身的属性,另外一部分则是用于上传这个用例的附件。

测试用例

以下用例用于在MeterSphere中新建一个测试用例。

代码语言:javascript
复制
   @Order(3)
     @Test
     @DisplayName("03用例-新建用例")
     public void addTestCase() throws Exception {
     testCase.setName("case-"+getRandom());
     testCase.setMaintainer("admin");
     testCase.setProjectId(project.getId());
     testCase.setNodeId(testCaseNode.getId());
     testCase.setMethod("manual");
     testCase.setPriority("P3");
     testCase.setType("functional");
     testCase.setNodePath("/"+testCaseNode.getName());
      String result=   doPostMultipartFormData("/test/case/add",getTestCaseRequest(getEditTestCaseRequest(testCase)),null);
         assertThat(result).contains("true");
         result=doGet("/test/case/recent/1");
         List<TestCase> testCases= JSON.parseArray(String.valueOf(JSON.parseObject(result,ResultHolder.class).getData()),TestCase.class);
         assertThat(testCases).isNotEmpty();
         testCase=testCases.get(0);
 
     }

上述只是一个简化的示例,主要是展示了如何将一个TestCase实例序列化后塞进Multi-Part类型的请求体中,并通过Post方式发送给后端服务接口。由于附件只是一个测试用例的可选项,请注意此案例并没有上传附件。

Multi-Part接口封装

从测试用例中可以看到,上述需求可以通过封装一个类似doPost的方法来实现,在这里作为示例的是一个doPostMultipartFormData的方法。它接受URL,以及两个MockMultipartFile类型的入参。

代码语言:javascript
复制
     public String doPostMultipartFormData(String url, MockMultipartFile file, MockMultipartFile anotherFile) throws Exception {
         return mockMvc.perform(
                 MockMvcRequestBuilders.multipart(url)
                       .file(file)
                      //   .file(anotherFile)
                 .contentType("multipart/form-data")
                 .session(session)
         )
                 .andDo(print())         //打印出请求和相应的内容
                 .andExpect(status().isOk())    //返回的状态是200
                 .andReturn().getResponse().getContentAsString();
     }

MockMvc的MockMvcRequestBuilders提供了专门的multipart方法来构建这样的请求。按照之前提到的由于是简化用例,并不提供附件,因此接收附件的第二个MockMultipartFile类型的入参并没有被使用。

接下来问题则是,如何将普通的TestCase序列化之后的字符串转换成这个接口能够接受的MockMultipartFile类型,并命名为"request"。

因此,有如下的一个私有方法用来转换

代码语言:javascript
复制
     private MockMultipartFile getTestCaseRequest(EditTestCaseRequest request){
         return new MockMultipartFile("request", "", "application/json", JSON.toJSONString(request).getBytes());
     }

由于MockMultipartFile只接受二进制的内容,因此需要将TestCase序列化之后再转换成二进制。这里还需要指出一下,"application/json"是必须指定的,不然在后端接口进行解析时会导致TestCase会反序列化失败。

执行结果

以下是通过

代码语言:javascript
复制
 mockMvc.andDo(print())

打印出的请求和响应。

代码语言:javascript
复制
 MockHttpServletRequest:
       HTTP Method = POST
       Request URI = /test/case/add
        Parameters = {}
           Headers = [Content-Type:"multipart/form-data"]
              Body = <no character encoding set>
     Session Attrs = {}
 
 Handler:
              Type = io.metersphere.track.controller.TestCaseController
            Method = io.metersphere.track.controller.TestCaseController#addTestCase(EditTestCaseRequest, List)
 
 Async:
     Async started = false
      Async result = null
 
 Resolved Exception:
              Type = null
 
 ModelAndView:
         View name = null
              View = null
             Model = null
 
 FlashMap:
        Attributes = null
 
 MockHttpServletResponse:
            Status = 200
     Error message = null
           Headers = [Content-Type:"application/json"]
      Content type = application/json
              Body = {"success":true,"message":null,"data":null}
     Forwarded URL = null
    Redirected URL = null
           Cookies = []

可以看到响应中"success":true,表示用例被成功地创建了。比较遗憾的是响应结构体中的data部分并没有返回类似TestCase id之类的信息。为了能够让整个旅程能继续下去,需要得到刚才新建的测试用例ID。因此需要额外通过查询接口来获取到最近一个用例,也就是刚才新建的用例。

代码语言:javascript
复制
 result=doGet("/test/case/recent/1");
 List<TestCase> testCases= JSON.parseArray(String.valueOf(JSON.parseObject(result,ResultHolder.class).getData()),TestCase.class);
 assertThat(testCases).isNotEmpty();
 testCase=testCases.get(0);

此处,建议MeterSphere团队能够优化一下这个接口。

小节一下

”multipart/form-data"类型的请求是基于Post的一种特殊请求,一般用于文件上传,同时支持传输额外的数据。

MockMvc的MockMvcRequestBuilders提供了专门的multipart方法来支持”multipart/form-data"类型的请求。

如果@RequestPart("request")是一个对象,则在构建MockMultipartFile实例时,contentType需要指定为"application/json"。

MockMVC提供了MockMvcResultHandlers.print方法来打印请求和应答。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 我来给MeterSphere写测试用例04
    • 源码分析
      • 测试用例
        • Multi-Part接口封装
          • 执行结果
            • 小节一下
            相关产品与服务
            文件存储
            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档