第6章:高度な機能編

この章では、runnの高度な機能について説明します。これらの機能を使うことで、より複雑なテストシナリオを作成できます。

ループ処理

基本的なループ

desc: 基本的なループ処理
runners:
  httpbin: http://localhost:8080

vars:
  test_users:
    - name: "Alice"
      email: "alice@example.com"
    - name: "Bob"
      email: "bob@example.com"
    - name: "Charlie"
      email: "charlie@example.com"

steps:
  # 単純な回数指定ループ
  - desc: 単純な回数指定ループ
    loop: 5
    httpbin:
      /status/200:
        get:
          body:
    test: current.res.status == 200
    dump: i  # ループインデックス(0から開始)

  # 配列の各要素に対するループ
  - desc: 配列の各要素に対するループ
    loop:
      count: len(vars.test_users)
    httpbin:
      /post:
        post:
          body:
            application/json:
              name: "{{ vars.test_users[i].name }}"
              email: "{{ vars.test_users[i].email }}"
    test: |
      current.res.status == 200 &&
      current.res.body.json.name == vars.test_users[i].name &&
      current.res.body.json.email == vars.test_users[i].email

条件付きループ(リトライ機能)

desc: 条件付きループ(リトライ機能)
runners:
  httpbin: http://localhost:8080

vars:
  max_retries: 3

steps:
  # 成功するまでリトライ
  - desc: 成功するまでリトライ(基本例)
    loop:
      count: 3
      until: current.res.status == 200
      minInterval: 1s
      maxInterval: 2s
    httpbin:
      /status/200:
        get:
          body:
    test: current.res.status == 200

  # ヘッダーの条件でリトライ
  - desc: ヘッダーの条件でリトライ
    loop:
      count: 3
      until: |
        current.res.status == 200 &&
        current.res.headers["Content-Type"][0] == "application/json"
    httpbin:
      /response-headers?Content-Type=application/json:
        get:
          body:
    test: |
      current.res.status == 200 &&
      current.res.headers["Content-Type"][0] == "application/json"

  # タイムアウトを伴うリトライ  
  - desc: タイムアウトを考慮したリトライ
    loop:
      count: 5
      until: current.res.status == 200
      minInterval: 500ms
      maxInterval: 2s
    httpbin:
      /delay/1:
        get:
          timeout: 3s
          body:
    test: current.res.status == 200

条件付き実行

ifフィールドを使用すると、特定の条件が満たされた場合にのみステップを実行できます。

desc: 基本的な条件分岐
runners:
  httpbin: http://localhost:8080

vars:
  enable_test: true
  test_value: 42

steps:
  # 変数による条件分岐
  - desc: 機能フラグのチェック
    if: vars.enable_test
    httpbin:
      /status/200:
        get:
          body:
    test: current.res.status == 200

  # 条件が偽の場合(スキップされる)
  - desc: スキップされるステップ
    if: vars.enable_test == false
    httpbin:
      /status/500:
        get:
          body:
    test: current.res.status == 500

  # 常に実行されるステップ
  - desc: データの投稿
    httpbin:
      /post:
        post:
          body:
            application/json:
              value: "{{ vars.test_value }}"
              enabled: "{{ vars.enable_test }}"
    test: |
      current.res.status == 200 &&
      current.res.body.json.value == vars.test_value

  # 前のステップの結果による条件分岐
  - desc: 前のステップが成功した場合のみ実行
    if: steps[2].res.status == 200
    httpbin:
      /anything:
        get:
          query:
            previous_value: "{{ steps[2].res.body.json.value }}"
          body:
    test: current.res.status == 200

シナリオのインクルード

他のYAMLファイルをインクルードすることで、共通処理を再利用できます。

desc: 基本的なインクルード
runners:
  httpbin: http://localhost:8080

steps:
  - desc: メインファイルから実行開始
    dump: '"=== メインファイル (include_basic.yml) から実行開始 ==="'

  - desc: 共通処理をインクルード
    include:
      path: ./common/auth.include.yml

  - desc: メインファイルに戻りました
    dump: '"=== メインファイル (include_basic.yml) に戻りました ==="'

  - desc: インクルード後のテスト
    httpbin:
      /get:
        get:
          query:
            included: "true"
    test: current.res.status == 200
# インクルードされるファイル
desc: 共通の前処理

steps:
  - desc: インクルードされたステップの開始
    dump: '"    >>> インクルードファイル (auth.yml) の実行開始 <<<"'

  - desc: 認証処理(例)
    httpbin:
      /status/200:
        get:
          body:
    test: current.res.status == 200

  - desc: インクルードされたステップの終了
    dump: '"    >>> インクルードファイル (auth.yml) の実行終了 <<<"'

実行結果:

=== メインファイル (include_basic.yml) から実行開始 ===
=== メインファイル (include_basic.yml) に戻りました ===

Runbook間の依存関係(needs)

needsフィールドを使用すると、他の Runbook を事前実行できます。

desc: 他のRunbookへの依存関係(needs)

# 他のRunbookの実行結果を必要とする
needs:
  setup: ./common/setup.include.yml

steps:
  - desc: needsで依存関係のRunbookを実行
    dump: "メインRunbookを実行しました"
# セットアップ用のRunbook
desc: 初期セットアップ処理

steps:
  - desc: セットアップ処理
    dump: "セットアップ完了しました"

実行結果:

null
null