kickflow Tech Blog

株式会社kickflowのプロダクト開発本部によるブログ

Autifyの弱点をCypressで補完:ノーコード×コードベースで実現するE2Eテスト戦略

ビーバーは「自分の生活のために周囲の環境を作り替える、ヒト以外の唯一の動物」であると言われる

こんにちは、kickflow QAチームの川村です。

「ノーコードツールだけでは対応しきれないテストケースがある」「コードベースのテストツールを導入したいが、どう使い分ければよいかわからない」といった課題を抱えていませんか?

本記事では、ノーコードE2EテストツールのAutifyと、コードベースのCypressを組み合わせることで、それぞれの強みを活かしたハイブリッドなE2Eテスト戦略を構築した事例をご紹介します。
具体的な使い分けの基準や、導入時の課題とその解決策まで詳しく解説します。

背景:なぜCypressを導入したのか

kickflowでは、E2EテストのメインツールとしてAutifyを使用しています。
Autifyはノーコードで直感的にテストを作成できる優れたツールですが、以下のようなテストケースでは実装が困難、または不安定になることがありました。

  • AIオプション機能のテスト:毎回出力が異なるため、固定値での検証が難しい
  • 同一画面での繰り返し操作:似たような要素が多い画面での操作が不安定になりやすい
  • 複雑な条件分岐を含むテスト:コードベースでの柔軟な制御が必要

これらの課題を解決するため、Autifyを補完するツールとしてCypressを導入することにしました。

AutifyとCypressの使い分けイメージ

項目 Autify Cypress
役割 メインツール 補完ツール
得意な領域 頻繁なUI変更への追従、シンプルなシナリオ 複雑なロジック検証、動的データの扱い、監査ログ
作成者 非エンジニアでも可能 AIツール活用で非エンジニアでも可能
メンテナンス AIによる自己修復 Claude Code等のAIツールで効率化

※ Cypressの実装やメンテナンスはClaude CodeなどのAIツールを活用しており、以前に比べて実装コストが格段に下がっています。

なぜCypressを選んだのか

コードベースのE2Eテストツールとして、Playwright、Puppeteer、WebdriverIO、TestCafeなども検討しました。

cypress-vs-playwright-vs-puppeteer-vs-testcafe-vs-webdriverio
コードベース自動テストツールのトレンド

※ 2023年7月時点での検討です。
上のグラフを見ると、現在であればPlaywrightが第一候補になると思いますが、当時はCypressのエコシステムの成熟度やドキュメントの充実度が決め手となりました。

その中でCypressを選んだ決め手は以下の点です。

Time Travel機能によるデバッグの容易さ

テスト実行の各ステップをスナップショットで確認でき、失敗原因の特定が直感的に行えます。
これは、テストが失敗したときの調査時間を大幅に短縮してくれます。

Cypress Cloudによる並列実行

テストファイルを複数ワーカーに自動分散し、実行時間を大幅に短縮できます。
実測では、4並列実行により約73%の時間短縮を実現しました。

カスタムコマンドによる抽象化

cy.login()cy.createTicket()のように、業務固有の操作をカスタムコマンドとして抽象化できます。
これにより、テストコードの重複を削減し、保守性を向上させることができました。

// cypress/support/commands.ts

// ログインコマンド:URLとメールアドレスを指定するだけでログイン処理を実行
Cypress.Commands.add('login', (url = '/dashboard', email?: string) => {
  cy.visit('/signin')
  cy.get('[data-testid="loginBtn.email"]').should('be.visible').click()

  cy.fixture('users').then(users => {
    const userEmail = email ? email : users[0].email
    cy.get('[name="username"]').type(userEmail)
    cy.get('[name="password"]').type(Cypress.env('userPassword'), { log: false })
  })

  cy.get('[data-action-button-primary="true"]').click()
  cy.url().should('contain', '/dashboard')
  cy.visit(url)
})

