Slide 1

Slide 1 text

あなたのシステムの壊し方 Takuya Suemura @ Ubie株式会社 2026.3.20 JaSST'26 Tokyo 1

Slide 2

Slide 2 text

Takuya Suemura Software Engineer in Test @ Ubie Web開発→QA→自動テストSaaS→現職 2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

みなさん、ぶっ壊してますか!!!!!! 4

Slide 5

Slide 5 text

ぶっ壊すのがテスターの本懐だよな QAの役割は、ハッピーではないパスを書くことだ。 (中略) QAの人たちはシステムを破壊する方法を見つける能力を買われて雇われている。 深い専門性を持った人たちであり、ユーザーがシステムに対して行うあらゆる奇 妙なことを予見できる。 Clean Agile 基本に立ち戻れ Robert C. Martin(著), 角征典, 角谷信太郎(訳) より 5

Slide 6

Slide 6 text

こんなときどうなる? データベースが遅くなったら? 外部APIが5xxエラーを返してきたら? ネットワークが不安定だったら? ユーザーが操作の途中でブラウザを閉じたら? 2つのタブから同時に同じデータを編集したら? デプロイの最中にリクエストが来たら? 6

Slide 7

Slide 7 text

Knowns-Unknowns 「知っている」ことと「わかっている」ことは違う わかっている わかっていない 知っている Known-Knowns Known-Unknowns 知らない Unknown-Knowns Unknown-Unknowns 7

Slide 8

Slide 8 text

Knowns-Unknowns とテスト Known-Knowns: 正常系テストでカバー済み Known-Unknowns: 壊れうることは知っているが、壊れたとき何が起きるかわか らない Unknown-Unknowns: そもそも考慮していない。壊してみて初めて気づく 普段のテストの多くは Known-Knowns の確認 「壊してみる」テストは Known-Unknowns → Known-Knowns に変える行為 8

Slide 9

Slide 9 text

壊すことは何が起きるかを知ること 1. 壊す — 意図的に障害を起こす 2. 知る — 何が起きるかを観察する(Known領域が広がる) 3. 改善する — 見えてきた弱点を直す 4. 繰り返す — レジリエンスが高まっていく 9

Slide 10

Slide 10 text

様々な壊し方 10

Slide 11

Slide 11 text

おことわり いろんなことを話します 登壇者自身もちゃんと分かってないところがあります 登壇駆動で勉強したので浅い部分があります おまえらの鋭いマサカリでおれを育ててくれ! 11

Slide 12

Slide 12 text

Known-Knowns 知っている・分かっている Known-Unknowns 知っているが分からない Unknown-Knowns 分かっていると知らない Unknown-Unknowns 分からないことすら知らない 例ベースの テストケース UI操作で壊す 開発者ツールで 壊す データを壊す ミューテーション テスト 検証 バグ分析 フォールト インジェクション カオス エンジニアリング 12

Slide 13

Slide 13 text

UI操作で壊す 〈Known-Unknowns〉 ダブルクリック・連打 — 二重送信、race condition 境界値・異常値入力 — 空文字、超長文字列、絵文字、制御文字 ブラウザバック — フォーム送信後に戻って再送信 タブの複数開き — 同一リソースの同時編集 13

Slide 14

Slide 14 text

突然ですがおれは文字関連のバグが好きです 14

Slide 15

Slide 15 text

Big List Of Naughty Strings 問題を引き起こす文字列のリポジトリ https://github.com/minimaxir/big-list-of-naughty-strings 15

Slide 16

Slide 16 text

i18n対応をチェックする魔法の文字列 表ポあA鷗ŒéB逍Üߪąñ丂㐀 16

Slide 17

Slide 17 text

toLowerCase() でバイト長が変わる文字 Ⱥ(U+023A)→ UTF-8で2バイト toLowerCase() すると ⱥ(U+2C65)→ UTF-8で3バイト 大文字から小文字への変換で バイト長が増える バッファオーバーフローを引き起こしやすい 17

