MagicPodの一括実行結果をまとめてQualityForwardに投入する

## 1. はじめに
MagicPodのテスト結果をQualityForward(以降QualityForward)に投入する方法については、
[MagicPodとQualityForwardでテスト実行から結果投入まで連携する・改](https://qiita.com/vZke/items/d3f8a0bc4229b6d1e82d)でも紹介されていますが、
QualityForward上の複数のテストスイートに対して結果を投入しようとした際に、面倒さを感じたので、
その解決策と、投入フローを整理した記事です。

## 2. 面倒なこと
[QualityForwardのAPIリファレンス](https://qualityforward.zendesk.com/hc/ja/articles/4416637686937-API%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9)によると、テスト結果をPOSTするためには、以下の情報が必要です。
- test phase id
- test suite assignments id
- test cycle id

加えて、MagicPodのテスト結果とQualityForwardのテストケースを突合するためには、テストケース情報の取得が必要なので、
上記に加えて、
- test suite id
- test suite version id

が必要になります。

これらの情報を任意のファイルに定義しておくことで、結果投入はできるのですが、
日々増えていくテストスイートや、テストスイートの更新に伴いテストスイートバージョンが変化するたびに、
定義ファイルを変更するのは面倒です。
ですので、何とかして定義ファイルを持つことなくMagicPodの結果をQualityForwardに投入したいというのがモチベーションです。

## 3. 前提とする運用の流れ
次の運用をすることを想定しています。
- QualityForwardのテストスイートは日々新たに作成され、増えていく。それに従い、MagicPodのテストケースを実装していく
- MagicPodテストケースの実装完了後、そのテストケースに対応するQualityForwardのテストスイートをQualityForwardのテストフェーズに追加していく
- QualityForwardのテストサイクルはMagicPodの実行の度に増やさず、最新の結果のみが保持されるようにする
- MagicPodのパターンは言語で分けるものとし、言語ごとにテスト手順は変えない(文言の違いのみを想定)

## 4. やりたいこと
### 4-1. 概要
QualityForwardのテストフェーズに登録されているテストスイートから、MagicPodのテストケースに該当するQualityForwardのテストケースを抽出し、テスト結果を投入することを考えます。

具体的には、次のような手順で投入をしていきます。
1. MagicPodの一括実行結果を取得する
1. QualityForwardのテストフェーズ情報を取得する
1. QualityForwardのテストサイクル情報を取得する。
1. QualityForwardのテストケース情報を取得する
1. MagicPodの一括実行結果と、QualityForwardのテストケース情報を突合し、一致するテストケースがあるかチェックする
1. 一致するテストケースがあればテスト結果を投入する

### 4-2. データの整理
MagicPodで取得した一括実行結果のサンプルは次のようなデータ構造になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/3f137190-fe29-38b3-cc1c-e208b23fe849.png)
簡単に表現するとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/fcf37877-826f-117b-4c9d-258c4fc7e929.png)
QualityForwardのテストフェーズはざっくりと示すと次のような構造になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/18375b8e-12c9-f7a7-50b2-8e5628ef1c2e.png)
また、QualityForwardのテストスイートには複数のテストケースが含まれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/62cf6e24-abfb-0f19-0090-e8262ab4628c.png)

本来のテストサイクルの意とは異なりますが、今回は、QualityForwardのテストサイクルにMagicPodのパターン(日本語、英語)を対応させ、次のように紐付けていくことにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/0c8f277a-a16d-c833-78f2-d379c2a901c5.png)

## 5. 困ったこと
QualityForwardのAPIでテストフェーズ情報を取得すると、次の情報が取得できます。
- test phase id
- test suite assignments id
- test suite version id

続いて、テストサイクル情報の取得により、次の情報が取得できます。
- test cycle id

上記の情報でテスト結果をPOSTすることはできるのですが、"test suite id"がなく、
テストケース情報の取得ができないので、
> MagicPodの一括実行結果と、QualityForwardのテストケース情報を突合し、一致するテストケースがあるかチェックする

ことができません…。

## 6. test suite version id から test suite idを取得する
もし、QualityForwardの一つのプロジェクトの中で、test suite version idが一意な値であれば、
テストフェーズ情報で取得したtest suite version idと、テストスイート情報で取得したtest suite version idを突合することで、
test suite idを特定できるのではと考えました。