// チケット作成コマンド:APIを直接呼び出してテストデータを生成
Cypress.Commands.add('createTicket', (options = {}) => {
  const request = {
    status: options.status || 'draft',
    title: options.title || 'Cypressによる自動生成',
    workflowId: options.workflowId || Cypress.env('WORKFLOW_ID'),
    inputs: options.inputs || [],
  }
  return createTicket(request, options.email)
})

テストコード側では、このようにシンプルに呼び出すだけで済みます。

// テストコードでの使用例
cy.login('/dashboard/tickets', 'test@example.com')
cy.createTicket({ title: 'テスト申請', status: 'in_progress' })

導入時に苦労した点

Cypressの導入はスムーズにいった部分も多かったですが、いくつかの課題にも直面しました。

ブラウザの言語設定

Ubuntu環境(GitHub Actions)でテスト実行時にブラウザが英語表示になる問題がありました。
cypress.config.tsでChrome起動引数とLANG環境変数を設定することで対応しました。

// cypress.config.ts
on('before:browser:launch', (browser, launchOptions) => {
  if (browser.name === 'chrome' || browser.name === 'chromium') {
    launchOptions.args.push('--lang=ja')
    launchOptions.args.push('--accept-lang=ja-JP,ja')
    launchOptions.env = {
      ...launchOptions.env,
      LANGUAGE: 'ja_JP.UTF-8',
      LANG: 'ja_JP.UTF-8',
      TZ: 'Asia/Tokyo'
    }
  }
  return launchOptions
})

テスト環境のBasic認証対応

テスト環境にBasic認証がかかっており、cy.visit()時の認証ヘッダー設定が必要でした。
Cypress.Commands.overwritevisitコマンドを上書きし、環境変数から認証情報を自動付与するようにしました。

// cypress/support/commands.ts
Cypress.Commands.overwrite(
  'visit',
  (originalFn, url, options = {}) => {
    const username = Cypress.env('basicAuthUsername')
    const password = Cypress.env('basicAuthPassword')

    if (username && password) {
      originalFn(url, {
        auth: { username, password },
        ...options,
      })
    } else {
      originalFn(url, options)
    }
  },
)

これにより、テストコード側では通常のcy.visit()を呼び出すだけで、Basic認証が自動的に処理されます。

非同期処理の待機

SPAの動的コンテンツに対する適切な待機処理の設計が必要でした。
具体的には、以下のようにcy.intercept()を活用してAPIレスポンスを待つことで、Flaky(不安定)なテストを防いでいます。

// 例: チケット情報の読み込み完了を待つ
cy.intercept('GET', '**/tickets/**').as('loadTicket')
cy.login('/dashboard/tickets/xxx/edit', 'user@example.com')
cy.wait('@loadTicket', { timeout: 15000 }) // APIが返ってくるまで確実に待機

アーキテクチャ:2つの実行モードの使い分け

現在、Cypressテストは2つのモードで運用しています。

flowchart TB
    subgraph Triggers["トリガー"]
        Manual["👆 手動トリガー"]
        Schedule["⏰ スケジュール実行<br/>平日 01:00 JST"]
    end

    subgraph GitHubActions["GitHub Actions"]
        subgraph LocalMode["自作並列モード"]
            LocalWorkers["並列実行(4ワーカー)"]
        end
        subgraph CloudMode["Cypress Cloud連携モード"]
            CloudWorkers["並列実行(4ワーカー)"]
        end
    end

    subgraph LocalOutputs["ローカル出力"]
        Mochawesome["📄 レポート"]
    end

    Sandbox["🌐 テスト対象環境"]

    subgraph CypressCloud["Cypress Cloud"]
        Dashboard["📊 ダッシュボード"]
    end

    Slack["💬 Slack通知"]

    Manual --> LocalMode
    Manual --> CloudMode
    Schedule --> CloudMode

    LocalWorkers --> Mochawesome
    LocalWorkers --> Sandbox
    CloudWorkers --> Sandbox
    CloudWorkers --> Dashboard

    Mochawesome --> Slack
    Dashboard --> Slack

    style Schedule fill:#4CAF50,color:#fff
    style Manual fill:#2196F3,color:#fff
    style CloudMode fill:#e3f2fd,color:#1565c0
    style LocalMode fill:#fff3e0,color:#e65100

