首頁>技術>

3分鐘閱讀

介紹

在本文中,我們將學習如何自動化REST API的驗收測試。該API提供了端點來註冊和驗證使用者(註冊/登入)。此外,還提供了一個安全的端點來獲取使用者資料。該服務將保留並獲取mongo資料庫中的資料。

下面的流程圖表示該服務的工作方式。

> API Flow diagram

先決條件

克隆包含以下內容的Git儲存庫

git clone [email protected]:ivancorrales/orion-test-api.git

此外,您應該在計算機上安裝Docker和Orion。

Orion-test-api

我們將瀏覽儲存庫中的不同檔案和資料夾。

> repository content

docker-compose.yml

服務和mongo資料庫的規範。

version: '3'services:  app:    image: ivancorrales/demo-api-mongo:0.0.1    environment:      MONGODB_URI: mongodb://root:secret@mongodb:27017/admin    ports:      - 3000:3000  mongodb:    image: mongo:latest    environment:      MONGO_INITDB_ROOT_USERNAME: root      MONGO_INITDB_ROOT_PASSWORD: secret    ports:      - 27017:27017    volumes:      - mongodb_data_container:/data/dbvolumes:  mongodb_data_container:

讓我們執行docker-compose來啟動服務和mongo容器。

.env

它包含要傳遞給Orion的環境變數。

.includes

資料夾include / *中的api.hcl和database.hcl檔案包含可重用的函式來處理API和資料庫。

main.hcl

該檔案將用作執行所有方案的入口點。

happyPath.hcl

涵蓋幸福道路的場景。

signIn-failures.hcl / signUp-failures.hcl / showProfile-failures.

一組場景,涵蓋了不愉快的道路。

我們開始做吧!

首先,我們使用docker-compose up命令啟動docker-compose。服務API在localhost:3000上執行,而mongo在localhost:27017上執行。請記住,連線到mongo(root / secret)需要身份驗證。

驗收測試可以使用以下命令執行:

orion run --input main.hcl --vars env/local.hcl

但…。讓我們深入研究Orion檔案!

包括/ api.hcl

它包含使用API端點的函式。這些功能是從方案中呼叫的。

實際上,閱讀功能非常簡單。您將意識到showProfile函式需要傳遞標頭x-access-token,因為這是一個安全的端點。

瞭解有關var,輸入引數,函式和操作的更多資訊http

vars {  mediaJson = "application/json"}func signUp {  input {    arg baseApi {        description = "URL base of the API"    }    arg user {        description = "entity with attributes fullName, username & password"    }  }  body {    http post {      request {        baseUrl = baseApi        path =  "/account"        headers {          Content-Type = mediaJson        }        payload json {          data = user        }      }      response {        httpResponse = {          statusCode = _.http.statusCode          body = json(_.http.body)        }      }    }  }  return {    value = httpResponse  }}func signIn {  input {    arg baseApi {        description = "URL base of the API"    }    arg credentials {        description = "entity with attributes username & password"    }  }  body {    http post {      request {        baseUrl = baseApi        path = "/session"        headers {          Content-Type = mediaJson        }        payload json {          data = credentials        }      }      response {        httpResponse = {          statusCode = _.http.statusCode          body = json(_.http.body)        }      }    }  }  return {    value = httpResponse  }}func showProfile {  input {    arg baseApi {        description = "URL base of the API"    }    arg token {        description = "a valid JWT"    }  }  body {    http get {      request {        baseUrl = baseApi        path = "/me"        headers {            x-access-token = token        }      }      response {        httpResponse = {          statusCode = _.http.statusCode          body = json(_.http.body)        }      }    }  }  return {    value = httpResponse  }}
包括/database.hcl

它包含一個函式,該函式將在執行方案之前從方案中使用以清理資料庫。我們為資料庫和集合輸入引數定義預設值。

func dropCollection {  input {    arg mongoUri {      description = "mongo uri"    }    arg database {      description = "Name of the database"      default = "admin"    }    arg collection {      description = "Name of the collection"      default = "users"    }    arg credentials {      description = "A object with two attributes: username & password"    }  }  body {    mongo drop {      connection {        uri = mongoUri        auth scram-sha-1{          username = credentials.username          password = credentials.password        }      }      query {        database = database        collection = collection      }    }  }}

