はじめに
2023年アドベントカレンダー20日目です。
本日から「ユーザーはトップページでブログタイトルの一覧を見ることができる」を進めていきます。
E2E
前回整備したようにGauge
+ TypeScript
でE2Eテストを書いていきます
以前初期値を入れたものを参考にして、次のようにSpecファイルを作成しました。
blog.spec
# ブログ一覧取得系
## Get Blogs
* URL"http://localhost:3000/blogs"にGETリクエストを送る
* レスポンスステータスコードが"200"である
* レスポンス内JsonBodyの"blogs[0].id"が文字列の"123e4567-e89b-12d3-a456-426614174000"である
* レスポンス内JsonBodyの"blogs[0].title"が文字列の"カフェの隅で見つけた幸せ:私のお気に入りの隠れ家"である
* レスポンス内JsonBodyの"blogs[0].author"が文字列の"田中太郎"である
* レスポンス内JsonBodyの"blogs[0].body"が文字列の"ブログの本文"である
* レスポンス内JsonBodyの"blogs[0].createdAt"が文字列の"2023-12-09 09:00:00"である
作ったStepは3種類
- URL
<url>
にGETリクエストを送る - レスポンスステータスコードが
<statusCode>
である - レスポンス内JsonBodyの
<jsonPath>
が文字列の<value>
である
このテストコードを実装してみます。
fetch.ts
import axios, { AxiosResponse } from 'axios'
import { assert } from 'chai'
import { Step, DataStore, DataStoreFactory } from 'gauge-ts'
// jsonとpathからValueを抽出するメソッド
const extractValue = (json: Object, path: string) => {
const parts = path.split(/[\.\[\]\'\"]/).filter(p => p);
let value = json
parts.map((part) => {
if (value[part] === undefined) {
return undefined
}
value = value[part]
})
return value
}
export default class BlogStep {
@Step('URL<url>にGETリクエストを送る')
public async requestGet(url: string) {
const response = await axios.get(url)
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
suiteStore.put('response', response)
}
@Step('レスポンスステータスコードが<statusCode>である')
public async checkStatusCode(statusCode: string) {
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
const response: AxiosResponse<any, any> = suiteStore.get('response')
assert.equal(response.status, parseInt(statusCode))
}
@Step('レスポンス内JsonBodyの<jsonPath>が文字列の<str>である')
public async checkJsonResponseString(jsonPath: string, str: string) {
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
const response: AxiosResponse<any, any> = suiteStore.get('response')
assert.equal(extractValue(response.data, jsonPath), str)
}
}
少しだけ解説します。
GETリクエスト
@Step('URL<url>にGETリクエストを送る')
public async requestGet(url: string) {
const response = await axios.get(url)
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
suiteStore.put('response', response)
}
- パラメータ
URL
を受け取り、GETリクエストを送る - gaugeのDataStoreにresponseを格納
ステータスコードチェック
@Step('レスポンスステータスコードが<statusCode>である')
public async checkStatusCode(statusCode: string) {
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
const response: AxiosResponse<any, any> = suiteStore.get('response')
assert.equal(response.status, parseInt(statusCode))
}
- 先ほど格納した
response
を取り出す -
respons
のstatus
と、パラメータのStatusCode
を比べる
JsonのValueチェック
// jsonとpathからValueを抽出するメソッド
const extractValue = (json: Object, path: string) => {
const parts = path.split(/[\.\[\]\'\"]/).filter(p => p);
let value = json
parts.map((part) => {
if (value[part] === undefined) {
return undefined
}
value = value[part]
})
return value
}
// ...
@Step('レスポンス内JsonBodyの<jsonPath>が文字列の<str>である')
public async checkJsonResponseString(jsonPath: string, str: string) {
let suiteStore: DataStore = DataStoreFactory.getSuiteDataStore()
const response: AxiosResponse<any, any> = suiteStore.get('response')
assert.equal(extractValue(response.data, jsonPath), str)
}
- 先ほど格納した
response
を取り出す - オリジナルの、Jsonから、pathを指定してValueを抽出するメソッドを作成
-
respons
のjsonPaht
のvalue
と、パラメータのstr
を比べる
解説は以上です。
実行
実行してみます
$ gauge run specs
# Blog E2E
## Get Blogs ✘
<<省略>>
Successfully generated html-report to => /your/path/reports/html-report/index.html
Specifications: 1 executed 0 passed 1 failed 0 skipped
Scenarios: 1 executed 0 passed 1 failed 0 skipped
Total time taken: 128ms
実装がまだなので、予想通り失敗しました
次回はAPIをRust + Axumを使ってクリーンアーキテクチャに基づいて作成していきます