Skipbox

GitHub Actions で Cypress・Playwright の E2E テストが不安定になる:ランナーが原因のとき

ローカルでは通るのに GitHub Actions でだけ落ちる E2E テストは、壊れているのではなく、マシンが足りていないことがよくあります。プライベートリポジトリの ubuntu-latest では、Cypress や Playwright、ブラウザー、アプリのサーバー、データベースが 2 CPU・メモリ 8 GB を取り合います。描画が遅れ、コマンドがタイムアウト(Cypress の既定は 4 秒)を過ぎ、ブラウザーが途中で落ちる。Cypress の公式ドキュメントも、リソース不足は「不安定、遅い、ランダムに見える失敗」として現れると書き、サンプルアプリが余裕をもって動くのは 4 vCPU・メモリ 16 GB、つまりプライベートリポジトリのランナーの 2倍だとしています。落ちる実行の最中の CPU とメモリを見て確かめ、テスト側の固定の待ちと共有データを直し、ジョブに必要なマシンを渡す。この順番です。

Skipbox なら、そのマシンが定額です。runs-on: skipbox-8x16 で 8 vCPU・メモリ 16 GB を月 12,000 円。ジョブはアカウント専用のマシンで動き、ブラウザーとパッケージは次の実行まで残ります。実行時間は無制限なので、再実行もシャードも請求は増えません。

テストは、何とランナーを分け合っているか

E2E のジョブで動くのは、テストだけではありません。Cypress の性能ガイドの言葉では「Cypress そのもの、ブラウザー、アプリのサーバー、アプリが頼っている裏のサービス」です。プライベートリポジトリの ubuntu-latest では、これが 2 CPU・メモリ 8 GB を分け合います(GitHub ホストランナー)。公開リポジトリなら 4 CPU・メモリ 16 GB で、Cypress がサンプルアプリに余裕のある大きさとして挙げているのはこちらです。

同じガイドが挙げる、マシンが足りないときの兆しです。

  • 実行が進むほど、テストが遅くなる
  • テストの失敗がはっきりしないまま、ブラウザーが途中で落ちる
  • 実行中、CPU かメモリが 100% 近くに張り付いている

Playwright はワーカーごとにブラウザーを開き、ワーカーの既定はコアの半分です。CI のドキュメントは、安定と再現性を優先して CI では workers: 1 を推奨しています。テストごとにマシンを丸ごと使えるようにするためで、並列にするのは「強力なセルフホストの CI」でなら、としています。

何かを変える前に、確かめる

  • Cypress: DEBUG=cypress:server:util:process_profiler npx cypress run で動かします。10 秒ごとに CPU とメモリが出て、CPU が 100% を超え続けていればマシンが飽和しています。
  • Playwright: 落ちたテストを --workers=1 で動かし直します。それで落ちなくなるなら、限界はテストではなくマシンです。再実行のときのトレース(trace: 'on-first-retry')を残すと、落ちたときに画面が何をしていたかが見えます。
  • どちらでも: テストの前に nproc && free -h のステップを入れ、裏で 15 秒ごとに top -b -n 1 | head -15 を記録します。

速いマシンでも同じ場所で落ちるなら、それはテストの不安定さで、マシンを大きくしても直りません。

テスト側で直すこと

  • 固定の待ちをやめる。 cy.wait(2000) や page.waitForTimeout() は、速い PC では通り、遅いランナーで落ちます。要素、ルート、レスポンスを待ちます。
  • intercept はリクエストの前に。 クリックのあとに置いた cy.intercept は、リクエストと競争になります。
  • データを分ける。 ユーザーやレコードを共有するテストは、順番が変わったり並列になったりすると落ちます。
  • CI ではリトライを有効にする。 Playwright は、落ちてから再試行で通ったテストをレポートで flaky として分けます。Cypress は retries の設定で、cypress run で落ちたテストをもう一度動かします。リトライで不安定なテストは見つかりますが、直りはしません。

シャードにかかるもの

シャードは、テストを複数のジョブに分けて、それぞれ別のマシンで動かします。Playwright は --shard=1/4 で分け、最後のジョブで blob のレポートをまとめます。Cypress の並列実行には Cypress Cloud への記録が要り、Cypress Cloud がスペックをマシンに振り分けます。

シャードはそれぞれ GitHub の新しい VM です。パッケージを入れ、ブラウザーをダウンロードし(Playwright は、復元がダウンロードと同じくらいかかるので、ブラウザーのキャッシュを勧めていません)、アプリをビルドして起動します。4 分割なら 4 回で、分課金ではそのすべてに請求が来ます。マシンが限界だったときには効きますが、準備も同じだけ増やします。

遅くて不安定なテストに、何がかかるか

E2E テストはマージ前の最後のチェックなので、チーム全員がそれを待ちます。そこに不安定な失敗の再実行が重なります。分課金では、その分数のすべてに請求が来ます。

8 vCPU で月 20,000分なら、GitHub は 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。、Skipbox M は 12,000 円です。GitHub の額は、GitHub Team に含まれる無料分を引いたあとの請求です。自分のチームの分数は、トップページの料金計算で出せます。

テストに、足りるマシンを渡す

