午前3時の沈黙と信頼喪失
深夜というか、まあ夜中に近い時間帯だろうか。スマホが微妙な振動をした気がする。「テストまた失敗してるみたいだけど、誰か見てくれない?」みたいなSlackの通知。たしか三時くらいだったと思うけど、もう少し早かったかもしれない。実はさっきまでは自分の手元で、その同じテストが普通に通っていた気がする。でもCI環境だと、どうやらまたダメだったようで……。
よくある話だけど、こういう時は誰かが半分寝ぼけながら再実行ボタンを押して、それで何となく一件落着した雰囲気になることも多い。ただ根本的な問題は解決されずに残ることも多そうだし、その辺り曖昧なまま時間だけが流れていく感じかな。
この類のフレークな挙動って、一晩で何度も発生するときもあれば、ほとんど現れない日もあるっぽい。一体何人くらい同じ経験をしているのか想像すると、不思議と眠気が増す日もある。
よくある話だけど、こういう時は誰かが半分寝ぼけながら再実行ボタンを押して、それで何となく一件落着した雰囲気になることも多い。ただ根本的な問題は解決されずに残ることも多そうだし、その辺り曖昧なまま時間だけが流れていく感じかな。
この類のフレークな挙動って、一晩で何度も発生するときもあれば、ほとんど現れない日もあるっぽい。一体何人くらい同じ経験をしているのか想像すると、不思議と眠気が増す日もある。
誰も答えないリリース直前のCI地獄
たしか、あの時だったかな。テストスイートに対する信頼感が、ほとんど消えかけているような空気が漂っていた。なんとなく、みんな口には出さないけど内心では「もう信用できないかも」と思っていた気がする。まあ、うちのチームだけじゃなくて、他でもそういう話は耳にしたことがある。
で、その日だよね。リリースのタイミングはいつもよりやや緊張してたけど、それでも普段通り進むはずだった。なのに、PMから「このビルド、本当に大丈夫?」みたいな質問が飛んできた瞬間、誰も何も言わなくなった。一瞬静まり返って…。その沈黙こそが答えになったような気もする。
最近では、テスト結果自体を疑う声もちょいちょい聞こえるし、「これ、本当に意味ある?」と小声でぼやいている人もいる。こういう雰囲気になるまでには少し時間がかかったけど、なんというか…徐々に蓄積した不安感みたいなもの?明確なきっかけは覚えてないけど、多分七十回以上同じようなトラブルを経験した後だったかもしれない。
結局のところ、「テスト=安心」という図式が崩れると、デプロイそのものにも疑問符がつくようになるみたい。でも、それをどう乗り越えるかまではまだ分からないかな…。
で、その日だよね。リリースのタイミングはいつもよりやや緊張してたけど、それでも普段通り進むはずだった。なのに、PMから「このビルド、本当に大丈夫?」みたいな質問が飛んできた瞬間、誰も何も言わなくなった。一瞬静まり返って…。その沈黙こそが答えになったような気もする。
最近では、テスト結果自体を疑う声もちょいちょい聞こえるし、「これ、本当に意味ある?」と小声でぼやいている人もいる。こういう雰囲気になるまでには少し時間がかかったけど、なんというか…徐々に蓄積した不安感みたいなもの?明確なきっかけは覚えてないけど、多分七十回以上同じようなトラブルを経験した後だったかもしれない。
結局のところ、「テスト=安心」という図式が崩れると、デプロイそのものにも疑問符がつくようになるみたい。でも、それをどう乗り越えるかまではまだ分からないかな…。
Comparison Table:
テスト環境の独立性 | ワーカーごとのユーザーやリソースの割り当て |
---|---|
自動化の利点 | ログイン処理や設定が自動化され、手作業が減少 |
不安定さの軽減 | 各テストシナリオが他と無関係に進行することで、失敗率が低下 |
テナント設定の重要性 | 共通リソースを見逃すとトラブルを招く可能性がある |
CIパイプラインでの工夫 | 環境変数としてテナント情報をまとめることが効果的 |

