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
Hazumi Ichijo
September 28, 2023
Programming
2.2k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
テーブル駆動テストと状態
https://golangtokyo.connpass.com/event/293636/
Hazumi Ichijo
September 28, 2023
More Decks by Hazumi Ichijo
See All by Hazumi Ichijo
RailsとRidgepoleの マイグレを120倍早くする
hazumirr
0
400
CIを整備してメンテナンスを生成AIに任せる
hazumirr
0
1.5k
病院の情報フローを理解して、 予約〜会計の見え方が変わった話
hazumirr
1
1.9k
Rubyのコード削除したい時 僕がやること
hazumirr
0
280
オンラインテストしようと思った その日に開始できる環境を目指して
hazumirr
0
1.1k
推薦によるプロダクト改善とマイクロサービスが噛み合った話
hazumirr
2
4.7k
ChatGPTで僕が知っていることまとめ
hazumirr
3
3.1k
プロダクトチームとどう 協業し分析環境を改善するか
hazumirr
2
1.6k
bqv速習会
hazumirr
6
7.2k
Other Decks in Programming
See All in Programming
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
1.6k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
190
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
200
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
3k
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
140
Oxcを導入して開発体験が向上した話
yug1224
4
290
関係性から理解する"同一性"の型用語たち
pvcresin
2
640
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
140
AIとRubyの静的型付け
ukin0k0
0
540
AI時代のUIはどこへ行く?その2!
yusukebe
19
6.7k
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.3k
Featured
See All Featured
Writing Fast Ruby
sferik
630
63k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Into the Great Unknown - MozCon
thekraken
41
2.5k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
Leo the Paperboy
mayatellez
7
1.8k
How to build a perfect <img>
jonoalderson
1
5.6k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.3k
Darren the Foodie - Storyboard
khoart
PRO
3
3.4k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
1.6k
Become a Pro
speakerdeck
PRO
31
6k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
220
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
200
Transcript
© 2023 Wantedly, Inc. テーブル駆動テストと状態 golang.tokyo #33 Sep. 28 2023
- Hazumi Ichijo
自己紹介 © 2023 Wantedly, Inc. 一條 端澄 @hazumirr/@rerost 略歴: 2018~
: ウォンテッドリー株式会社 • 2018/04~ 推薦基盤チーム エンジニア • 2021/09~ 推薦チーム プロジェクトマネージャー • 2022/06~ 推薦チーム リーダー 趣味: テトリス・旅行
テーブル駆動テストで悩ましい点 © 2023 Wantedly, Inc. testCase := []struct{ in string
out int }{ { in: "engineer", out: 2, }, } 単語を受け取りその検索結果の件数を返す関数のテ ストの一部
テーブル駆動テストで悩ましい点 © 2023 Wantedly, Inc. testCase := []struct{ in string
out int }{ { in: "engineer", out: 2, }, } 単語を受け取りその検索結果の件数を返す関数のテ ストの一部 テストケースごとにデータを用意しようとすると...
テーブル駆動テストで悩ましい点 © 2023 Wantedly, Inc. testCase := []struct{ in string
before func(sql.DB) out int }{ { in: "engineer", before: func(db sql.DB) error { // ここでテストデータを DBに準備 }, out: 2, }, } よくあるケースとしてはこんな実装 データを生成するのもテストケースごと に管理する
テーブル駆動テストで悩ましい点 テストコードが負債になる • すでにあるテストをどう修正して良いかわからない • かなり似ているが微妙に異なるものが多い • … © 2023
Wantedly, Inc.
テーブル駆動テストで悩ましい点 テストコードが負債になる • すでにあるテストをどう修正して良いかわからない • かなり似ているが微妙に異なるものが多い • … テストケースの記述では「どう作るか」の関心を排除し、「何が状 態として欲しいか」だけに絞りたい
© 2023 Wantedly, Inc.
解決策 © 2023 Wantedly, Inc. testCase := []struct{ in string
state State out int }{ { in: "engineer", state: State{ users: []User{ { OccupationType: "engineer", }, テストケースはここだけ読めばやりたいこと が見えやすくなる 更に、データベースへの接続などのインター フェース変更が容易に
Tips © 2023 Wantedly, Inc. // 文字列を受け取ってUUIDに変換する func GenerateID(id string)
string { return uuid.NewSHA1(uuid.NameSpaceDNS, []byte(id)).String() } func TestSearchCount(t *testing.T) { ... state: State{... { Uid: generateId("User1"), FriendIDs: []string{generateId("User2")}, }, { Uid: generateId("User2"), FriendIDs: []string{generateId("User1")}, … 依存関係を管理したくなった時
Tips © 2023 Wantedly, Inc. デフォルト値を作りたくなった時 // デフォルト値をpropで受け取ったnon null値で上書きしたものを返す関数 func
Merge[T any](t *testing.T, defaultValue, prop T) T { t.Helper() res := new(T) if err := copier.CopyWithOption(&res, defaultValue, copier.Option{...}); err != nil { t.Errorf("Failed to copy default value. err: %v", err) } if err := copier.CopyWithOption(&res, prop, copier.Option{..}); err != nil { t.Errorf("Failed to copy prop value. err: %v", err) } return *res }
まとめ 1. テストケースには「何が状態として欲しいか」のみ記述 2. (自分の観測範囲では)うまく行っている © 2023 Wantedly, Inc.
© 2023 Wantedly, Inc.