Postman テストスクリプトサンプル

本記事は、Postman [Script examples](https://learning.postman.com/docs/writing-scripts/script-references/test-examples/) の日本語訳です（2025年4月15日更新）。

この記事では、Postman の様々な API テストシナリオのための Post-response スクリプトの例を説明します。これらの Post-response スクリプトをリクエストで使用すると、レスポンスデータをパースしてアサーションを行うことができます。また、これらのスクリプトを使ってレスポンスの構造を検証したり、よくあるテストエラーのトラブルシューティングを行ったりすることもできます。

初めて Post-response スクリプトを作成するときは、まず Postman でリクエストを開き、**Scripts > Post-response** タブを選択します。そして、次の JavaScript コードを入力してください：

```js
pm.test("ステータスコードは 200", function () {
  pm.response.to.have.status(200);
});
```

このコードでは、`pm` ライブラリを使って `test` メソッドを実行しています。テキスト文字列はテストの出力に現れます。テスト内の関数はアサーションを表します。Postman のテストでは [Chai Assertion Library BDD](https://www.chaijs.com/api/bdd/) 構文を使うことができ、これはテストの可読性を高めることに役立ちます。この場合、コードは BDD 形式の `to.have` チェーンを使用してアサーションを表現します。

このテストは API が返すレスポンスコードをチェックします。レスポンスコードが `200` ならテストは合格、そうでなければ失敗です。**送信**を選択し、レスポンスエリアの**テスト結果**タブに移動してください。

![](https://assets.postman.com/postman-docs/v11/example-test-assertion-result-v11.23.jpg)

テスト結果が合格あるいは失敗の場合にどのように見えるかを確認するには、アサーションコード内のステータスコードを変更して、リクエストをもう一度送信してみましょう。

結果をどのように出力したいかによって、さまざまな方法でテストアサーションを構成できます。次のコードは、上のコードと同じテストを `expect` 構文で行うものです：

```js
pm.test("ステータスコードは 200", () => {
  pm.expect(pm.response.code).to.eql(200);
});
```

:::note
アサーション構文オプションの完全な概要については、[Chai Assertion Library Docs](https://www.chaijs.com/api/bdd/) を参照してください。
:::

# 複数のアサーションを使用する

ひとつのテストに複数のアサーションを含めることができます。これを使用して、関連するアサーションをひとまとめにします：

```js
pm.test("レスポンスはすべてのプロパティを持つ", () => {
    // レスポンス JSON をパースして、3つのプロパティをテストする
    const responseJson = pm.response.json();
    pm.expect(responseJson.type).to.eql('vip');
    pm.expect(responseJson.name).to.be.a('string');
    pm.expect(responseJson.id).to.have.lengthOf(1);
});
```

含まれるアサーションのいずれかが失敗すると、テスト全体が失敗となります。テストに合格するには、すべてのアサーションが成功しなければなりません。

# レスポンスボディデータをパースする

レスポンスに対してアサーションを実行するには、まずデータをパースしてアサーションが使用できる JavaScript オブジェクトにする必要があります。

JSON データをパースするには、次の構文を使用します：

```js
const responseJson = pm.response.json();
```

XML をパースするには、以下を使用します：

```js
const responseJson = xml2Json(pm.response.text());
```

:::note
複雑な XML レスポンスを扱っている場合、[コンソールログ出力](https://learning.postman.com/docs/sending-requests/response-data/troubleshooting-api-requests/#debugging-in-the-console)が役に立つかもしれません。
:::

CSV をパースするには、[CSV parse (csv-parse/lib/sync)](https://csv.js.org/parse/) ユーティリティを使用します：

```js
const parse = require('csv-parse/lib/sync');
const responseJson = parse(pm.response.text());
```

HTML をパースするには [cheerio](https://cheerio.js.org/) を使用します：

```js
const $ = cheerio.load(pm.response.text());
// html をテスト用に出力
console.log($.html());
```

## パースできないレスポンスを処理する

レスポンスボディが JSON、XML、HTML、CSV などのパース可能なデータ形式でフォーマットされていないために JavaScript でパースできない場合でも、データに対してアサーションを行うことができます。

レスポンスボディに特定の文字列が含まれているかどうかをテストします：

```js
pm.test("ボディは文字列を含む",() => {
  pm.expect(pm.response.text()).to.include("customer_id");
});
```

上の例は、レスポンスボディ全体に対してテストを実行するため、文字列がどこで検出されたかはわかりません。レスポンスが文字列に一致するかどうかは、次のようにテストします：

```js
pm.test("ボディは文字列", function () {
  pm.response.to.have.body("whole-body-text");
});
```

# HTTP レスポンスに対するアサーションを作成する

[ボディ](#レスポンスボディをテストする)、[ステータスコード](#ステータスコードをテストする)、[ヘッダー](#ヘッダーをテストする)、[Cookie](#cookie-をテストする)、[レスポンス時間](#レスポンス時間をテストする)など、 リクエストレスポンスのさまざまな側面をチェックすることができます。

## レスポンスボディをテストする

レスポンスボディ内の特定の値をチェックします：

```js
/* レスポンスは以下のような構造を持つ：
{
  "name": "一郎",
  "age": 23
},
*/
pm.test("人物は一郎", () => {
  const responseJson = pm.response.json();
  pm.expect(responseJson.name).to.eql("一郎");
  pm.expect(responseJson.age).to.eql(23);
});
```

## ステータスコードをテストする

レスポンスのステータスコードをテストします：

```js
pm.test("ステータスコードは 201", () => {
  pm.response.to.have.status(201);
});
```

ステータスコードが集合のひとつであることをテストしたい場合は、それらをすべて配列に含めて `oneOf` を使用します：

```js
pm.test("POST リクエストに成功", () => {
  pm.expect(pm.response.code).to.be.oneOf([201,202]);
});
```

ステータスコードのテキストをチェックします：

```js
pm.test("ステータスコードは特定の文字列", () => {
  pm.response.to.have.status("Created");
});
```

## ヘッダーをテストする

レスポンスヘッダーが存在するかチェックします：

```js
pm.test("Content-Type ヘッダーが存在する", () => {
  pm.response.to.have.header("Content-Type");
});
```

レスポンスヘッダーが特定の値を持つかテストします：

```js
pm.test("Content-Type ヘッダーは application/json", () => {
  pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');
});
```

## Cookie をテストする

レスポンスに Cookie が存在するかどうかをテストします：

```js
pm.test("Cookie isLoggedIn が存在する", () => {
  pm.expect(pm.cookies.has('isLoggedIn')).to.be.true;
});
```

特定の Cookie の値をテストします：

```js
pm.test("Cookie isLoggedIn の値は 1", () => {
  pm.expect(pm.cookies.get('isLoggedIn')).to.eql('1');
});
```

## レスポンス時間をテストする

レスポンス時間が指定された範囲内であることをテストします：

```js
pm.test("レスポンス時間は 200ms 未満", () => {
  pm.expect(pm.response.responseTime).to.be.below(200);
});
```

# 一般的なアサーションの例

以下の一般的なアサーションの例は、Post-response スクリプトを記述する際に役立ちます。

:::note
アサーションに含めることができる内容のより包括的な概要については、[Chai Assertion Library Docs](https://www.chaijs.com/api/bdd/) を参照してください。
:::

## レスポンス値を変数に対してアサートする

レスポンスのプロパティが変数と同じ値かどうかをチェックします (この例では環境変数を使用)：

```js
pm.test("レスポンスプロパティは環境変数と一致する", function () {
  pm.expect(pm.response.json().name).to.eql(pm.environment.get("name"));
});
```

:::note
Post-response スクリプトで変数を使用する方法については [Using variables](https://learning.postman.com/docs/sending-requests/variables/variables/) を参照してください。
:::

## 値の型をアサートする

レスポンスの任意の部分の型をテストします：

```js
/* レスポンスは以下のような構造を持つ：
{
  "name": "一郎",
  "age": 29,
  "hobbies": [
    "スケート",
    "絵画"
  ],
  "email": null
},
*/
const jsonData = pm.response.json();
pm.test("レスポンスのデータ型をテストする", () => {
  pm.expect(jsonData).to.be.an("object");
  pm.expect(jsonData.name).to.be.a("string");
  pm.expect(jsonData.age).to.be.a("number");
  pm.expect(jsonData.hobbies).to.be.an("array");
  pm.expect(jsonData.website).to.be.undefined;
  pm.expect(jsonData.email).to.be.null;
});
```

## 配列プロパティをアサートする

配列が空かどうか、また特定の項目が含まれているかどうかをチェックします：

```js
/* レスポンスは以下のような構造を持つ：
{
  "errors": [],
  "areas": [ "goods", "services" ],
  "settings": [
    {
      "type": "notification",
      "detail": [ "email", "sms" ]
    },
    {
      "type": "visual",
      "detail": [ "light", "large" ]
    }
  ]
},
*/

const jsonData = pm.response.json();
pm.test("配列のプロパティをテストする", () => {
  // errors 配列が空
  pm.expect(jsonData.errors).to.be.empty;
  // areas 配列には「goods」が含まれる
  pm.expect(jsonData.areas).to.include("goods");
  // notification settings オブジェクトを取得する
  const notificationSettings = jsonData.settings.find
    (m => m.type === "notification");
  pm.expect(notificationSettings)
    .to.be.an("object", "setting が見つからない");
  // detail 配列は「sms」を含む
  pm.expect(notificationSettings.detail).to.include("sms");
  // detail 配列はリストされたすべての項目を含む
  pm.expect(notificationSettings.detail)
    .to.have.members(["email", "sms"]);
});
```

:::note
`.members` の順番はテストに影響しません。
:::

## オブジェクトプロパティをアサートする

オブジェクトにキーやプロパティが含まれていることをアサートします：

```js
/* レスポンスは以下のような構造を持つ：
{
  "a": 1,
  "b": 2
},
*/
pm.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
pm.expect({a: 1}).to.have.property('a');
pm.expect({a: 1, b: 2}).to.be.a('object')
  .that.has.all.keys('a', 'b');
```

:::note
ターゲットには、`object`、`set`、`array`、`map` を指定できます。`.all` または `.any` を指定せずに `.keys` を実行すると、式のデフォルトは `.all` になります。`.keys` の動作はターゲットの型によって異なるため、`.a` と共に `.keys` を使用する前に型を確認することをお勧めします。
:::

## 値がセット内にあることをアサートする

レスポンス値を有効なオプションのリストと照合します：

```js
/* レスポンスは以下のような構造を持つ：
{
  "type": "Subscriber"
},
*/

pm.test("値が有効なリスト内にある", () => {
  pm.expect(pm.response.json().type)
    .to.be.oneOf(["Subscriber", "Customer", "User"]);
});
```

## オブジェクトが含まれていることをアサートする

オブジェクトが親オブジェクトの一部であることをチェックします：

```js
/* レスポンスは以下のような構造を持つ：
{
  "id": "d8893057-3e91-4cdd-a36f-a0af460b6373",
  "created": true,
  "errors": []
},
*/

pm.test("オブジェクトが含まれている", () => {
  const expectedObject = {
    "created": true,
    "errors": []
  };
  pm.expect(pm.response.json()).to.deep.include(expectedObject);
});
```

`.deep` を使用すると、チェーン内で後続するすべての `.equal`、`.include`、`.members`、`.keys`、`.property` アサーションで、厳密な（`===`）等価性ではなく深い等価性が使用されるようになります。

## 現在の環境をアサートする

Postman の[アクティブな環境](https://learning.postman.com/docs/sending-requests/variables/managing-environments/#switch-between-environments)をチェックします：

```js
pm.test("アクティブな環境をチェックする", () => {
  pm.expect(pm.environment.name).to.eql("Production");
});
```

# よくあるテストエラーをトラブルシュートする

Post-response のスクリプトでエラーや予期せぬ挙動に遭遇した場合、[Postman コンソール](https://learning.postman.com/docs/sending-requests/response-data/troubleshooting-api-requests/)が原因の特定に役立ちます。`console.log()`、`console.info()`、`console.warn()`、`console.error()` のデバッグ文とテストアサーションを組み合わせることで、HTTP リクエストやレスポンスの内容、そして変数などの Postman のデータ項目を調べることができます。`console.clear()` メソッドを使用して、コンソールから情報を消去することもできます。Postman のフッターから**コンソール**を選択して開きます。

![](https://assets.postman.com/postman-docs/v11/console-logs-in-pane-v11.jpg)

変数やレスポンスプロパティの値をログに出力します：

```js
console.log(pm.collectionVariables.get("name"));
console.log(pm.response.json().name);
```

変数やレスポンスプロパティの型をログに出力します：

```js
console.log(typeof pm.response.json().id);
```

コンソールのログを使用して、コードの実行を記録します。「トレースステートメント」と呼ばれることもあります：

```js
if (pm.response.json().id) {
  console.log("id を発見!");
  // 何かする
} else {
  console.log("id なし...");
  // 何か他のことをする
}
```

## 深い等価性アサーションエラー

`AssertionError: expected <value> to deep equal '<value>'` というエラーが発生することがあります。例えば、次のようなコードで発生します：

```js
pm.expect(1).to.eql("1");
```

これは、テストが数値と文字列値を比較しているために起こります。このテストは、型と値の両方が等しい場合にのみ真を返します。

## 変数未定義エラー

`ReferenceError: <variable> is not defined` というエラーに遭遇するかもしれません。これは通常、宣言されていない変数を参照しようとしたときや、テストコードのスコープ外の変数を参照しようとしたときに発生します。

次の例では、JSON オブジェクトが最初のテストの変数の値です。二番目のテストはこの変数を参照しようとしていますが、変数が二番目のテストのコードのスコープ外にあるため、参照できません。

```js
/* レスポンスは以下のような構造を持つ：
{
  "name": "一郎",
  "age": 29
},
*/
pm.test("テスト 1", () => {
  const jsonData = pm.response.json();
  pm.expect(jsonData.name).to.eql("一郎");
});

pm.test("テスト 2", () => {
  pm.expect(jsonData.age).to.eql(29); // ReferenceError: jsonData is not defined
});
```

テスト関数が変数を参照する必要がある場合は、グローバルスコープで変数を利用できるようにします。先ほどの例では、最初の `pm.test` の前に `const jsonData = pm.response.json();` を移動させれば、両方のテスト関数で利用できるようになります。

## アサーション未定義エラー

`AssertionError: expected undefined to deeply equal <value>` というエラーに遭遇するかもしれません。これは通常、存在しないプロパティやスコープ外のプロパティを参照しているときに発生します。

```js
const jsonData = pm.response.json();
pm.expect(jsonData.name).to.eql("一郎");
```

この例で、`AssertionError: expected undefined to deeply equal '一郎'` というエラーが出た場合、これは `name` プロパティが `jsonData` オブジェクトで定義されていないことを示しています。

## テストが失敗しない

テストが失敗すると思っていたのに、失敗しないことがあるかもしれません。テストコードが構文的に正しいことを確認してから、リクエストをもう一度送信してください。

次の例では、`true` が `false` と等しくないのでテストは失敗すると予想されます。実際にテストが合格するのは、`pm.test` 関数が正しく定義されていないからです。`pm.test` 関数には、テスト結果出力に表示されるテキスト文字列である最初のパラメータがありません。[`pm.test` 関数を使ったテストの定義](https://learning.postman.com/docs/writing-scripts/test-scripts/#validating-responses)についてはこちらを参照してください。

```js
pm.test( function () {
  pm.expect(true).to.eql(false);
});
```

# レスポンス構造を検証する

[Ajv](https://www.npmjs.com/package/ajv/v/6.12.5) でJSONスキーマを検証することができます。以下の例では、`alpha` という名前のクエリパラメーターがリクエストに含まれている場合のみテストが合格します。

```js
const schema = {
    required: ["args"],
    properties: {
        args: {
            required: ["alpha"],
            properties: {
                alpha: { type: "string" }
            }
        }
    }
};

pm.test('レスポンスは有効', function() {
  pm.response.to.have.jsonSchema(schema);
});
```

:::note
Ajv JSON Schema バリデーターの使用方法についての詳細は[こちら](https://qiita.com/nagix/items/3d0555df2cbea2783856#json-schema-でレスポンスデータを検証する)をご覧ください。[tv4](https://github.com/geraintluff/tv4) の使用は非推奨になりました。
:::

# 非同期リクエストを送信する

テストコードからリクエストを送信し、レスポンスをログに出力することができます：

```js
pm.sendRequest("https://postman-echo.com/get", function (err, response) {
  console.log(response.json());
});
```