01 什么是Swagger
官方定义:Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
简单点说:就是开发人员用代码来实现基于实时测试的功能更强大的接口文档。
02 Swagger的优点与缺点
优点:a).更优美的图形化接口文档展示,可以随时尝试基于接口的调用来验证参数。
b).避免后端开发,前端开发,测试之间花费过多的精力在接口参数的沟通上。
c).配合合适的测试工具例如(PostMan/SoupUI等)可以实现自动化测试解决方案。
缺点:a).通过注释方式实现,对代码有稍许侵入性。
b).开发人员的不专业可能会导致注释的请求参数和实际参数不一致,导致接口文档的不准确
03 基于SpringBoot + Swagger2 的实现
举例实现基于Web MVC的(由于SpringBoot2实现了WebFlux的非阻塞风格web框架,故以下方案只适用于基于Web MVC风格的项目实现)整个闭环。
Step1:引入Gradle依赖,采用2.7.0版本
Step2:引入Configuration配置。
此处注意:
1).如果采用了MVC异步模式,注意在初始化对应组件时添 加.genericModelSubstitutes(DeferredResult.class)来避免对返回参数的解析不规范的问题。
2),目前行内有许多接口文档是维护在ShowDoc上的,我们可以在初始化的时候把对应的链接加入到我们的Swagger首页上.termsOfServiceUrl(XXXXX).
Step3:在对应的Controller层添加对应Annotation,并对应标注,主要需要用的参数如下:
//类级别
@Api:用在请求的类上,表示对类的说明
//方法级别注释
@ApiOperation:用在请求的方法上,说明方法的用途、作用
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
//请求/返回对象类级别
@ApiModel:用于响应类上,表示一个返回响应数据的信息
//请求/返回对象属性级别
@ApiModelProperty:用在属性上,描述响应类的属性
截图详细解释如下:
Step 4:所有代码层面改动已经完成了,编译启动项目,然后通过项目URL+特定后缀就可以访问了,例如项目根目录是 127.0.0.1:8080/xxx,那么启动后Swagger对应链接是127.0.0.1:8080/xxx/swagge-ui.html
进入首页详情,显示Configuration中配置各项参数以及抓取的Controller层各个请求入口列表(此处是系统自动,不是手动配置各个Controller)
点击任意一个描述链接,展开当前controller下所有接口
点击任意一个具体接口,展示所有详细请求参数,根据之前的配置来说 ,@RequestHeader/@RequestParam/@PathVariable通过@ApiImplicitParam来捕捉,而@RequestBody/@ResponseBody通过@ApiModel来捕捉
此接口文档界面可以实时尝试系统的返回结果,通过填写请求参数,点击 try it out!
点击完成以后,系统会实时给出请求具体参数与返回具体参数:
04 在生产中禁用Swagger
在配置文件中添加参数
#Swagger开关
SWAGGER.ENABLE = true
在配置类中添加配置:
@Value() swaggerEnable@Override addResourceHandlers(ResourceHandlerRegistry registry) { (swaggerEnable) { System.out.println(swaggerEnable)registry.addResourceHandler() .addResourceLocations()registry.addResourceHandler() .addResourceLocations()} }
在配置中添加@Profile注解,如果只对sit环境生效,那么我们就添加参数如下
@EnableSwagger2 @Profile() Swagger2 WebMvcConfigurationSupport { @Bean Docket createRestApi() { Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage()) .paths(PathSelectors.any()) .build()} ApiInfo apiInfo() { ApiInfoBuilder() .title() .contact(Contact()) .version() .description() .build()} @Override addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler().addResourceLocations( )registry.addResourceHandler().addResourceLocations( )} }
05 基于PostMan的自动化测试解决方案。
Swagger的首页有个导出接口提示,如下图,其链接适用于导出所有接口到PostMan/SoupUI中,且一键生成(此处是开发和测试的福音!),以下用PostMan演示:
找到API对应后缀
在PostMan中导入操作中输入对应链接
点击完成,发现所有接口已经自动按照需求自动导入Postman!
以下为如何在PostMan中完成自定义的一个测试化用例,以用户登录并且领卡为例:
注意:PostMan的Tests标签页的语法本质上是Js,如需完成一个测试用例的编写,需要测试人员掌握一定的前端语法(只需部分简单语法即可)。如果的确不了解,问题也不大,选中Tests的Tab以后,可以看到右边有很多的snippets,各种现成的Assertion已经准备好了,如返回代码,是否match特定内容,是否特定包含某部分内容等等。90%的需求都可以满足。
Step1:创建一个新的Colletion,命名为项目--测试用例集,然后在Collection中创建子文件夹,每个文件夹代表一个测试用例。从之前导入的接口中运用save as 按钮把需要的接口导入到对应的测试用例文件夹中,然后选取合适的snippets来完成Assertion,完成单个测试用例的编写,然后点击Collection右上角,Run。
Step2:点击Run按钮以后,会跳转到对应的Runner组件,选取对应的测试案例,直接点击运行。
Step3:运行完毕,系统会给出这个测试案例根据编写的Tests验证具体内容的验证结果(成功个数,失败个数,返回结果,耗时等等),以及这个测试案例涉及到的所有接口顺序验证的内容结果,我们可以根据预期来判断是否验证通过。相比于目前零售端的人力验证测试案例,功能回归可以从天级别的回归缩短到分钟级别的回归。
06 基于以上实现的总结
从实现难度上来说,本套整体实施方案并不复杂,只是需要前后端开发+测试的协同合作即可,前期花一定的时间改造,会对后期的生产力提高起到巨大的帮助,尤其是整个测试周期的缩短,迭代周期的降低起到巨大的帮助。而且整套方案具有可移植性,方便套用到其他任何项目中去。