見出し画像

テストケースの関連付け作業を簡単にするためにAzure DevOps REST APIを使ってTest Plansに登録されているTest Caseの更新をしてみた(後編)

はじめに

こんにちは!SHIFTでテスト自動化アーキテクトをしている木村です。

今回は前回の続きとなります。Azure DevOpsが提供しているREST APIを用いて、Test Plansに登録されているTest Caseの結果を更新してみましたので、
その内容について書いていきたいと思います。

後編は、実際にどういう順序でAPIを実行し、どのようにTestCaseに反映するかについて、書いていきたいと思います。

Test Point IDの取得

まずは結果を登録するAPIに必要なTest Point IDを取得します。

Test Point - Get Points List
GET /testplan/Plans/{planId}/Suites/{suiteId}/testpoint

{planId}にはTest PlansのIDを入力し、{suiteId}にはTest SuiteのIDを入力します。それぞれ、Test PlansのURLに以下のようになっているはずです。

今回はC#で作っていきます。HttpClientを用いて、GETリクエストを送信します。
まずは、APIを送るクラスとしてAdoApiControllerを作成し、以下のように実装します。

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace AzureDevOpsApiTest
{
    class AdoApiController
    {
        /// <summary>
        /// 受信ヘッダー
        /// </summary>
        public System.Net.Http.Headers.HttpResponseHeaders ResponseHeaders { get; private set; } = null;

       /// <summary>
       /// 受信文字列
       /// </summary>
        public string ResponseContent { get; private set; } = "";

        /// <summary>
        /// GETリクエストを送信する
        /// </summary>
        /// <param name="pat">アクセストークン</param>
        /// <param name="url">URL</param>
        /// <returns></returns>
        public async Task GetRequest(string pat, string url)
        {
            using (var client = new HttpClient())
            {
                try
                {
                    // ヘッダーを準備
                    var base64String = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(pat));

                    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64String);

                    // 受信コンテンツクリア
                    ResponseContent = "";

                    // リクエスト送信
                    using (HttpResponseMessage response = await client.GetAsync(url))
                    {
                        response.EnsureSuccessStatusCode();
                        ResponseHeaders = response.Headers;
                        ResponseContent = await response.Content.ReadAsStringAsync();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
        }
    }
}

GetRequest()を呼び出す際に、patとして個人用アクセストークン(詳細については前編を参照ください)を指定し、urlにAPIを指定します。
今回はTest Point IDを取得したいので、

https://dev.azure.com/{organization}/{project}/_apis/testplan/plans/{planId}/suites/{suiteId}/testpoint?api-version=6.0

とします。これを実行すると

{
  "value": [
    {
      "id": 12345,
      "tester": {
        "displayName": null,
        :
      },
      :
      "testCaseReference": {
        "id": 67890,
        "name": "Name of Test Case",
        :
      }
    },
    {
      :
    },
    :
    {
      :
    }
  ],
  "count":  200
}

といった応答が返ってきます。
countに記載されている個数のデータが取得できており、testCaseReferenceの中のidが今回取得したいTest Point IDになります。
注意が必要なのは、このAPIは一度に200件の情報しか取得できませんので、Test Plansのテストケースが200個を超える場合は、1度のリクエストで取得が完了しません。
この場合、受信ヘッダーの中(x-ms-continuationtoken)にトークンが保存されているので、このトークンをAPIに追加して再度送信すると、
次の200件が取得できる仕組みになっているので、このトークンがなくなるまで処理を実施することで、すべてのIDを取得することができます。
APIとしては、

https://dev.azure.com/{organization}/{project}/_apis/testplan/plans/{planId}/suites/{suiteId}/testpoint?continuationToken={continuationToken}&api-version=6.0

となり、上記作業を繰り返すことで、必要なTest Point IDを取得することができます。

Test Runの作成

Test Caseの結果を更新する処理の流れは以下の通りです(詳細は前編をご覧ください)。

順を追って見ていきましょう。まずはTest実行のためのWorkItemとしてTestRunを作成します。

Runs - Create
POST /test/runs

POSTメッセージなので、リクエストのBodyに必要な情報を入れないといけません。

{
  "name": "NewTestRun",
  "plan": {
    "id": "12345"
  },
  "pointIds": [
    67890
  ]
}

nameにはTestRunの名称を、planのid、pointIdsにはそれぞれ、Test PlansのTestCaseID、さきほど取得したTest Point IDをそれぞれ指定してください。
これを以下のAPIにセットしてPOSTリクエストします。

https://dev.azure.com/{organization}/{project}/_apis/test/runs?api-version=6.0

実装方法は、GetRequestとほぼ同じ形でGetAsyncの代わりにPostAsyncを使用し、Contentとして、application/jsonを指定してjsonをリクエストするようにしてください。

var content = new StringContent(json, Encoding.UTF8, "application/json");

エラーが発生しなければ、応答結果のjsonに作成されたTestRunのID(id)が格納されます。

{
  "id": 54321,
  :
}

エビデンスの画像を登録する

テスト結果を格納するためのWorkItemを作成することができたので、
ここに情報を追加していきます。
まずはエビデンスとなる画像を登録していきます。以下のAPIを使用します。

Attachments - Create Test Result Attachment
POST /test/Runs/{runId}/Results/{testCaseResultId}/attachments

runIdには先ほど取得したTestRunのIDを指定します。
testCaseResultIdにはデフォルトで100000が使用されるので、
その値を使用します。リクエストのBodyに必要な情報を入れます。

{
  "stream": "VXNlciB0ZXh0IGNvbnRlbnQgdG8gdXBsb2FkLg==",
  "fileName": "textAsFileAttachment.txt",
  "attachmentType": "GeneralAttachment"
}

streamにアップロードするファイルストリームのデータ(Base64変化済のデータ)を、fileNameに登録するファイル名を、attachmentTypeにはGeneralAttachmentを指定します。これを以下のAPIにセットしてPOSTリクエストします。

https://dev.azure.com/{organization}/{project}/_apis/test/runs/{runId}/results/100000/attachments?api-version=6.0

応答が返ってきてエラーが発生していなければ、登録完了です。

テストの結果を登録する

エビデンスが登録できたので、テスト結果を登録します。

Results - Update
PATCH /test/runs/{runId}/results

runIdには先ほど取得したTestRunのIDを指定します。
リクエストのBodyに必要な情報を入れます。

[
  {
    "id": 100000,
    "state": "Completed",
    "outcome": "Failed",
    "comment": "Website theme is not looking good",
    "errorMessage": "An error occurred"
  }
]

idにはデフォルトケースID(100000)を、stateには完了を示すCompletedを、outcomeには成功であればPassedを失敗であればFailedを指定し、コメントがある場合はcommentにコメントを指定します。
エラー発生時はerrorMessageにメッセージを指定するとエラーとしてハイライトされます。これを以下のAPIにセットしてPATCHリクエストします。

https://dev.azure.com/{organization}/{project}/_apis/test/runs/{runId}/results?api-version=6.0

実装方法は、PostRequestとほぼ同じ形でPostAsyncの代わりにPatchAsyncを使用します。ただし、ヘッダーにはapplication/jsonではなく*/*を使用するようにしてください。

client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));

こちらも応答が返ってきてエラーが発生していなければ、登録完了です。

TestRunの状態を更新する

以上でエビデンスの登録とテスト結果の登録が完了したので、最後にTestRunを完了扱いに変更します。

Runs - Update
PATCH /test/runs/{runId}

runIdには先ほど取得したTestRunのIDを指定します。リクエストのBodyに必要な情報を入れます。

{
  "id": 54321,
  "state": "Completed",
  "outcome": "Failed",
}

idにはrunIdを、stateには完了を示すCompletedを、outcomeには成功であればPassedを失敗であればFailedを指定します。これを以下のAPIにセットしてPATCHリクエストします。

https://dev.azure.com/{organization}/{project}/_apis/test/runs/{runId}?api-version=6.0

こちらも応答が返ってきてエラーが発生していなければ、更新完了です。
以上でAPIを利用したTestCaseの更新処理は完了となります。

まとめ

いかがでしたか。各APIの具体的な使用方法と流れに沿ったTest Caseの結果の作成と更新について記載しました。これを用いることで、自動テストを実施した後に取得したエビデンスと結果をプログラムで登録することができるため、柔軟性の高い自動テストが可能になります。

最後に

前編ではAPIを実行できる環境作りと更新手順、後編はその具体的なやり方について解説しました。今回の実装によって、アプリケーションからAzure DevOpsのTest Plansの情報を取得・更新ができるようになりました。APIの対象はTest Plansだけではないので、APIを使うことでアプリケーションから様々なことができるようになりますので、皆様もぜひ一度試してみてください。

以上です。皆様も素敵な自動化ライフを!


執筆者プロフィール:木村 直樹
製造業のSE、フリーランス、大手製造業のグループ会社をへて、2022年にSHIFTに入社。
様々なソフトウェア開発を経験し、PMや案件管理者として働きながら、
エンジニアとしてもまだまだ勉強中。趣味はDIYやプラモデル作成など。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO: UnsplashBernard Hermant