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
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
83
懺悔-テストを何一つ書いていませんでした-
yoshinagaiwnl
0
160
Other Decks in Technology
See All in Technology
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
330
SONiCの統計情報を取得したい
sonic
0
230
2026 TECHFRESH 畢業分享會 - 開發日常大解密!從領域驅動到企業級上線
line_developers_tw
PRO
0
1.3k
OTel × Datadog で 「AI活用」を計測し、改善に繋げる
shihochan
1
420
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
1
2.5k
白金鉱業Meetup_Vol.24_「AIエージェントは分けるほど良い」は本当か? / Is it true that “the more you divide AI agents, the better”?
brainpadpr
1
410
手塩にかけりゃいいってもんじゃない
ming_ayami
0
610
AIチャット検索改善の3週間
kworkdev
PRO
2
140
SONiCのLinuxベースを活かしたZabbix監視
sonic
0
230
GitHub Copilot 最新アップデート – 「一歩先」の実践活用術
moulongzhang
5
1.5k
2026TECHFRESH畢業分享會 - Lightning Talk - E起 See See : 電商推薦讀心術? 數據說了算
line_developers_tw
PRO
0
1.3k
2026年6月23日 Syncable Tech + Start Python Club にて
hamukazu
0
140
Featured
See All Featured
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
170
Practical Orchestrator
shlominoach
191
11k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
390
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Mind Mapping
helmedeiros
PRO
1
250
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
340
Building Adaptive Systems
keathley
44
3.1k
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 含めて若手多めです!