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
460
CIを整備してメンテナンスを生成AIに任せる
hazumirr
0
1.5k
病院の情報フローを理解して、 予約〜会計の見え方が変わった話
hazumirr
1
2k
Rubyのコード削除したい時 僕がやること
hazumirr
0
300
オンラインテストしようと思った その日に開始できる環境を目指して
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
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
180
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
530
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
2
300
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
190
Heart of Swift Concurrency
koher
0
950
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
3
370
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
740
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
170
Jetpack Compose メカニズム
skydoves
0
460
SREの越境 / SRE Collaboration
y0hgi
2
270
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
1
7.2k
Featured
See All Featured
Paper Plane
katiecoart
PRO
4
53k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
880
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
240
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Facilitating Awesome Meetings
lara
57
7.1k
Claude Code のすすめ
schroneko
67
230k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
710
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
820
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
A Soul's Torment
seathinner
8
3.6k
Odyssey Design
rkendrick25
PRO
2
810
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.