Slide 18

Slide 18 text

面白いが多分壊さない チャットUIとかだと「顔文字が入力できない」がクリティカルになるかもね ヽ༼ຈل͜ຈ༽ノ ヽ༼ຈل͜ຈ༽ノ (。◕ ∀ ◕。) `ィ(´∀`∩ __ロ(,_,*) ・( ̄∀ ̄)・:*: ゚・✿ヾ╲(。◕ ‿◕。)╱✿・゚ ,。・:*:・゜’( ☻ ω ☻ )。・:*:・゜’ (╯°□°)╯︵ ┻━┻) (ノಥ益ಥ)ノ ┻━┻ ┬─┬ノ( º _ ºノ) ( ͡ ° ͜ ʖ ͡ °) ¯\_(ツ)_/¯ 18

Slide 19

Slide 19 text

面白いが多分壊さない Zalgo Text (Unicode結合文字で作った怖い文字列) 見た目が面白いが意外とあんまり壊れない Ṱ̺̺̕ o͞ ̷i̲̬͇̪͙ n̝̗͕ v̟̜̘̦͟ o̶̙̰̠kè͚̮̺̪̹̱̤ ̖t̝͕̳̣̻̪͞ h̼͓̲̦̳̘̲ e͇̣̰̦̬͎ ̢̼̻̱̘ h͚͎͙̜̣̲ͅi̦̲̣̰̤ v̻͍ e̺̭̳̪̰ -m̢iͅn̖̺̞̲̯̰ d̵̼̟͙̩̼̘̳ ̞̥̱̳̭ r̛̗̘e͙p͠ r̼̞̻̭̗ e̺̠̣͟ s ̘ ͇ ̳ ͍ ̝ ͉ e͉̥̯̞̲͚̬͜ ǹ̬͎͎̟̖͇̤ t͍̬̤͓̼̭͘ͅi̪̱n͠ g̴͉ ͏͉ͅc̬̟h͡ a̫̻̯͘o̫̟̖͍̙̝͉ s̗̦̲.̨̹͈̣ ̡͓̞ͅ I̗̘̦͝ n ͇ ͇ ͙ v̮̫ok̲̫̙͈ i̖͙̭̹̠̞ n̡̻̮̣̺ g ̲ ͈ ͙ ̭ ͙ ̬ ͎ ̰t͔̦ h̞̲e̢̤ ͍̬̲͖ f̴̘͕̣ è͖ẹ̥̩l ͖ ͔ ͚ i͓͚̦͠ n͖͍̗͓̳̮ g͍ ̨o͚̪͡ f̘̣̬ ̖̘͖̟͙̮ c҉͔̫͖͓͇͖ͅ h̵̤̣͚͔ á̗̼͕ͅo̼̣̥s̱͈̺̖̦̻͢ .̛̖̞̠̫̰ ̗̺͖̹̯͓ Ṯ ̤ ͍ ̥ ͇ ͈ h̲́e͏͓̼̗̙̼̣͔ ͇̜̱̠͓͍ͅN͕͠ e̗̱z̘̝̜̺͙ p̤̺̹͍̯͚ e̠̻̠͜ r̨̤͍̺̖͔̖̖ d̠̟̭̬̝͟ i̦͖̩͓͔̤ a̠̗̬͉̙ n͚͜ ̻̞̰͚ͅh̵͉ i̳̞v̢͇ ḙ͎͟ -҉̭̩̼͔ m̤̭̫i͕͇̝̦ n̗͙ ḍ̟ ̯̲͕͞ ǫ̟̯̰̲͙̻̝ f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ ḥ͚a̮͎̟̙͜ ơ̩̹͎ s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜ a͖̰͙̬͡ l̲̫̳͍̩ g̡̟̼̱͚̞̬ͅo̗͜ .̟ ̦ H̬̤̗̤͝ e͜ ̜̥̝̻͍̟́w̕ h̖̯͓ o̝͙̖͎̱̮ ҉̺̙̞̟͈ W̷̼̭a̺̪͍ į͈͕̭͙̯̜ t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙ i̹͓̳̳̮͎̫̕ n͟ d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢ h͏͓̮̻ e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣ l̴͔̰̤̟͔ ḽ̫.͕ Z̮̞̠͙͔ͅḀ̗̞͈̻̗ Ḷ͙͎̯̹̞͓ G̻O̭̗̮ 19

