GOURD
=======
## About
- API Automation Framework For Testing Http Restful API
- We use 'gourd' to remember its developers whose first name are 'Hu' and 'Lu'

## Usage

### csv字段说明

**必填字段**

以下字段框架自动生成，按顺序填写，不可删除或变更顺序
- CaseId：case序号，必填，unique
- Desc: 用例描述
- apiName: API 接口路径，如：/api/v1/orgs/{org_id}/me
- method: http请求method，如get，post，delete
- isNeed: 这个case是否需要运行，填写：N、Y

**可选字段**

请求参数
- apiPath.{key} : 可有多个。用于apiPath中的变量设置，key需和API接口路径中设定保持一致。如：/api/v1/orgs/{org_id}/me，可以用apiPath.org_id对path变量进行case设计
- apiParam.{key}: 可有多个。用于api参数设定，如/api/v1/orgs/me?email=xxx&name=xxx, email和name即为param,可以用apiPath.email、apiPath.name对param进行case设计
- apiHeader.{key}:可有多个。用于请求header设定

返回结果
- status: 期望返回的请求结果码，如200，401，500。如设定，框架会默认进行校验。默认为200
- expectJson.{key}:可期望返回的json字段中某个key的值。如设定，框架会默认进行校验,校验类型为string
- expectJsonInt.{key}:同上，校验int类型的json字段值
- expectJsonBoolean.{key}:同上，校验boolean类型的json字段值
- expectJsonExist.{key}:校验某个json字段是否存在

严重性
- severity: 定义该case的严重性，支持blocker，critical，normal，minor，trivial五个等级，默认为normal

**重试次数**
重试次数可以通过两种方式定义
- 全局定义：在conf中有retry字段，默认为0，即不重试
- 单独定义：可针对每个case设置不同的重试次数，case的retry字段可为空，表示使用全局定义。
示例：

| caseNo | desc | apiName | method | isNeed | retry | status | severity
  | ----  |  ----  |  ----  |  ----  |  ----  |  ----  |  ----  | ---- |
| 1 | case1 | /api/getInfo | GET | Y | 2| 404 | minor
| 2 | case2 | /api/getInfo | GET | Y | 1| 200| 
| 3 | case3 | /api/getInfo | GET | Y | | 200 | trivial

case1期望得到返回值404，否则重试2次

case2期望得到返回值200，否则重试1次

case3期望得到返回值200，否则根据全局定义重试

**动态参数添加**

存在某些参数每次请求试需要动态生成，如header中的token。我们在setup方法中，加入对象注册，在csv中以首尾$的格式填写，通过反射实现调用。
特别的，对于struct类型，某个filed的传入采用[registerID].[field]。示例如下：

 | caseNo | desc | apiName | method | isNeed | apiPath.org_id | apiParam.email | apiHeader.authorization | status | expectJson.first_name | expectJson.last_name | Retry
   |  ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | 
   | 1 | a | /api/v1/orgs/{org_id}/me | GET | Y | 1 | zhongmin@pingcap.com | $token$ | 200 | Zhong | min |2
   | 2 | b | /api/v1/orgs/{org_id}/me | GET | Y | $cluster.OrgId$ | zhongmin@pingcap.com | $token$ | 200 | Zhong | min | 1


然后在main_test.go中的setup函数里进行注册即可：
  
         type cluster struct{
            OrgId string
            ClusterId string
            PerPage int
         }

         func setup() {
          // "Before all tests"
            c:=cluster{"1","1373933076654370569"}
            x:="Bearer eynw12kxNOWQ8f5rrKfffqiQ..."
      
          //将初始化结果进行注册,便于后续调用
            handler.Register("cluster",c)
            handler.Register("token",x)
         }
    

### conf字段说明
- name: 环境的名称，每个环境一个conf
- baseUrl：请求的域名地址

### 使用步骤示例

1. 在接口测试工程中引入qa-Gourd
2. 新建main.go文件，运行util.GenerateUtil("**signup**")，其中"**signup**"为设定的API描述

        package main
        
        import "github.com/tidbcloud/qa-Gourd/util"
        
        func main()  {
            apiName := "signup"
            util.GenerateUtil(apiName)
        }
3.首次运行会生成的文件有：
 - testCase/main_test.go, 用于全部用例的前置和后置处理。单个接口的前后置处理在单个接口脚本中处理

         func TestMain(m *testing.M) {
               handler.CommandHandler()
               setup()
               code := m.Run()
               teardown()
               os.Exit(code)
         }
         
         func setup() {
         // "Before all tests"
         }
         
         func teardown() {
         // "After all tests"
         }

 - testCase/signup_test.go文件和/testData/signup.csv文件。csv文件为case设计文件，go文件为脚本逻辑处理文件，可在go文件中执行特定的校验逻辑。
   
        func TestAPISignup(t *testing.T){
            var apiName = "signup"
            handler.DoTest(t, apiName)
        }
  - conf文件夹和conf文件，默认生成staging.conf。其他环境文件需自行在conf文件夹下添加，且文件命名规则：[环境名].conf

         [ENV]
         name=staging
         baseURL=https://us-west-2.staging.shared.aws.tidbcloud.com

4. 在csv文件中填写测试用例，如：

  | caseNo | desc | apiName | method | isNeed | apiPath.org_id | apiParam.email | apiHeader.authorization | status | expectJson.first_name | expectJson.last_name |
   |  ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | ----  | 
   | 1 | a | /api/v1/orgs/{org_id}/me | GET | Y | 1 | zhongmin@pingcap.com | Bearer xxxx | 200 | Zhong | min |
   
   
   
5. 运行/testCase/signup.test.go，即可得到结果。特别的，DoTest方法返回Map <sting> GourdCase类型，以caseId为key。如某个case需要有额外校验，可通过get("caseId")获取该case运行的全部上下文，包括返回结果
8. 命令行切换配置。默认运行配置环境为staging，如需切换环境，命令行中进入testCase文件夹，输入命令：
   >go test -env phone
   
   其中，“phone”为环境名称，可替换

### 本地report展示
框架集成了开源allure报告解决方案（https://github.com/dailymotion/allure-go）。本地使用方式如下：
- 明确报告生成的地址
  
      export ALLURE_RESULTS_PATH=</some/path>

- 安装allure插件，mac 安装如下，其他参考（https://docs.qameta.io/allure/#_about）
  
      brew install allure

- 执行go test 后即可在上述指定位置生成allure 报告所需的json文件
- 本地查看报告
  
      allure serve </some/path>

- 报告示范
  
  ![avatar](report1.png)![avatar](report2.png)
  
- 其他说明：allure 有插件可以集成jenkins，后续持续集成结果可在jenkins上直接查看

   
   