ぱっと見た感じ、test suite version idは一意になっていそうでしたが、QualityForwardのサポートチームにもご確認いただいて、
一つのプロジェクトの中で同じtest suite version idが発行されることがないことがわかったので、
この方法でテストフェーズに紐付けられているテストスイートのtest suite idを取得することができそうです。

## 7. 投入にあたっての準備
QualityForwardのテストスイート設定で、MagicPodのテストケースと紐づけるためのテスト定義を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/3e3c8878-51ca-0498-84fc-c6055ad98fbe.png)
この列には、MagicPodのテストケース#を記載していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/73b10eae-04c7-7a82-efba-2e393ccfe79f.png)

テストサイクル名はMagicPodの一括実行のパターン名と同じものを設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/daf448ed-5d2b-1214-c63f-1dcee4723b3b.png)


## 8. 投入までのステップ
### 8-1. MagicPodの一括実行結果を取得する
一括実行結果を取得するAPIを実行し、テスト結果を取得します。
#### MagicPod APIエンドポイントURL
`https://app.magicpod.com/api`
```Shell:[GET]
/v1.0/{organization_name}/{project_name}/batch-run/{batch_run_number}/
```

### 8-2. テストスイートの情報を取得する
プロジェクト内のテストスイートIDの一覧を得るために、テストスイート情報取得APIを実行します。
#### QualityForward APIエンドポイントURL
`https://cloud.veriserve.co.jp`
```Shell:[GET]
/api/v2/test_suites?api_key={your_api_key}
```

### 8-3. テストスイートバージョン情報を取得する
8-2で取得したテストスイートIDの数だけ、テストスイートバージョン情報を取得していきます。
```Shell:[GET]
/api/v2/test_suites/{test suite id}/test_suite_versions?api_key={your_api_key}
```

### 8-4. テストフェーズ情報を取得する
テストフェーズ情報取得APIを実行し、以下の情報を取得します。
- test phase id
- test suite assignments id
- test suite version id
```Shell:[GET]
/api/v2/test_phases?api_key={your_api_key}
```

### 8-5. test suite version idからtest suite idを特定する
「8-4. テストフェーズ情報を取得する」で取得したtest suite version idと
「8-2. テストスイートの情報を取得する」「8-3. テストスイートバージョン情報を取得する」で取得したtest suite version idを突合することで、test suite idを特定します。
これにより、テストフェーズに紐付けされているテストスイートに対して、テストケース情報の取得が可能になりました。

### 8-6. テストケース情報を取得する
上記で取得した次の情報を使って、テストケース情報を取得していきます
- test suite id
- test suite version id
```Shell:[GET]
/api/v2/test_suites/{test suite id}/test_suite_versions/{test suite version id}/test_cases?api_key={your_api_key}
```

### 8-7. テストサイクル情報を取得する
同じくこれまでの手順で取得した次の情報を使って、テストサイクル情報を取得します。
- test phase id
- test suite assignments id
```Shell:[GET]
/api/v2/test_phases/{test phase id}/test_suite_assignments/{test suite assignments id}/test_ cycles?api_key={your_api_key}
```

### 8-8. MagicPodの一括実行結果と、QualityForwardのテストケース情報を突合し、一致するテストケースがあるかチェックする
準備のとき、テストスイートのテスト定義に「MagicPod#」という列を追加していました。
この列の値にMagicPodのテストケース#が入っているので、
これを使ってQualityForwardのテストケースがMagicPodのどのテストケースと対応しているのかを突合していきます。

また、テストサイクル名を一括実行のパターン名と同じ名前にしているので、
テストサイクル情報の取得で取得したテストサイクル名と、MagicPodのパターン名を使って、
どのテストサイクルがどのパターンと対応しているのかを突合していきます。

### 8-9. 一致するテストケースがあればテスト結果を投入する
突合ができたら、テスト結果を投入していきます。
```Shell:[POST]
/api/v2/test_phases/{test phase id}/test_suite_assignments/{test suite assignments 
 id}/test_cycles/{test cycle id}/test_results?api_key={your_api_key}
```

これを繰り返していくことでMagicPodの一括実行結果をQualityForwardに投入することができます。