Slide 20

Slide 20 text

PDFやOCRからのコピペはフォームを壊すことがある https://x.com/eta_nouru1/status/2030947927691301104 20

Slide 21

Slide 21 text

開発者ツールで壊す 〈Known-Unknowns〉 21

Slide 22

Slide 22 text

Chrome Devtools F12 を押すと出てくるやつですね ネットワークスロットリング — 低速回線のシミュレーション リクエストのブロック — 特定API/リソースの読み込み停止 レスポンスの改ざん — 500エラー、空配列、不正なJSON ストレージの操作 — Cookie/LocalStorageの削除・改ざん Consoleからの操作 — DOM操作、hidden値書き換え、API直叩き などなど 22

Slide 23

Slide 23 text

レスポンスをブロックしてみよう 23

Slide 24

Slide 24 text

レスポンスが失敗したのにローディングしっぱなし 24

Slide 25

Slide 25 text

例えばこんな不具合を再現させられる 静かな失敗 — エラーなのにユーザーに通知されない リトライのハンドリング — 失敗したリクエストがリトライされデータが重複 機密情報の露出 — 認証バイパス — トークン無効でもAPIが応答 サーバーサイドのバリデーション不備 — フロントエンドのバリデーションが壊れ ていると不正データが通ってしまう ブラウザはとてつもなく優秀なテストベッド、活用していこう 25

Slide 26

Slide 26 text

余談: URLの最後に .json と付けると面白い Ruby on Railsなどのリソースには 26

Slide 27

Slide 27 text

ミューテーションテスト 〈Known-Knownsの検証〉 コードを壊した状態で自動テストを回して、いくつキャッチできるかを調べる # ミュータントの例 if (x > 0) → if (x >= 0) return result → return null 27

Slide 28

Slide 28 text

https://codezine.jp/article/detail/10066 28

Slide 29

Slide 29 text

29

Slide 30

Slide 30 text

