3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Webアプリ構築カレンダーAdvent Calendar 2023

Day 20

【Day 20】ブログ一覧を取得し、表示する - API E2E

Last updated at Posted at 2023-12-19

はじめに

スライド21.PNG


2023年アドベントカレンダー20日目です。

本日から「ユーザーはトップページでブログタイトルの一覧を見ることができる」を進めていきます。

image.png

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)
  }
  1. パラメータURLを受け取り、GETリクエストを送る
  2. 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))
  }
  1. 先ほど格納したresponseを取り出す
  2. responsstatusと、パラメータの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)
  }
  1. 先ほど格納したresponseを取り出す
  2. オリジナルの、Jsonから、pathを指定してValueを抽出するメソッドを作成
  3. responsjsonPahtvalueと、パラメータの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

実装がまだなので、予想通り失敗しました :ok:

次回はAPIをRust + Axumを使ってクリーンアーキテクチャに基づいて作成していきます

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?