Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
テーブル駆動テストと状態
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
450
CIを整備してメンテナンスを生成AIに任せる
hazumirr
0
1.5k
病院の情報フローを理解して、 予約〜会計の見え方が変わった話
hazumirr
1
2k
Rubyのコード削除したい時 僕がやること
hazumirr
0
290
オンラインテストしようと思った その日に開始できる環境を目指して
hazumirr
0
1.1k
推薦によるプロダクト改善とマイクロサービスが噛み合った話
hazumirr
2
4.8k
ChatGPTで僕が知っていることまとめ
hazumirr
3
3.1k
プロダクトチームとどう 協業し分析環境を改善するか
hazumirr
2
1.7k
bqv速習会
hazumirr
6
7.3k
Other Decks in Programming
See All in Programming
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
120
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.3k
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
新卒PdEのリアル
ryu1013
1
480
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
150
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
490
高専キャリア LT 発表内容
crysta1221
6
5.6k
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
280
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
470
業務時間外もAIに働いてもらう話
colorful12
3
10k
Security issues being discussed on Web Platforms
petamoriken
0
650
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
Amusing Abliteration
ianozsvald
1
290
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
470
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
690
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.2k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Crafting Experiences
bethany
1
320
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
520
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
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.