Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
スタートアップだからこそ考えるフロントエンドのテスト戦略
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Ibuki Yoshinaga
March 21, 2023
Technology
1.3k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
スタートアップだからこそ考えるフロントエンドのテスト戦略
2023-03-21-saitama.js
Ibuki Yoshinaga
March 21, 2023
More Decks by Ibuki Yoshinaga
See All by Ibuki Yoshinaga
テーブル全部消しちゃった笑 -ヒヤリハットから学ぶ当事者のメンタルと鎮火方法-
yoshinagaiwnl
0
87
懺悔-テストを何一つ書いていませんでした-
yoshinagaiwnl
0
170
Other Decks in Technology
See All in Technology
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
190
『三匹の子ぶた』から学ぶネットワークセキュリティの昔と今 / Network Security: Then and Now Through the Lens of The Three Little Pigs
nttcom
1
1.7k
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
640
ブラウザ研修 2026
recruitengineers
PRO
4
740
【CEDEC2026】ゲームシナリオライターを支援するAIツール開発の実践 ― 設計とプロンプトの工夫 ―
cygames
PRO
1
770
変化の早いClaude Codeを 書籍に落とし込む
oikon48
7
1.3k
つくって納得、つかって実感! 大規模言語モデルことはじめ ver2.0
recruitengineers
PRO
3
1.1k
社内の7割が使うデータ基盤を、 データチーム2人で回すためにやったこと
koh_yoshi
4
1k
【Google Cloud Next Tokyo'26】Gemini Enterprise と Oracle AI Database で実現する、業務データ活用を実現する AI エージェント実装
shisyu_gaku
0
230
【CEDEC2026】『Relink』を拡張せよ - 『GRANBLUE FANTASY: Relink - Endless Ragnarok』の開発速度と品質を守るCI運用
cygames
PRO
0
140
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
5
1.3k
SnowflakeCoCoでデータエンジニアリング!
foursue
0
180
Featured
See All Featured
Claude Code のすすめ
schroneko
67
230k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
The Curious Case for Waylosing
cassininazir
1
450
How to Ace a Technical Interview
jacobian
281
24k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Into the Great Unknown - MozCon
thekraken
41
2.7k
The Language of Interfaces
destraynor
162
27k
GraphQLとの向き合い方2022年版
quramy
50
15k
Believing is Seeing
oripsolob
1
180
How to build a perfect <img>
jonoalderson
1
5.9k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Transcript
スタートアップだからこそ考える フロントエンドのテスト戦略 2023/3/21 Saitama.js vol.5
自己紹介 ・名前: Ibuki Yoshinaga ・誕生日: 2001/02/24 ・Twitter: @__GGEasy ・埼玉要素: 埼玉県飯能市で爆誕。一時静岡で育つも、小学生
の時埼玉に戻ってきた。 ・その他: 昨日沖縄旅行から帰ってきました。
所属している会社 Misson e スポーツで 一人ひとりの可能性が ひろがる教育機会を e スポーツとは 「e スポーツ」とは、「エレクトロニック・スポーツ(Electronic
Sports )」の略で、ビデオゲームを使った対戦をスポーツ競技として 捉える際の名称を指す。 つい数年前まではオタクの趣味または「ゲームは悪」と捉えられてい たが、現在では海外での人気のみならず、日本においてもさいたまス ーパーアリーナを埋め尽くすほどの観客動員数を誇り始めている。 ゲシピ株式会社
最近開発しているサービス 主力サービスをさらに発展させるため、9 月より1 人目の正社員エンジニアとして僕がジョインしました。 実は弊社に関わり始めたのは高校生の頃なので、超待望のリリースって感じです。 概要 主に小学生~ 大人向けの英会話レッスンを提供するtoC サービ ス
特徴 ネイティブスピーカーの講師陣とFortnite やマイクラを遊びな がら、英会話を教えてもらえる。 ゲーム内でのやり取りは基本全て英語、ゲームを用いたカリ キュラムが組まれているため子供達が自主的に取り組みやす く英語に対する苦手意識も克服できる。 ニュース 最近リスキリングe スポーツ英会話がリリース🎉大人向けの 英会話レッスンがゲームを通した会話で学べます。 e スポーツ英会話
開発初期に採用した主な技術 ・Next.js + TypeScript ・react-hook-form ・Recoil フロントエンド ・Nest.js + TypeScript
・Prisma ・OpenApi ・PostgreSQL バックエンド ・Heroku ・Docker インフラ ・GitHub Actions CI/CD
現在の開発体制 会社全体で正社員 10 人未満のスタートアップ 現在の開発組織 (2022/09~) CTO( 設計 + 他プロダクト
+ マネージメント) ワイ( 設計 + 開発) フルタイム 業務委託( 設計 + 開発) 業務委託( 設計 + 開発) 業務委託( デザイナー) その他 ・全体的に若い組織、CTO 以外の開発者は全員20 代 ・全プロダクトでTS を採用している ・新規開発が多いフェーズ ・正社員で開発に関わるエンジニアは自分だけ ・よほど大きなものでない限りはフロントエンド・バックエンドは一人でやる ・テストを書いた経験は全員少ない 開発組織の特徴
クオリティの担保は誰がする? 恐怖がつきまとう開発体験は、とても心理的に厳しい 長期的に見た結果、テストがないことが何よりもの負債になることは目に見えているし、組織のスケールもしにくい とはいえ... ・現状テストの知見は0 ・テストに工数を取られて、開発速度が落ちたら元も子もない ・クオリティをCTO に任せきりの開発体制で良いのか? ・プロダクト数や、コード量が増えることに対する恐怖心、オフショア委託も始めました ・事業の成長に伴う、デグレ時の被害の増大
・普通に動作確認が大変 芽生えた危機感 レベル1: バグの発生にすぐ気がつける レベル2: atom レベルの単体テストが充実する レベル3: API のモック、atom 要素以外の単体・結合テストが充実する 優先度
Testing Trophy によれば 上にいけば行くほど実装コストが高くなるが信頼性が上がる。体積 が大きいほど重点が置かれている。 各項目の説明 実際の環境でアプリケーションを動かすテスト End to End
関数(hooks) やコンポーネントを組み合わせた時のテスト ここを一番厚く書くことが推奨される Integration atoms レベルのコンポーネントや、関数(hooks) 単体のテスト Unit 静的テスト、lint とか Static
まずはテストピラミッドを目指す ・どのテストに力を入れるかをピラミッド型で示している ・上に行けば行くほどテストが少なく、費用対効果が低い ・結合テストを重視するトロフィとは違い、高速で回せる Unit テスト多め テストピラミッドとは ・最初は簡単なものから始めたい ・unit テストは範囲が限られているので調査・実装コストが
とても軽く素振りしやすい 何故 Unit テストの配分を増やしたのか
結果的に導入したもの 静的な物(eslint/prettier) に関しては最初に導入してました。 strictNullChecks は有名ですが、後からtrue にすると大量のエラーと戦うハメになります。 PR 立ち上げ時に動作 ・eslint 静的
・React Testing Library 単体 / 結合 STG デプロイ時に動作 ・Cypress ・Storybook ・Chromatic( 消した) UI ・Sentry 常時
各種ライブラリの使い分け
React Testing Library ・コンポーネント・カスタムフックのテスト ・Storybook との連携 ・1hooks 、component 毎にテストが作られる ・PR
内のCI で怒られたい 期待した役割 ・ロジックに関わる部分は基本的にRTL に集約 ・期待通りの結果が表示・返却されているかの確認だけで、スタイルの崩れなどはここでは見ない ・ビジネスロジックに関わらなそうな部分のテストコード作成は、たまにChatGPT に投げている 現状の運用方法 ・結合テストの充実 ・MSW を入れたい( 現在はAPI を使う場合型と同じ形の値をmock してしまっている) 今後の期待
実装例 1 口座の情報をprops から受け取って、それが整形されて返ってくるhooks のテスト describe(__dirname, () => { it('should
return the correct text for a domestic bank transfer', async () => { const bankAccount: any = { transfer_method: 'domestic', bank_name: 'Test Bank', branch_name: 'Test Branch', account_type: 'checking', account_number: '123456789', account_holder_name: 'Test User', }; const { result } = renderHook(() => useRemittanceText({ bankAccount })); await waitFor(() => { expect(result.current.get).toEqual({ section1: 'Test Bank Test Branch', section2: ' 当座 123456789 Test User', }); }); }); });
実装例 2 コンポーネントのテスト with Storybook 余談: 最近play という関数を知った。フォームコンポーネントなどの結合テストを書く場合、RTL 主導にするよりもStorybook 内でテ
ストを書いて、それをRTL で結果を見て判断する方法に変えていくのもありだなと思った。 const { $Example } = composeStories(stories); describe(__dirname, () => { test(`${CLASS_SCHEDULE_STATUS.COMPLETED} の時${CLASS_SCHEDULE_STATUS_TEXT.completed} が表示される`, () => { const { getByText } = render( $Example lessonStatus={CLASS_SCHEDULE_STATUS.COMPLETED} > ); expect(getByText(CLASS_SCHEDULE_STATUS_TEXT.completed)).toBeInTheDocument(); }); test(`${CLASS_SCHEDULE_STATUS.IMPLEMENTATION} の時${CLASS_SCHEDULE_STATUS_TEXT.implementation} が表示される`, () => { const { getByText } = render( $Example lessonStatus={CLASS_SCHEDULE_STATUS.IMPLEMENTATION} > ); expect( getByText(CLASS_SCHEDULE_STATUS_TEXT.implementation) ).toBeInTheDocument(); }); });
Storybook ・ Chromatic ・Storybook 駆動開発がしたい( 願望) ・コンポーネント毎のカタログが欲しい ・1 コンポーネントにつき1 つのstory
ファイルが作られる ・スナップショットテストやビジュアルリグレッションテスト 期待した役割 ・atom レベルのコンポーネントは必ずstory ファイルを作成する ・スタイル崩れなどはここで検知する 現状の運用方法 ・Chromatic に代わる何かを導入する( 後述) ・play などを使って、結合テストをより充実させる 今後の期待
実装例 アイコンを表示するコンポーネント type Component = typeof BaseIcon; type Meta =
ComponentMeta<Component>; export default { title: 'frontend/src/components/common/FixSb/BaseIcon', component: BaseIcon, argTypes: { icon: { options: Object.keys(ICONS), control: { type: 'radio' }, defaultValue: 'lined_reward', }, }, } as Meta; const Template: Story<BaseIconProps> = (args) => <BaseIcon {...args} >; export const $Example = Template.bind({}); $Example.args = { icon: 'lined_reward', };
Sentry Cypress ・バグった状態に気が付かないは避けたい ・バグを防ぐと言うより、バグにすぐ気がつく環境整備 期待した役割 ・効果を明確に感じるまではとりあえず無料アカウントで運用( 人が増えたら有料に移行) ・朝確認しつつ、ヤバそうな通知が飛んできたら都度確認 現状の運用方法 ・最初期に作った部分が正常に動いているかを確かめたい
・異常系よりも正常系を優先( そもそも壊れていないかを知りたかった) 期待した役割 ・STG デプロイ後に動作 ・デプロイ時にこけていた場合は怒られるので、該当箇所を確認して修正する 現状の運用方法
採用を見送った・消した技術 便利な技術には予算をかけるスタンスは維持しつつ、使われずに腐る可能性も考慮した上で選定することが大事 ・スケールした場合のお値段が高い、予算をかけずにミニマムに進めたい ・現状Admin ページとコーチページしかリリースしていないため、最悪表示が壊れているだけならごめんなさいでギリ許される ( 許されない) ・無料枠を使い切らずにどうにか回せるなら採用するかも 結果 :
Storycap + reg-suit あたりを検討しています Chromatic ・物によるがちょっと高い ・ノーコードとはいえそのツールのお作法を覚えることに、今コストをかけたくない ・契約して腐りましたは絶対に嫌だ 結果 : Cypress を採用 ノーコード系の E2E テストツール
テストを導入してどうだったか・まとめ 現在はノルマ・目標などは設けておらず、atom レベルのロジックを持ったコンポーネントにはStorybook 、新しく発行したカスタム フックにはテストを書いてねくらいのゆるさにしている。 現在弊社ではある一定の期間でリファクタウィークを設けて、そこでテストを含めた負債の解消をしようとしています。 すぐに全てのテストを作れはしない ( モチベ的にも )
ので、継続して対応することが必要。 ・デグレによる不安が少し解消された ・古くからある機能や壊れやすい部分をE2E で担保することで、該当機能を充実させるまでの時間稼ぎができている ・エラーが起こった時に、ある程度規模感を検知・場合によってはrevert できる ・知見が溜まってない頃に書いたコードは普通に汚いので、ある意味強制的なリファクタリングが発生する ・現状一人で開発している僕にとって、ある一定の心理的安全性が保たれる よかった点 ・テストの粒度を決めきれていない、網羅しきれていない ・知見・時間等の理由で明確なシナリオを用意できていないため、正常系が主体になってしまっている ・一時的だがChromatic を消してしまった今、明確にStorybook に登録するメリットを感じきれていない ・デザイナーを正社員として雇っていないこともあり、動機的なStorybook 駆動開発をするにはまだ時間がかかりそう 懸念点・もっと頑張る
ご清聴ありがとうございました! 正社員や副業も募集してます! CTO 含めて若手多めです!