テストはなぜ嘘をつく?並列実行と謎バグ
CIのテストが上手くいかなかった時、なんだか作業を一旦止めて原因探しに追われることになる。まあ、それ自体はどこでも起きてそうだけど、「テストがフレークする」って問題、実はテスト技術そのものより、もっと信頼の話だったりもするみたい。そこからどうやって信頼を取り戻すか、簡単そうで案外効いた方法が見つかった――各ワーカーごとにテナント分離しただけ。
なんとなくPlaywrightで並列に動かしてスピード出せるのは嬉しいんだけど、共通のデータ(例えばユーザー設定とか機能フラグとか)を書き換えるような形になってたら…不思議な失敗がぽつぽつ現れて、それこそ「これ本当に自分のせい?」みたいな気分になる。
思い返せば最初は全然問題ないと思ってた。小さなユーティリティ関数を使って設定を書き換えてたんだよね。
ユーザー設定自体もシンプルで、大まかにはテーマ(ダーク/ライト)、コメント・いいね・ユーザー表示ON/OFFくらい。
それで例えば、一つ目のテストではダークテーマがちゃんと反映されるかを見るやつ:
もう一方は「いいね」が非表示になるパターン:
この二つ、一個ずつ手動で走らせれば何事もなく通る。けど…
なんとなくPlaywrightで並列に動かしてスピード出せるのは嬉しいんだけど、共通のデータ(例えばユーザー設定とか機能フラグとか)を書き換えるような形になってたら…不思議な失敗がぽつぽつ現れて、それこそ「これ本当に自分のせい?」みたいな気分になる。
思い返せば最初は全然問題ないと思ってた。小さなユーティリティ関数を使って設定を書き換えてたんだよね。
import { updateUserConfiguration } from "./test-api";
export class TestUtils {
static async setup(userId: number, config: Partial<UserConfiguration>, token: string): Promise<void> {
await updateUserConfiguration(userId, {...this.defaultConfig(), ...config}, token);
}
static defaultConfig(): UserConfiguration {
return {
theme: 'light',
showUser: true,
likesEnabled: true,
commentsEnabled: true
};
}
}
ユーザー設定自体もシンプルで、大まかにはテーマ(ダーク/ライト)、コメント・いいね・ユーザー表示ON/OFFくらい。
export interface UserConfiguration {
theme: 'dark' | 'light';
commentsEnabled: boolean;
likesEnabled: boolean;
showUser: boolean;
}
それで例えば、一つ目のテストではダークテーマがちゃんと反映されるかを見るやつ:
test('authenticates with Bret, sets dark theme via API, and validates dark theme on home page', async ({ page }) => {
await TestUtils.setup(1, { theme: 'dark' }, 'Bret');
const mainPage = new MainPage(page);
await mainPage.navigate();
await mainPage.authenticateAs('Bret');
expect(await mainPage.getCurrentTheme()).toBe('dark');
});
もう一方は「いいね」が非表示になるパターン:
test('sets up Bret to hide likes and validates user cannot see likes', async ({ page }) => {
await TestUtils.setup(1, { likesEnabled: false }, 'Bret');
const postPage = new PostPage(page);
await postPage.navigate(1);
await postPage.authenticateAs('Bret');
await expect(postPage.likeButton).toBeVisible({ visible: false });
});
この二つ、一個ずつ手動で走らせれば何事もなく通る。けど…
何度も繰り返す“とりあえずリトライ”の無限ループ
同時に二つのPlaywrightテストを動かすなんて、まあ、ちょっとした混沌が生まれることもあるみたい。最初のテストでテーマを暗めに変更して、その後すぐ別のテストが始まる流れだと、何となくうまくいかない場面が出てきたんだとか。どっちのテストも同じ利用者、確か一人だけのユーザーだった気がするけど、その人の設定をお互い勝手に変えちゃうから、片方は「いいね」が見えなくなることを期待していたのに、実際には前のテストで暗いテーマが残っていたりするらしい。 テーマ切り替えの後ですぐ次へ進んじゃうから、それぞれの結果も毎回バラバラになったとか。片方は「いいね」がちゃんと表示されているようで、もう片方では暗い画面なのに肝心な項目が消えていた…みたいな状態だったとの話も耳にしたことがある。ユーザーステータスを共有しているから、このあたり微妙な挙動になりやすいかもしれない。でも全部の場合でそうなるわけでもなさそうで、一部だけで現れるっぽい。