ミューテーションテストツール Stryker (JS/TS C# Scala) PITest (Java) mutmut (Python) 言語によってあったりなかったりする 今ならバイブコーディングで自言語のやつを作ったりしてもいいかもね 30

Slide 31

Slide 31 text

データを壊す 〈Known-Unknowns〉 データは、あらゆるアプリケーションにおいて比類ない重要性を持っており、絶 え間ない努力によってデータの完全性が保たれていないと、アプリケーションに 対する顧客の信頼はすぐに悪化してしまい、ビジネスはそれによる信頼低下の影 響を受けることになります。 フルスタックテスティング 第5章 データテスト 31

Slide 32

Slide 32 text

並列処理・競合状態で壊す 更新の消失: 2つのトランザクションが同じ行をread→modify→writeする間に、片 方の書き込みがもう片方に上書きされる 中途半端な読み取り: 販売可能フラグはONだが数量は0のまま(2テーブル間の更 新タイミング差) 共有リソースのミスマッチ: 残り1つの商品を2人が同時購入 → 商品はAさんに、請 求書はBさんに 32

Slide 33

Slide 33 text

壊れたデータで壊す 5年前のデータを入れてみる 更新処理で「何も変えてないのにバリデーションエラー」 重複データで壊す DBの制約で保証されていない重複データはなにかの弾みで出来ることがある 33

Slide 34

Slide 34 text

大量のデータで壊す 一つのGROUP BYをめちゃくちゃ増やしたらインデックスが効かなくなった カーディナリティ(データがどれだけ分散しているか)が低い 巨大なJSONが入ったレコード フロントエンドの描画にめちゃくちゃ時間がかかるかも データスキュー(特定カテゴリにデータが偏る) バッチ処理で特定パーティションだけ極端に遅くなる クエリで扱う件数を増やす 少ない件数ではスロークエリに気づかないことがある 34

Slide 35

Slide 35 text

余談: 食べチョクの例: 本番に近いデータでテストする ステージング環境には、本番と同等のデータが入っています。 リリース当初は、 ステージング環境と本番環境のデータは同期しておらず、テスト用のダミーデー タで動作確認を行っていました。 しかしダミーデータでの確認だと、 ダミーばかりが並んだサイトと本番環境では見た目や印象が違っていて、UI が最適なのか、操作しやすいのか、性能は問題ないか等の検証がしにくい 本番環境でしか再現しない、データに依存したバグに気がつかない恐れがあ る という問題がありました。ステージングで動いたのに本番デプロイしたらエラー が発生した というリスクもできるかぎり下げたいものです。 そのため本番環境の データをステージングに同期し、テストに利用することにしました。 https://tech.tabechoku.com/entry/2018/11/29/113244 35

Slide 36

Slide 36 text

壊れたデータを見つける dbt tests — NOT NULL、ユニーク、リレーション整合性をYAMLで定義 Great Expectations — 実データに統計的なバリデーションをかける Soda — データ品質の継続監視・アラート 36

Slide 37

Slide 37 text

フォールト・インジェクション 〈Known-Unknowns → Unknown- Unknowns〉 システムに意図的に障害を注入して影響範囲を調べる 37

Slide 38

Slide 38 text

Toxiproxy アプリとDB/APIの間にプロキシを挟んで障害を注入 遅延(latency) — 「たまに遅い」を再現。2秒遅延でUIはどうなる? 接続切断(timeout) — リクエスト途中で切断。書き込みの途中だったら? パケットロス(limit_data) — レスポンスが途中で切れる テストコードから動的にON/OFFできるので自動テストにも組み込める 38

Slide 39

Slide 39 text

クラウド環境での障害注入 AWS Fault Injection Service (FIS) — EC2停止、CPU/メモリストレス、ネットワー ク遮断 Azure Chaos Studio — Azureリソースへの障害注入 Gremlin — クラウド非依存の障害注入プラットフォーム 39

Slide 40

Slide 40 text

カオスエンジニアリング カオスエンジニアリングは分散シス テムに対する実験における規律で、 本番環境における不安定な状況に耐 えるシステムの能力に、自信を築き 上げるためのもの 40

Slide 41

Slide 41 text

Chaos Monkey KubernetesのPodをランダムに落とす 本番環境でやる(本番環境でしか起こり得ない問題を見つける) 夜中の3時に叩き起こされる代わりに、業務時間中に突然落ちる 復旧の余裕もあるし、対策も考えられる 41

Slide 42

Slide 42 text

余談: カオスエンジニアリングは実験であり文化 システムは本番で突然壊れるもの システム障害は複雑で不確実なもの これらを「コードとして組み込む」ことで文化にする 継続的に実験を重ねる 42

Slide 43

Slide 43 text

番外編: 壊れてるかもしれないがリリースしてみよう テストで十分不確実性を取り除けない場合は、割り切って実世界に壊してもらう ただし実害を許容範囲に収められるようにコントロールする 43

Slide 44

Slide 44 text

プログレッシブデリバリーの手段 手段 概要 フィーチャーフラグ コードはデプロイ、機能は段階的に有効化 カナリアリリース まず1%に配信、監視しながら拡大 Blue-Greenデプロイ 2面用意して切り替え デプロイとリリースを分けて考える リリースにおける障害がどこまで許容しうるか考える すぐ切り戻す 44

Slide 45

Slide 45 text

まとめ 壊すのは QA・テスターの本懐 壊すのは知られていることを増やす 実験 壊れるのはコントロールできないが、壊すのはコントロールできる 壊して調べて改善していきましょう 45

Slide 46

Slide 46 text

Enjoy Cracking! 46