懶出天際~基於swagger和postman的接口測試平臺

前言

近年微服務盛行,若是沒有進行理性合理的切分服務之間的邊界,很容易致使接口膨脹,這是通病!
基於spring-cloud微服務體系openFeign組件來暴露接口(Restful),說白了就是暴露了一堆又一堆的Http接口(跨語言嘛)前端

Api接口的維護歷程
本人經歷過以下幾個api接口維護的工具vue

說說這幾個的優缺點吧java

Rap                    這特麼就是阿里一個KPI項目 手動維護接口,開發完代碼還得本身編寫接口
Postman             強大,很強大 測試很強大,但仍是得手動維護接口
Swagger 2.x比1.x改進很多  自動生成接口頁面,但不能歸檔和前置腳本,全部參數必須人工錄入,不能複用

問題來了
1,前置數據處理怎麼辦?後置數據驗證怎麼辦?
    postman能夠作前置參數處理,不能作後置驗證
2,測試結果怎麼歸檔?
    swagger自己就是一個網頁版的快捷測試頁面,瀏覽器關掉就沒了
3,每次精心準備了數據只能測試一次?
    玩呢?mysql

 

開發了一個基於golang+vue版原本整合swagger+postman基本功能來解決問題
中國有句古話:是騾子是馬拉出來溜溜,hinny 翻譯:驢騾;公馬和母驢所生的騾子
即接口是好是仍是壞拿出來測測linux

 

項目地址:
項目:https://github.com/otk-final/hinny(後端)
項目:https://github.com/otk-final/hinny-ui(頁面)webpack

準備環境
數據庫:mysqlgit

建立數據表
執行db.sql文件,三張表(空間,模板,日誌)配置文件見工程config/conf.toml文件es6

運行
由於go能夠直接將應用程序打包成可執行文件,前端頁面沒有采用分離部署,已將前端所需頁面webpack打包至hinny-ops\static目錄下方便統一部署
將hinny-ops目錄下文件拷貝至運行機器,執行便可window下執行hinny.exe便可,linux執行hinny_linux便可(目前只打包了64位系統運行文件)github

相關頁面golang

1工做空間

  

微服務開發中,不一樣開發人員可能同時並行開發,進行本地測試,在開發人員未提交正式測試環境前,可切換至對方空間進行接口測試,即遠程調用開發者本地機器,接口有變更在平臺上進行接口同步便可(保證目標服務正常運行,即能正常提供接口)

建議:同一項目,項目名稱保持一致,不一樣運行環境保持命名空間不一致

例:請求地址:http://192.168.30.1:8080 是接口調用地址

例:接口地址:http://192.168.30.1:8080/v2/api-docs 是swagger暴露出的接口地址以下圖

 

每一個空間支持配置默認腳本,在接口調用時會將當前空間默認腳本回填到驗證腳本中

2服務列表

3接口列表

 

請求參數分爲4個部分

請求頭 http-header 自定義報文頭(能夠經過腳本添加自定義頭)
URI參數 url路徑上的變量

http://localhost:8080/{version}/user/{id}

http://localhost:8080/v1/user/12345

請求參數 ?para1=&para2= url後續拼接的參數

http://localhost:8080/v1/user?keyword={keyword}

http://localhost:8080/v1/user?keyword=關鍵字

報文體  body中的參數 json(目前只支持json)
驗證腳本     以js腳本爲準 

init:作前置初始化函數

testing:後置驗證函數

$appendResult 驗證結果工具方法

詳情見示例截圖

4接口詳情

    

腳本編輯

   

接口測試完成後,能夠對當前記錄進行歸檔操做,下次在執行記錄中進行復用

5執行記錄

 

spring-boot項目搭建 項目搭建

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>example</groupId>
    <artifactId>example-parent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>
    
    <properties>
        <swagger.version>2.9.2</swagger.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
    </dependencies>
</project>

 

啓動類

