2024.3.26
SHARE ON |
在撰寫自動化測試時,遇到 get 的 API,因為回傳的資料非常大一包,若將每個 property 拆開單獨寫一個 test 會導致 test 過多,但若包在一起用傳統寫法又缺乏準確報錯,因此尋找一個 solution 來驗證 JSON 回傳的格式是否正確,若錯誤也會針對錯誤欄位 assert error
這個工具是以 JSON 格式來定義要驗證的 JSON 資料,讓使用者透過這個工具簡單設計出自訂格式的 JSON parser,可以用在 testing 或 backend 輸入輸出格式的定義,還有酷炫的功能可以按照格式生產隨機的測試資料。
語言支援非常多,只要用 JSON 格式定義好物件後他的 validator 支援 C#, C++, python, java, JS...等,種類繁多,其中這次會用 JS 套件 Ajv JSON schema validator,該套件也有內建在 postman 裡,語法如下
pm.response.to.have.jsonSchema({JSON schema})
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" }, "warehouseLocation": { "description": "Coordinates of the warehouse where the product is located.", "$ref": "https://example.com/geographical-location.schema.json" } }, "required": [ "productId" ]}
這是一個簡單的範例,他定義了一個 product 的 JSON schema
$符號開頭,用來定義 schema 的特殊屬性,若只是單純要驗證資料沒有特殊的外部需求,完全不寫也沒關系
$schema
****代表你寫的 JSON Schema 文件遵循的規範是哪一個版本,在上面這個範例中他的版本是 draft/2020-12 這個版本
$id
是這個 schema 的 unique 識別號,只要用在外部使用$ref 時可以透過它識別出要 reference 誰
$ref
可以透過它來 reference 一些公開的 schema,或是分檔撰寫 schema 再 reference 在一起,在上面這個範例是 warehouseLocation 這個 property 必須依照"https://example.com/geographical-location.schema.json"的schema格式
title
和description
屬於此類,主要用於紀錄人類可讀的說明性資訊
各類功能不同的 validation keyword,用來規範 schema 必須依循的規則,在上面的範例中properties
、type
、required
都屬於這類
properties
規範了這個 schema 裡會出現的 properties,再針對各自的 property 可以有更細的規範
type
最簡單的 validation keyword,用來規範資料的 data type,常見的有 string、integer、number(包含 int、float)
required
搭配 properties 使用,用來規範一定要出現的 property
JSON 最常見的就是 object 裡包 object 或包 array,當然它也可以規範出 nested 的 schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" "tags": { "description": "Tags for the product", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "dimensions": { "type": "object", "properties": { "length": { "type": "number" }, "width": { "type": "number" } }, "required": [ "length", "width", "height" ] } }, "required": [ "productId"]}
array 可以用items
來規範內部物件的格式,object 則是用properties
還有其他的 validation keywords 可以參考 reference 裡的 understanding JSON schema 連結
一些常見的應用和這次撰寫測試裡用到的實際案例
"personality": { "type": "array", "minItems": 5, "maxItems": 5, "items": { "type": "number", "minimum":0, "maximum":1 } }
性格是固定長度為 5 的 float array,每個 flaot 的最小值為 0 最大值為 1
"animalName":{ "type":["string","null"] },
animalName 會是 string,但若在未選擇寵物前回傳 null 是正常行為
{ "title": "ID card number", "type": "string", "pattern": "^[A-Z]{1}[0-9]{9}$"}
依照 regular expression 來驗證符合身分證字號格式的字串
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "title": "Product", "description": "A product from Acme's catalog", "type": "object", "properties": { "productId": { "description": "The unique identifier for a product", "type": "integer" "tags": { "description": "Tags for the product", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "additionalProperties":false}
additionalProperties
不允許出現properties
以外的其他 property,也可以直接規範其他額外 property 或單純設為 true(預設就是 true)
"additionalProperties":{ "type":"string" }"additionalProperties":true
一個遇到 error 卻不會噴 error 的 test 是沒有意義的,務必在寫完 JSON schema 後先自己玩弄一下看看有沒有設計瑕疵
JSON Schema Validator - Newtonsoft
驗證資料的好幫手 - JSON Schema Validator · Issue #2 · Hsueh-Jen/blog
Understanding JSON Schema - Understanding JSON Schema 2020-12 documentation