安心して変更できるWebフロントエンドの作り方
by
Hiroyuki ANAI
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
安心して変更できる Webフロントエンドの作り方 フロントエンドカンファレンス福岡2026 穴井宏幸 @pirosikick
Slide 2
Slide 2 text
自己紹介 穴井宏幸(@pirosikick) 株式会社LayerX ソフトウェアエンジニア バクラク勤怠の開発をメインに、WebフロントエンドのEnablingを少々 経歴 2009 ~ 2018年 ヤフー株式会社 2016~2018年? JavaScript黒帯 2018 ~ 2020年 サイボウズ株式会社 フロントエンドエキスパート 2020 ~ 2025年 スタートアップCTO 2025年8月 株式会社LayerX 執筆 © LayerX Inc. 2018年「React入門」(翔泳社、共著) Web + DB Press 「どんとこい!フロントエンド開発」(連載、共著)、 「フロントエンド脱レガシー」(特集記事、共著) 2
Slide 3
Slide 3 text
今日の話 Webフロントエンド開発歴1N年のSWEが考える 「安心して変更できるWebフロントエンドの作り方」 実践編 LayerXで実践して学んだこと AI時代、何が変わったか? © LayerX Inc. 3
Slide 4
Slide 4 text
本編に入る前に用語の整理 本編に登場する「Integration Test」「Unit Test」は、Testing Trophyの定義です Unit Test アプリケーション内で最も小さく分離されたコード単位(関数、純粋なロジック、ユーティリティなど)が、 単体で正しく動作するかを評価するテスト Integration Test 複数のユニットやモジュール(UIコンポーネント、状態管理 ... etc)が 組み合わさって機能する一連の流れを評価するテスト 個人的には、Storybookの play 関数をよく使うが、 vitestのbrowser modeやtesting-library + jsdom/happy-domなどを使ったテストのイメージ (ヘッドレスでブラウザを使うテストは、Integration Testなのか、という話もあるが、そこは許して) © LayerX Inc. 4
Slide 5
Slide 5 text
Testing Trophyの詳しい情報は、本家の記事をご覧ください The Testing Trophy and Testing Classifications(Kent C. Dodds) https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications Testing Trophyの図(穴井手書き) © LayerX Inc. 5
Slide 6
Slide 6 text
ここから本編
Slide 7
Slide 7 text
私の考える 「安心して変更できるWebフロントエンドの作り方」 全ての振る舞いをIntegration Testで保護すればOK © LayerX Inc. 7
Slide 8
Slide 8 text
なぜ? Why 1. 自動テストがないと安心して変更できない 「自動テストがない」は変更できない定番の理由 「テストが全く無い」みたいな状態はほぼ見なくなった 「Webサイト」から「Webアプリケーション」が主流になり、テストを書く重要性が高まった テストのツールチェーンの成熟。自動テストのハードルが下がった。 書籍等、啓蒙やノウハウの普及 ... etc 最近は「何を選ぶか」「どれくらい書くのか」「どのタイミングで書くのか」などが話の 中心なのかも © LayerX Inc. 8
Slide 9
Slide 9 text
なぜ? Why 2. なるべく上位に自動テストを追加する方が効果が高い 上位 = 依存側、下位 = 非依存側 AがBに依存している場合、Aが上位 ※注意: この定義が一般的かは分からない 効果が高い = 安心して変更できる範囲が広い © LayerX Inc. 9
Slide 10
Slide 10 text
Why 2. なるべく上位に自動テストを追加する方が効果が高い 変更の影響は依存側へ AがBに依存 Bに加えた変更は、Aに影響する © LayerX Inc. 10
Slide 11
Slide 11 text
Why 2. なるべく上位に自動テストを追加する方が効果が高い 安心するには、依存側に自動テストがある必要がある Bを安心して変更するには、 A(やAに依存している更に上位のコンポーネント)に自動テストが必要 © LayerX Inc. 11
Slide 12
Slide 12 text
Why 2. なるべく上位に自動テストを追加する方が効果が高い 上位なほど、カバーする範囲が広くなる Unit TestよりIntegration Test、 Integration TestよりE2E Testの方が効果が高い = 安心できる範囲が広い © LayerX Inc. 12
Slide 13
Slide 13 text
Why 2. なるべく上位に自動テストを追加する方が効果が高い ただし、上位なほど、実行コストが高くなる E2E Test >>> Integration Test >> Unit Test 全てをE2E Test or Integration Testに書くと 共通処理(複数から依存されている処理)でテストケースが重複して無駄 Unit Testは、そのようなケース(共通処理)や Validationなどテストパターンが多い場合に書く、くらいでよい気がする © LayerX Inc. 13
Slide 14
Slide 14 text
なぜ? Why 3. テスト自体が生きた仕様書になる 仕様が残ってないと、 意図した挙動なのか、たまたまそうなっているのかわからず、 変更に躊躇してしまう E2E TestやIntegration Testは、ユーザーのユースケースに近い形でテストを書くので、 1つのテストケース=1つの仕様・振る舞いになりやすい テストを読めば、仕様がわかるという状態になる ドキュメントは、実装と距離があるので、乖離が起きやすい © LayerX Inc. 14
Slide 15
Slide 15 text
なぜ? Why 4. E2E Testはコストが高い テストの効果を考えるとIntegration Testより、E2E Testに分がある カバーする範囲が広い 実装に完全非依存、テストケースがほぼユーザーの振る舞いと一致 変更が安全かのフィードバックはすぐ欲しい 作成したPRやpushしたcommitに対して、CIでテストしたい E2E Testは、現実的ではない E2E Testは、実行時間が長い E2E Testは、環境構築コストが高い micro serviceだと、動的な環境構築・データの洗替が無理なケースも © LayerX Inc. 15
Slide 16
Slide 16 text
まとめる 安心して変更できる状態にするには、保護範囲が広い自動テストを増やすべき Webフロントエンドでは、Integration Testが最もコスパがいい Integration Testを書きましょう! © LayerX Inc. 16
Slide 17
Slide 17 text
完 フロカン福岡、ありがとう!
Slide 18
Slide 18 text
とは言えど、現実はどうか? LayerXのバクラク勤怠チームに配属されて1年 当時はIntegration Testはほぼ無く、「やってやるぞ」と鼻息を荒くしていた 1年経過したので、実践できたのか?を振り返る ネタバレですが、主に反省です © LayerX Inc. 18
Slide 19
Slide 19 text
Integration Testの数の推移 バクラク勤怠のIntegration Testの数をカウント ファイル数・ケース数の推移だけ見ると順調に増えてそうに見える プロダクト全体なので、穴井以外も書いてそうでうれしい 時点 2025年8月 2026年9月 © LayerX Inc. ページ数 79 94(+15) Integrataion Test 2ファイル, 11ケース 18ファイル(+16), 94ケース(+83) 19
Slide 20
Slide 20 text
体感: 満足はできていない 本当にIntegration Testがほしいページ = 変更が怖いページでは、 導入が進んでいない 何が実践を阻んだか? © LayerX Inc. 20
Slide 21
Slide 21 text
何が実践を阻んだか? 「早くリリースしなきゃ」という圧 圧に負けて、テストを書かずにマージしてしまった 好きな言葉は「テストを書いた方が速い」なので悔しい! 圧の原因はいくつかある 転職したばかりで早く成果を出したかった AIを使いこなしている同僚のアウトプット量に圧倒され、焦ってしまった 忙しくて余裕が無かった ... etc ※注意: あくまで自発的な焦りです! 組織・上司に圧を掛けられているわけではありません!!! © LayerX Inc. 21
Slide 22
Slide 22 text
何が実践を阻んだか? 「圧」は常にあるもの 大小の問題で、無くなるものではない 「怠惰だったから」で片付けるべきではない 圧があった中で、 Integration Testを書けたページ・書けなかったページの違いは何なのか? © LayerX Inc. 22
Slide 23
Slide 23 text
何が実践を阻んだか? テスト容易性に当てはめて考えてみる ソフトウェアテストのやりやすさを表す特性 7つの特性から構成: 実行円滑性, 観測容易性, 制御容易性 分解容易性, 単純性, 安定性, 理解容易性 Integration Testを書けたページ・書けなかったページで 特性ごとに差異があるのかを考える © LayerX Inc. 23
Slide 24
Slide 24 text
何が実践を阻んだか? 差異がない特性 実行円滑性 = 簡単に実行できるか テストが実行しやすいかはテスト対象に関係ない モノレポ、かつ、同僚が既に整備済みだったので◎ 観測容易性 = テスト対象の状態を簡単に観測できるか 要は、AAAパターンのAssert部分 UIの変化、モックしたAPI等とのやり取りが観測対象 テスト対象によってそこまで変わらない 制御容易性 = テスト対象の動作を簡単に制御できるか 要は、AAAパターンのArrange/Act部分 モックAPI、コンポーネントのprops、clickなどの操作 ... etc テスト対象によってそこまで変わらない © LayerX Inc. 24
Slide 25
Slide 25 text
違いがある特性 単純性 = 実装がシンプルか Integration Testが書けなかったページは、実装が複雑 行数が多い、1ファイルに詰め込みがち GraphQLのQueryがでかい、複数叩いている 分岐が多い、分岐条件の要素が多い コンポーネントのpropsが多い ... etc 理解容易性 = 仕様がシンプルか Integration Testが書けなかったページは、仕様が複雑 歴史が長く、ドメインが詰まりがち UIが複雑で、表示パターンが多い ... etc © LayerX Inc. 25
Slide 26
Slide 26 text
反省 反省1: Integration Testに固執してた リファクタリングは、挙動を変えずに内部構造を整理すること コードをリファクタするには、まずIntegration Testを書かないと〜 → でもコードが複雑で、Integration Testが書けない〜 → デッドロック!何も進まない! © LayerX Inc. 26
Slide 27
Slide 27 text
反省1: Integration Testに固執してた どうすべきだったか? Unit Testで小さく始める? 小さな改善を地道に続ける必要があり、我慢が必要 上司の名言 「東京ドームの改修をするのに、外周の草刈りから始めるようなもの」 改善案があるなら、思い切って先にコードの整理を行う 今はAIで改修ミスは起きづらいし 「挙動が変わっていないこと」は、自動テスト以外の方法でも保証可能 手動でQAを頑張る コードレビューを頑張る © LayerX Inc. 27
Slide 28
Slide 28 text
何が実践を阻んだか? 反省2: ドメイン理解が浅いままタスクを進めていた Integration Testが欲しいページほど、歴史が長く、ドメインロジックが詰まりがち ドメイン理解が浅いと、いいIntegration Testは書けない 正しくAPIをモックできない(不整合があるデータを作る、など) 正しい振る舞いが分からず、テストケースが思い浮かばない ... etc © LayerX Inc. 28
Slide 29
Slide 29 text
反省2: ドメイン理解が浅いままタスクを進めていた どうすべきだったか? 変更箇所だけでなく、周辺のコードが理解できるまで、調べる 時間がかかっても、トータルでは早くなるという意識を強く持つ AI 時代だからこそコードを読もう https://zenn.dev/layerx/articles/6f510abfc3fa72 「自分のパフォーマンスを支えてくれていたのは、プロダクトに対するコンテキストだった」 © LayerX Inc. 29
Slide 30
Slide 30 text
何が実践を阻んだか? 反省3: 「怠惰だったから」で思考停止していた 正しいと分かっているのに圧に負けてしまって実践できない →「なんて怠惰なんだろうか。。。」で思考停止してた 圧があっても、怠惰でも、Integration Testを書ける方法を考えるべき © LayerX Inc. 30
Slide 31
Slide 31 text
どうすべきだったか? テストを書くハードルはいくらでも下げていい 例: UIの観測を楽にする関数の提供 react-select-event のようなUI操作用のヘルパー関数の提供 共通で利用できるモック用データを充実させる 実環境からモック用データを吸い出す仕組みを作る 軽く考えただけでも、アイデアはいっぱい出せるので、実践すればいいだけ © LayerX Inc. 31
Slide 32
Slide 32 text
「安心して変更できるWebフロントエンドの作り方」に付け加えるなら 全ての振る舞いをIntegration Testで保護すればOK ただし、それには前提がある Integration Testが書ける程度に、実装と仕様がシンプルであること(単純性・理解容易性) 書く人がドメインを理解していること Integration Testを書くのが楽な基盤があること(圧に負けにくくする) 前提が崩れているなら、テストより先に前提を直す リファクタ、調査、テスト基盤への投資 「テストが書けない」は怠惰ではなく、コードからのシグナル © LayerX Inc. 32
Slide 33
Slide 33 text
AI時代、何が変わったか
Slide 34
Slide 34 text
現状を知るために調査 どれくらいIntegration Testが書かれているのか テストファイル数の推移 人間が書いたのか、AIが書いたのか 各テストファイルを目視で確認し、気づいたことをメモ © LayerX Inc. 34
Slide 35
Slide 35 text
現状を知るために調査 テストファイル数の推移 時点 2025年8月 2026年1月 2026年4月 2026年9月 © LayerX Inc. .tsx .test.tsx 417 632 694 799 0 8 11 57 play有 .stories.tsx 2 13 14 18 35
Slide 36
Slide 36 text
現状を知るために調査 AIが書いたファイルがどれくらいあるか 種別 .test.tsx play有 .stories.tsx 合計 計 57 18 75 AI(※ 1) 41 8 49 人間(※ 2) 16 10 26 AI比率 71.9% 44.4% 65.3% ※1 コミットやPR本文に「Generated with Claude Code」が含まれるか等で判定 ※2「人間」判定は、コミットログにAIと判定できるマーカーが無かっただけなので、 実際はもっとAI比率が高いはず © LayerX Inc. 36
Slide 37
Slide 37 text
現状を知るために調査 言えそうなこと なんとなく感じてたが、AIによって、自動テストが増えた は数字的にも正しそう 指示をしなくても勝手にUIのテストを書くようになった が、2026年4月以降に急速に増加 AIに「リポジトリ内に特別な指示はあるか?」と聞いたが「無いっぽい」 確実なことは分からないが、モデルに何か変化があったかも? .test.tsx 何も指示しない場合、AIは .test.tsx (testing-library)でテストを書きがち © LayerX Inc. 37
Slide 38
Slide 38 text
現状を知るために調査 テストコードを読んで感じたこと AI、めっちゃモックする 意味がないテストが稀にある 効果の薄いテストが増えた © LayerX Inc. 38
Slide 39
Slide 39 text
テストコードを読んで感じたこと AI、めっちゃモックする 複雑なUIコンポーネント、だいたいモックしてる ex) モーダルコンポーネントをただprops.childrenを返すだけにする ex) リッチなセレクトボックスをただの に置き換える その発想はなかったので感心したが、 同じコードがコピペしたかのように点在しちゃってるのはよくない テスト基盤として提供するのがよさそう テスト用のFakeコンポーネント react-select-event のような複雑なUIコンポーネントをテスト時に操作するヘルパー関数 ... etc © LayerX Inc. 39
Slide 40
Slide 40 text
テストコードを読んで感じたこと AI、めっちゃモックする のsetValue関数をspyしている行儀の悪いケースも 人間だとそこまでしてテストを書かないので、そういう意味ではすごい 実装にかなり依存しており、テストが壊れやすく、テストコードが複雑になりがち 外から観測できる変化で検証できないのか、 Integration Test以外の方法で動作を保証できる設計はないのか、 (ex: ロジックを切り出して、Unit Testを書く) テストの複雑さに見合う効果があるのか ... etc react-hook-form © LayerX Inc. 40
Slide 41
Slide 41 text
テストコードを読んで感じたこと 意味がないテストが稀にある 例: booleanのpropsを追加する変更に、それがtrueの場合のテストケースしか無い 全体で1ケースだったのでめったに起こるわけではないが、 こういうテストコードを書くこともあるよという話 神同僚が作ったレビュー用スキルで、 テストケース不足は炙り出されるようになったので、 今後は起きにくいだろうが、気をつけたい © LayerX Inc. 41
Slide 42
Slide 42 text
テストコードを読んで感じたこと 効果の薄いテストが増えた 小さいコンポーネントに対するテストや、 テストケースが実装に寄りがちで、読んでも仕様が分からないテスト 自分の入れた変更に対する動作確認のための最小限のテスト、という印象 蓋を開けてみたらIntegration TestではなくUnit Testが増えていた 人間が書いたIntegration Test( .stories.tsx )には、ほぼ手を付けてない © LayerX Inc. 42
Slide 43
Slide 43 text
テストコードを読んで感じたこと テストコード、読んでますか? 実装のコードに比べると、真剣に読んでなかった 「どういうテストケースを追加したか」だけを見て安心し、 「それらがどのように実装されているか」まで見れていなかった(自戒) © LayerX Inc. 43
Slide 44
Slide 44 text
テストコードを読んで感じたこと Integration Testのテストケースは人間が考えるべき AIのおかげで、テスト量は大幅に増えた 一方で、AIは、自分の書いたコードや指示されたスコープに対する Unit Testしか書かない(特別に指示しない限りは) 「Integration Testに何を追加すべきか」はまだ人間が考える必要がありそう © LayerX Inc. 44
Slide 45
Slide 45 text
おまけ: CIのコストがかなり増えた話 最近、Coding AgentでGithubのPRの数やプッシュ数が増えた結果、 CIのコスト増が問題になった しかも、Web FEに関するタスクが、コストの上位を占めていた LintやType Checkはより速いツールへの移行を検討(oxlint, oxfmt, tsgoなど) © LayerX Inc. 45
Slide 46
Slide 46 text
おまけ: CIのコストがかなり増えた話 一方で、Testはどうコスト削減するか? Storybookのplay関数推しだったが、 より実行コストの低いツールへの乗り換えが必要? ex) testing-library + happy-dom/jsdomなど、ブラウザを使わない構成 テストケースを厳選する?どうやって? ... etc 答えはまだない お金のことまで考えると FEのテスト戦略はより複雑になるな〜というのが 最近の悩みという話でした © LayerX Inc. 46
Slide 47
Slide 47 text
End