@SpringBootApplication
@EnableSwagger2
public class ExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }


    /**
     * 開啓swagger便於生成文檔
     *
     * @return
     */
    @Bean
    public Docket docket() {
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(
                        new ApiInfoBuilder()
                                .title("接口文檔")
                                .description("當前API版本" + "v1")
                                .version("v1")
                                .build())
                .select().apis(RequestHandlerSelectors.basePackage("com.example"))
                .build()
                .globalOperationParameters(Arrays.asList(
                        new ParameterBuilder().name("tenantId").parameterType("header")
                                .modelRef(new ModelRef("string")).description("租戶ID(全局請求頭)").build(),
                        new ParameterBuilder().name("userId").parameterType("header")
                                .modelRef(new ModelRef("long")).description("用戶ID(全局請求頭)").build(),
                        new ParameterBuilder().name("token").parameterType("header")
                                .modelRef(new ModelRef("string")).description("用戶登陸TOKEN(全局請求頭)").build()
                ))
                .enable(true);
        return docket;
    }
}

RestController暴露接口 

@Api(description = "示例接口")
@RestController
public class ExampleController {

    @ApiOperation("添加數據")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1,v2", required = true)
    @PostMapping("{version}/pv/example/post")
    public Boolean post(@RequestHeader("userId") Long userId, @RequestBody SimpleDto body) {

        return true;
    }

    @ApiOperation("查詢數據")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1,v2", required = true)
    @GetMapping("{version}/pv/example/{id}")
    public SimpleDto get(@RequestHeader("userId") Long userId, @PathVariable("id") int id) {
        SimpleDto out = new SimpleDto();
        out.setName("名稱");
        out.setTags(Lists.newArrayList("標籤1", "標籤2", "標籤3"));
        return out;
    }

    @ApiOperation("更新數據")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1,v2", required = true)
    @PutMapping("{version}/pv/example/post")
    public Boolean put(@RequestHeader("userId") Long userId, @RequestBody SimpleDto body) {

        return true;
    }

    @ApiOperation("刪除數據")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1,v2", required = true)
    @DeleteMapping("{version}/pv/example/{id}")
    public Boolean delete(@RequestHeader("userId") Long userId, @PathVariable("id") int id) {

        return true;
    }

}
@Api(description = "用戶接口")
@RestController
public class UserController {


    @ApiOperation("用戶登陸")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1", required = true)
    @PostMapping("{version}/pv/user/login")
    public Map<String, String> login(@RequestParam("loginName") String loginName,
                                     @RequestParam("passWord") String password) {

        Map<String, String> out = new HashMap<>();
        out.put("loginName", loginName);
        out.put("passWord", password);

        return out;
    }


    @ApiOperation("查詢-(實體)")
    @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1", required = true)
    @GetMapping("{version}/pv/user/get-by-obj")
    public List<SimpleDto> query(QueryDto query) {

        return null;
    }


    @ApiOperation("查詢-(參數)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "version", paramType = "path", allowableValues = "v1", required = true),
            @ApiImplicitParam(name = "keyword", paramType = "query", allowableValues = "*", required = true),
            @ApiImplicitParam(name = "phone", paramType = "query", allowableValues = "13100000001", required = true)
    })
    @GetMapping("{version}/pv/user/get-by-param")
    public List<SimpleDto> query(@RequestParam("keyword") String keyword, @RequestParam("phone") String phone) {

        return null;
    }
}

 

Feature

  1. 驗證腳本暫不支持外部js文件引入,
  2. 驗證腳本是基於golang環境執行,暫不支持頁面調試,全部腳本編寫時基於es6相關規範,避免錯誤
  3. 目前報文體只支持json格式數據,其餘暫不支持
  4. swagger接口暫未解析全面,平常開發中基於swagger註解配置的接口,如上圖配置均能實現,還有不少swagger原生測試頁面元素並未集成進來,如元數據文檔
  5. 暫不支持文件上傳接口

本項目不屬於生產項目,只是基於本地開發測試,純屬當作工具使用,望指點~~~

freestyle ... 你看這個輪子它又大有圓!!!!

相關文章
相關標籤/搜索