1. Cypress Cloud連携モード(定期実行用)

平日毎朝1時にスケジュール実行しています。
Cypress Cloudがテストの分散、結果の可視化、Slack通知を担当します。

2. 自作並列モード(手動実行用)

開発中の検証やNightly以外のテスト実行では、Cypress Cloudに連携せず、自作の並列実行スクリプトを使用しています。

この使い分けの理由は、Cypress Cloudはプランによっては使用量に応じて追加課金が発生するためです。
定期実行のみCypress Cloudを使用し、それ以外は自作の並列実行を活用することでコストを最適化しています。

自作並列実行の詳細については、以下の記事で解説しています。

tech.kickflow.co.jp

導入の成果

Cypressを導入し、Autifyと組み合わせることで、以下の成果が得られました。

1. ノーコードでは検証困難だった領域の自動化

Autifyでは実装コストが高かった「複雑な条件分岐」や「動的な監査ログの検証」などをCypressで実装しました。
これにより、これまでは手動テストに頼らざるを得なかった機能も、毎日の自動テストに組み込むことができました。

主なCypress担当領域 ファイル数
監査ログの検証 39ファイル
複雑な条件分岐を含むケース 64ファイル
合計 103ファイル

2. 安定した並列実行環境の構築

Cypress Cloudと自作スクリプトによる並列実行を活用することで、重たいテストケースが増えても実行時間を短く抑えることができています。
現在、全457ケース(Cypress分)を約22分(4並列)で完了できており、Autifyのテスト実行と合わせても、毎朝の始業までに確実に結果を確認できる体制が整いました。

3. 監査ログテストの体系化

特に、セキュリティ・コンプライアンス要件に関わる「監査ログ」のテストは、画面操作とログデータの突合が必要なため、コードベースであるCypressの強みが活きました。
39ファイルの監査ログテストを実装し、継続的に検証できる状態を確立しました。

Cypressの良い点と課題点

実際に運用してみて感じた良い点と課題点をまとめます。

良い点

  • Time Travel機能による直感的なデバッグ体験
  • Cypress Cloudによる並列実行と結果可視化
  • 豊富なカスタムコマンド機能で業務ロジックを抽象化可能
  • 公式ドキュメントの質の高さと活発なコミュニティ
  • CI/CD統合の容易さ(GitHub Actions対応が充実)

課題点

  • 複数タブ・複数ウィンドウのテストが困難
  • iframeの操作に制約がある
  • CI環境のようなネットワーク遅延が大きい環境でのフレイキーテスト対策が必要
  • Cypress Cloudはプランによっては使用量に応じて追加課金が発生するため、コスト管理が必要

今後の展望

今後は以下の取り組みを進めていく予定です。

  • AIテスト自動生成の拡充:Playwright MCPを活用したCypressテストコード自動生成をさらに発展させ、テスト作成工数を削減
  • DevinやClaude Codeを活用したE2Eテスト修正の自動化:仕様変更に合わせたテストコード修正をAIエージェントで効率化
  • テストカバレッジの拡大:未カバーの機能領域への拡張と、エッジケースのテスト追加

まとめ

ノーコードツール(Autify)とコードベースツール(Cypress)を組み合わせることで、それぞれの強みを活かしたE2Eテスト戦略を構築できました。

  • Autifyは直感的なテスト作成と安定した操作記録が強み
  • Cypressは柔軟なカスタマイズと複雑なテストケースへの対応が強み

どちらか一方に統一するのではなく、適材適所で使い分けることが重要です。
E2Eテスト戦略にお悩みの方の参考になれば幸いです。


kickflowのQAチームでは、テスト自動化の効率化だけでなく、品質保証プロセス全体の改善に取り組んでいます。
Autifyでカバーしきれないテストケースをどう補完するか、AIを活用したテスト自動化をどう進めるかなど、技術的な課題解決に興味がある方を募集しています。

ぜひ採用サイトをご覧ください。

careers.kickflow.co.jp