プランごとに、アカウント専用のマシンが付き、ジョブのあとも残ります。料金は定額です。

  • 全部が動けるだけの CPU とメモリ。 skipbox-8x16 は、Cypress がサンプルアプリに挙げるメモリと、それより多いコアがあります。ブラウザー、アプリ、データベースが取り合わなくなります。8 vCPU なら、Playwright の既定のワーカーは 4 つです。
  • ブラウザーとパッケージが残る。 ~/.cache/ms-playwright の Playwright のブラウザー、~/.cache/Cypress の Cypress 本体、npm のキャッシュ、サービスの Docker のイメージが、次のジョブの始まりにディスクにあります。
  • 実行時間は無制限。 リトライも再実行もシャードも、請求は変わりません。同時に動くシャードの数はプランの vCPU の合計で決まり、超えた分は順番を待ちます。

移行は runs-on を 1行書き換えるだけ

jobs:
  e2e:
    runs-on: skipbox-8x16 # ubuntu-latest から書き換える
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: lts/*
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test

skipbox-8x16 はプラン M で動きます。トライアルで動くのは runs-on: skipbox(4 vCPU・メモリ 16 GB)です。

  1. Skipbox に GitHub でログインする
  2. Skipbox の GitHub アプリを入れて、使うリポジトリを選ぶ
  3. runs-on を書き換えて push する

セキュリティ

  • マシンはアカウントごとの専用です。ほかの会社のジョブと同じマシンで動くことはありません。
  • ジョブが終わるたびに、ランナーの認証情報、プロセスとコンテナを消します。ブラウザーとキャッシュは残ります。「毎回クリーン」なら、ジョブごとに新しいマシンで動きます。
  • 書き込み権限のない人のコード(フォークからのプルリクエストなど)は、使い捨ての VM で動きます。キャッシュは読めますが、書き換えられません。

くわしくはジョブの分離のしくみにあります。

不安定なテストで試す

カード不要で、7日間かジョブの合計 3,000分まで無料です。E2E のジョブを runs-on: skipbox に替えて何回か動かし、落ちた回数とステップの時間を GitHub と比べてください。

よくある質問

Cypress のテストが GitHub Actions でだけ不安定。ランナーの CPU やメモリが原因?

多くの場合そうです。プライベートリポジトリの ubuntu-latest は 2 CPU・メモリ 8 GB で、そこで Cypress、ブラウザー、アプリのサーバー、データベースがいっしょに動きます。取り合いになると、画面の描画が遅れ、コマンドが既定の 4 秒のタイムアウトを過ぎ、ブラウザーが途中で落ちます。Cypress の公式の性能ガイドも、リソース不足は不安定・遅い・ランダムな失敗として現れると書き、サンプルアプリは 4 vCPU・メモリ 16 GB で余裕をもって動くとしています。DEBUG=cypress:server:util:process_profiler で確かめ、固定の待ちを直し、それからジョブに大きいマシンを渡します。

Playwright の E2E テストが GitHub Actions だと不安定でローカルでは通る。ランナーの性能が原因?

その可能性は高いです。Playwright はワーカーごとにブラウザーを 1つ開き、ワーカーの既定はコアの半分です。公式の CI のドキュメントは、安定と再現性のために CI ではワーカー 1つを推奨しています。--workers=1 で通り、増やすと落ちるなら、限界はマシンです。2 CPU ならワーカー 1つのまま、コアとメモリの多いマシンに移すならそこでワーカーを増やします。

マシン不足と、テストそのものの不安定さは、どう見分ける?

落ちる実行の最中のマシンを見ます。Cypress は DEBUG=cypress:server:util:process_profiler で 10 秒ごとに CPU とメモリを出します。Playwright なら、裏のステップで free -h と top を記録するか、--workers=1 で動かし直します。マシン不足なら CPU が 100% 近くに張り付くかメモリが上限近くまで行き、落ちるテストが毎回変わり、後半ほど悪くなります。速いマシンでも同じ場所で落ちるなら、テストの問題です。

E2E テストをシャードに分けると、不安定さや料金は直る?

それだけでは直りません。シャードごとに別のマシンになるので、マシンが限界だったときは効きます。ただしシャードごとにパッケージのインストール、ブラウザーのダウンロード、アプリの起動をやり直し、分課金ではそのすべてに請求が来ます。Cypress の並列実行には Cypress Cloud への記録も要ります。Skipbox ならブラウザーとパッケージが専用のマシンに残り、実行時間は無制限なので、シャードも再実行も請求は増えません。

E2E テストには、どのくらいのランナーが要る?

テストのそばで動くもので決まります。ブラウザー、アプリのサーバー、そのサービスです。Cypress のサンプルアプリは 4 vCPU・メモリ 16 GB で余裕をもって動きます。Skipbox なら runs-on: skipbox-8x16 で 8 vCPU・メモリ 16 GB が月 12,000 円、skipbox-16x32 なら 16 vCPU・メモリ 32 GB です。

試すのにお金はかかる?

かかりません。カード不要で、7日間かジョブの合計 3,000分まで無料です。トライアルのマシンは 4 vCPU・メモリ 16 GB です。E2E のジョブを runs-on: skipbox に替えて何回か動かし、落ちた回数とステップの時間を GitHub と比べてください。

2026年11月13日 更新

常に warm なキャッシュで CI/CD を高速化するなら

専用ランナーを定額で。実行時間は無制限

フル稼働なら GitHub の 1/12 の費用。定額だから一日中動かせる。GitHub の 7倍のキャッシュ容量。

  • カード不要
  • GitHub でログイン
  • いつでも解約