瞭解有關var,函式和action mongo的更多資訊

happyPath.hcl

滿意路徑必須驗證使用者已註冊,透過身份驗證,然後他/他才能獲取她/他的個人資料詳細資訊。

您將意識到,當我們在include / api.hcl中呼叫函式時,不會傳遞引數baseApi。這是由於baseApi將成為main.hcl中的全域性變數。

scenario "happy path" {  given "my user details" {    set user {      value = {        fullName = "John Smith"        username = "[email protected]"        password = "secret"      }    }  }  when "I sign up" {    call signUp{      # block with can be omitted since variable user is already in the scope      with {  user = user }      as = "response"    }  }  then "I am registered successfully" {    assert {      assertion = response.statusCode == 200    }  }  when "do login" {    call signIn {      with {        credentials = {            username = user.username            password = user.password        }      }      as = "response"    }  }  then "I am authenticated successfully" {    assert {      assertion = response.statusCode == 200    }  }  when "I fetch my profile details" {    call showProfile{      with { token = response.body.accessToken }      as = "response"    }  }  then "the returned data are ok" {    assert {      assertion = (          response.statusCode == 200 &&          response.body.fullName == user.fullName      )    }  }}

瞭解有關場景以及操作呼叫和斷言的更多資訊。

main.hcl

該檔案用作執行所有方案的入口點。負責新增其他hcl檔案。除此之外,我們使用此檔案來定義全域性掛鉤並定義輸入引數。

description = <<EOF    This feature verify that API works as expectedEOFincludes = [    "includes/database.hcl",    "includes/api.hcl",    "happyPath.hcl",    "signUp-failures.hcl",    "signIn-failures.hcl",    "showProfile-failures.hcl"]input {    arg baseApi {        description = "URL base of the API"        default     = "http://localhost:3000/api"    }    arg mongoConn {        description = "a map with connection details { uri='', username='', password=''}"    }}before each {    call dropCollection{        with {            mongoUri = mongoConn.uri            credentials = {                username = mongoConn.username                password = mongoConn.password            }        }    }}

瞭解有關鉤子定義,輸入引數和包含的更多資訊

signUp-failures.hcl

我們寫了兩種情況:“由於輸入資料無效,所以無法註冊使用者”或“此電子郵件已經有一個使用者”。

scenario "a user registration fails because required fields are not provcided" {    examples = [        { fullName ="", username = "",  password =""},        { fullName ="Jane Doe", username = "",  password =""},        { fullName ="Jane Doe", username = "[email protected]",  password =""},        { fullName ="Jane Doe", username = "",  password ="secret"},    ]    when "register the user" {        call signUp {            with {                user = {                    fullName = fullName                    username = username                    password = password                }            }            as = "createUserResponse"        }    }    then "the server returns with a bad request error" {        assert {        assertion = createUserResponse.statusCode==400        }    }}scenario "user registration fails when email is already in use" {  given "a user with valid email & password" {    set user {      value = { username = "[email protected]", password = "secret"}    }  }  when "tries to register the user" {    # omit block `with` because both user and basiApi are in the scope    call signUp {      as = "response"    }  }  then "the server returns with a success status code" {    assert {      assertion = response.statusCode==200    }  }  when "tries to register the same user" {    # omit block `with` because both user and basiApi are in the scope    call signUp {      as = "response"    }  }  then "the server returns with an error" {    assert {      assertion = (          response.statusCode==400 &&            response.body.message=="Failed! Username is already in use!"      )    }  }}

為了表示第一個請求不好的場景,我們將利用帶有示例的場景。

signIn-failures.hcl / showProfile.hcl

這些檔案是空的。我鼓勵您嘗試自己實施方案。練習是我知道學習知識的唯一途徑……當然,如果您需要任何幫助,請告訴我!

6
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • leetcode1300_轉變陣列後最接近目標值的陣列和