原因不明の競合状態に振り回される開発者たち
時々、ダークテーマのテストがなぜか上手くいかないんだよね。まあ、いい加減に順番が変わったりするからなのかな、たぶん「いいね」機能のテストが先に走っちゃって、そのせいで設定が初期化されたりしてるみたい。逆もあって、「いいね」のチェックがダークテーマを引き継いじゃうこともあるし。まあ、何て言えばいいんだろ…どっちが先になるかなんてほぼ予想できない状況。
それはそうと、不思議な例え話を聞いたことがある。二人の料理人が同じフライパンで違う料理作ろうとしている感じ。一方は野菜をさっと炒めようとしてるところに、もう一人はパンケーキを焼こうとするから、とにかく結果は安定しないという話らしい。
そういうカオスなおかげで、開発チームのメンバー達もそれぞれ自分流の対応策というか逃げ道を見つけ始めた。「もう一回やればそのうち通るでしょ」とか、「まあ不安定なんじゃない?」とか、「自分のPCでは大丈夫だったんだけどな…」みたいな声もちらほら。それぞれ工夫してたけど、根本解決にはならず…。
ただ、そのあとになって案外シンプルな方法に気づいた人もいて。正直、それまで思いつかなかったのもちょっと恥ずかしいくらい簡単だったとか…。まあつまり、一つのユーザーアカウントを全員で取り合う形じゃなくて、「Playwright」のワーカーごとに専用のテナント(利用環境?)を割り当ててあげれば良かったらしい。それだけでも結構落ち着いた気配も出てきたとか。でも、それ以外にも細かな調整は必要だったみたいで、一気に全部解決とはいかなかったと思う。
一瞬で終わった単純すぎる解決策、それが隔離
なんだか最近、テストの環境分けって複雑になってきた気がする。プレイライトで並列にテストを動かす場合、各ワーカーごとにユーザーや投稿みたいなリソースを割り当てる方法が必要になるんだけど、それ用の設定ファイルを書いてみたりして。たとえば「アンタネット」とか「サマンサ」みたいな名前やIDをそれぞれの担当に割り振る感じ。数字も正確には覚えてないけど、四つくらい用意されていたような。
でも面白いのは、その後。自動的にどのワーカーが今実行中なのか、プレイライトのtest.info().parallelIndexっていう仕組みで判断できるみたい。それで、「今このワーカーは誰を担当してる?」とか「どの投稿を見るべき?」とか全部環境変数から引っ張ってきてくれる工夫が施されていた気がする。
コードも細かい部分までは頭に入ってこないことあるけど、大体こういう流れだったはず――まず初期化で、そのワーカー専用の設定値(たとえばテーマとか、コメント機能ON/OFFとか)をセットアップ。そのあとで投稿ページへ移動してログイン処理。この辺もほぼ自動化されているので、一々手作業というよりは流れ作業っぽい。
これらのお陰かどうかわからないけど、テスト一つひとつが他とは無関係に進むようになった印象はある。誰にも邪魔されず、自分だけの設定・リソース使えるから、「さっき別テストで何か壊したせいで失敗した…」みたいな現象、減ったと思う人もいるらしい。「いいね」ボタン消えてたり表示されたり、「ユーザー情報ウィジェット」が見えなくなるケースも個別対応しやすくなった。ただ実際ところどこまで安定しているかはまだ試行錯誤中だろうし、人によって意見分かれるんじゃないかな…。
そうそう、「カリアンヌ」のためだけコメント欄非表示だとか、「カムレン」はプロフィール非公開状態、とか細かな違いにも柔軟に対応可能になったようだった。でも、この辺りもちょっと記憶怪しい部分あるので間違ってたらごめんなさい。
全体として見ると、多分これまで以上に各テストシナリオごとの独立性が保たれている…ことになりそう。ただ絶対大丈夫とは限らなくて、ごく稀に謎めいた不安定さ出る日もあった気がするし、一概には語れない部分多いとも思う。それでも以前より信頼度上げやすくなったという話はちらほら聞こえてきて、もし開発者側の心理的ハードル下げる効果あれば、それだけでも十分意味ありそうだよね。
でも面白いのは、その後。自動的にどのワーカーが今実行中なのか、プレイライトのtest.info().parallelIndexっていう仕組みで判断できるみたい。それで、「今このワーカーは誰を担当してる?」とか「どの投稿を見るべき?」とか全部環境変数から引っ張ってきてくれる工夫が施されていた気がする。
コードも細かい部分までは頭に入ってこないことあるけど、大体こういう流れだったはず――まず初期化で、そのワーカー専用の設定値(たとえばテーマとか、コメント機能ON/OFFとか)をセットアップ。そのあとで投稿ページへ移動してログイン処理。この辺もほぼ自動化されているので、一々手作業というよりは流れ作業っぽい。
これらのお陰かどうかわからないけど、テスト一つひとつが他とは無関係に進むようになった印象はある。誰にも邪魔されず、自分だけの設定・リソース使えるから、「さっき別テストで何か壊したせいで失敗した…」みたいな現象、減ったと思う人もいるらしい。「いいね」ボタン消えてたり表示されたり、「ユーザー情報ウィジェット」が見えなくなるケースも個別対応しやすくなった。ただ実際ところどこまで安定しているかはまだ試行錯誤中だろうし、人によって意見分かれるんじゃないかな…。
そうそう、「カリアンヌ」のためだけコメント欄非表示だとか、「カムレン」はプロフィール非公開状態、とか細かな違いにも柔軟に対応可能になったようだった。でも、この辺りもちょっと記憶怪しい部分あるので間違ってたらごめんなさい。
全体として見ると、多分これまで以上に各テストシナリオごとの独立性が保たれている…ことになりそう。ただ絶対大丈夫とは限らなくて、ごく稀に謎めいた不安定さ出る日もあった気がするし、一概には語れない部分多いとも思う。それでも以前より信頼度上げやすくなったという話はちらほら聞こえてきて、もし開発者側の心理的ハードル下げる効果あれば、それだけでも十分意味ありそうだよね。

workerごとの分離設定ファイルで意外な安心感
テストで使い回されるリソース、たとえばユーザーや設定ファイル、それからデータなんかが重なっていることは時々あるみたいだ。どこかで聞いた話では、そうした共通部分を見逃すとあとで面倒になるらしい。実際にやる場合、まずはそれぞれのワーカー用に何となく似たようなテナント設定をいくつか用意しておくことが求められるようだ。それも、一度決めたものをちょっとずつ手直しする感じで。
テストのヘルパー的な関数やツールも、どこかで `test.info().parallelIndex` という仕組みを使うように書き換えたほうが良さそう。このへんは細かな作業が多くて、気づけば一部漏れている…なんてことも起こりえる。まあ、全部完璧には難しいかな。
ところで各テナントの準備だけど、どうやら裏側の処理(バックエンド)で統一的な初期化をする方法が選ばれることが多いっぽい。同じ条件にそろえておいた方が後々トラブルになりにくいとか。具体的には全部同じような構成とデータになっている必要がある、とまでは言わないけど、大体似てるくらいじゃないかな。
CI環境だと、そのテナント情報をまとめて環境変数としてセットする流れになるケースも見かける。CircleCIなどでもそういう設定ファイル内に記述していることがあった気がする。ただし、その手順自体は人によって微妙に違うかもしれない。
スケールについて考えるなら――例えばワーカー数を四つ以上まで増やしたければ、その分だけ追加でテナント設定を書き足す形になるだろうと言われている。その仕組み自体は大げさじゃなくて、CIサーバー側の余裕さえあれば横展開しやすいんじゃないかという声もちらほら聞こえてきた気がする。ただ、それでも限界はあるので、本当に必要かどうか検討しながら進めても良さそうだ。
結局のところ、このあたり一連の流れをローカルでも少し worker 数変えたり試してみながら調整すると、不思議と動作確認もしやすかったりする。それぞれ現場ごとの事情にもよるけど、おおむねそんな雰囲気だった気がする。
テストのヘルパー的な関数やツールも、どこかで `test.info().parallelIndex` という仕組みを使うように書き換えたほうが良さそう。このへんは細かな作業が多くて、気づけば一部漏れている…なんてことも起こりえる。まあ、全部完璧には難しいかな。
ところで各テナントの準備だけど、どうやら裏側の処理(バックエンド)で統一的な初期化をする方法が選ばれることが多いっぽい。同じ条件にそろえておいた方が後々トラブルになりにくいとか。具体的には全部同じような構成とデータになっている必要がある、とまでは言わないけど、大体似てるくらいじゃないかな。
CI環境だと、そのテナント情報をまとめて環境変数としてセットする流れになるケースも見かける。CircleCIなどでもそういう設定ファイル内に記述していることがあった気がする。ただし、その手順自体は人によって微妙に違うかもしれない。
スケールについて考えるなら――例えばワーカー数を四つ以上まで増やしたければ、その分だけ追加でテナント設定を書き足す形になるだろうと言われている。その仕組み自体は大げさじゃなくて、CIサーバー側の余裕さえあれば横展開しやすいんじゃないかという声もちらほら聞こえてきた気がする。ただ、それでも限界はあるので、本当に必要かどうか検討しながら進めても良さそうだ。
結局のところ、このあたり一連の流れをローカルでも少し worker 数変えたり試してみながら調整すると、不思議と動作確認もしやすかったりする。それぞれ現場ごとの事情にもよるけど、おおむねそんな雰囲気だった気がする。
parallelIndexマジック、各自孤立テナントへ誘う小技
全体の流れをなんとなく振り返ると、テストが不安定だと開発チームの雰囲気もどこか落ち着かなくなることがあるみたい。誰かが「またテスト通らない…」なんて呟いて、レビューもつい本質じゃないところで時間取ったりしてね。デプロイ前に妙な緊張感が漂うことも珍しくないし、結局リリースまで想像より長引いたりする。
でも、ここ最近で何度か試行錯誤を重ねた結果、以前よりはずっと安定してきた気がする。CIの失敗がほぼなくなって、やり直しとか「自分の環境では上手くいくのに…」という話を聞く機会も減ったような。幽霊みたいなバグ調査で丸一日潰す…そんな心配も今はあまり聞かなくなった印象。
それと、不思議だけどテストを書こうとする人もちょっと増えた気配さえある。レビュー時に「このコード論理的にどう?」という話題が中心になってきて、「これ通すとCI壊れたりしないかな」と疑う声は前ほど多くないようだ。
そうそう、一見些細なリソース共有でも油断するとどこかで不安定さにつながることがあるらしい。パターンに早めに気付けば、大きく悩まず済む場合も少なくない、と誰かが言っていたような…。全部完璧とは言えないけど、七十回くらい試した中では、確かに変化は感じている人もいるみたいだよ。
でも、ここ最近で何度か試行錯誤を重ねた結果、以前よりはずっと安定してきた気がする。CIの失敗がほぼなくなって、やり直しとか「自分の環境では上手くいくのに…」という話を聞く機会も減ったような。幽霊みたいなバグ調査で丸一日潰す…そんな心配も今はあまり聞かなくなった印象。
それと、不思議だけどテストを書こうとする人もちょっと増えた気配さえある。レビュー時に「このコード論理的にどう?」という話題が中心になってきて、「これ通すとCI壊れたりしないかな」と疑う声は前ほど多くないようだ。
そうそう、一見些細なリソース共有でも油断するとどこかで不安定さにつながることがあるらしい。パターンに早めに気付けば、大きく悩まず済む場合も少なくない、と誰かが言っていたような…。全部完璧とは言えないけど、七十回くらい試した中では、確かに変化は感じている人もいるみたいだよ。

環境準備・スケール・変数管理――細かいけど重要な裏側
たしか、テナント分離のパターンを設定するのに、ほんの数時間もかからなかったと思う。いや、三時間弱くらいだったかな。これで開発者の作業効率とか、テストスイートへの信頼感が結構上がったような気がする。
ただ、本質的な話って単なるユーザー設定だけじゃなくて――むしろ、「どんな共有リソースでもテストで不安定さの原因になり得る」ってところに気付くことが大事かもしれない。例えば、アカウントやらフラグやら、ファイル置き場とかデータベースの中身なんかもそうだし……API制限とかブラウザセッションとかも頭に浮かぶ。細かいものまで挙げたらキリがない。
それぞれ問題になるポイントは違うけど、とにかく「共有している依存先を見つけて、それを実行中のワーカー単位で分割する」。このパターン自体はあまり変わらないんだよね。
Playwright の並列テスト回してるとき、「あれ?今まで動いてたはずなのになぜか失敗する」みたいな現象に出くわす人、多いんじゃないかなぁ。自分たちの場合も似たような競合状態(レースコンディション)っぽい何かで悩まされた記憶がある。それこそ各ワーカーごとにテナントを切り分けてみたら、不思議と落ち着いたという感じだった。
まあ全部のケースで効くとは言えないけど、この方法を試す価値はありそう。少なくとも一部では開発者の精神衛生にも多少いい影響あった、そんな印象かな…。
ただ、本質的な話って単なるユーザー設定だけじゃなくて――むしろ、「どんな共有リソースでもテストで不安定さの原因になり得る」ってところに気付くことが大事かもしれない。例えば、アカウントやらフラグやら、ファイル置き場とかデータベースの中身なんかもそうだし……API制限とかブラウザセッションとかも頭に浮かぶ。細かいものまで挙げたらキリがない。
それぞれ問題になるポイントは違うけど、とにかく「共有している依存先を見つけて、それを実行中のワーカー単位で分割する」。このパターン自体はあまり変わらないんだよね。
Playwright の並列テスト回してるとき、「あれ?今まで動いてたはずなのになぜか失敗する」みたいな現象に出くわす人、多いんじゃないかなぁ。自分たちの場合も似たような競合状態(レースコンディション)っぽい何かで悩まされた記憶がある。それこそ各ワーカーごとにテナントを切り分けてみたら、不思議と落ち着いたという感じだった。
まあ全部のケースで効くとは言えないけど、この方法を試す価値はありそう。少なくとも一部では開発者の精神衛生にも多少いい影響あった、そんな印象かな…。
全ては信頼回復のために…孤立化パターンの威力
今までに、似たようなパターンをテストスイートで試したこと、ありますかね?まあ、人によっては何度か見かけた話かもしれませんけど。CIのパイプラインで妙にややこしくなる共通リソース、なんだかんだで色々ある気がしますよ。自分では「これかな」と思うものがあったり、逆に曖昧なままだったり。テストの不安定さ――いわゆるフレーク問題について、ほかの方はどう対処しているのでしょう。工夫しても全部がすっきり片付くわけじゃないですが、「このくらい効いた」という手応えとか、「まあ参考程度だけど」みたいな方法論、もしよろしければコメント欄でシェアしていただけると助かります。最近だと七十件近い議論も流れていましたし、その中でも完全に一致する意見というよりは「ああ、自分もそんな経験ある」みたいな空気感でしたね。不確かな部分も多いですが、それぞれのやり方や悩み事など聞いてみたいところです。