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
Tech Leverages
January 21, 2024
Technology
0
210
技術的負債に立ち向かうために テストを書いてる話
## 技術
テスト、単体テスト、統合テスト、技術的負債、単体テストの考え方/使い方、偶発的な複雑さ、本質的な複雑さ
Tech Leverages
January 21, 2024
Tweet
Share
More Decks by Tech Leverages
See All by Tech Leverages
Biome で Format と Lint のストレスをゼロに
leveragestech
0
9
10倍スケールを見越した データモデリングのリアーキテクチャ
leveragestech
0
21
理想のパスワードは?
leveragestech
1
78
データエンジニアとしてのキャリア戦略 〜これからの挑戦〜
leveragestech
0
93
ドメインロジックで考えるテスタビリティ
leveragestech
1
330
専門領域に特化したチームの挑戦
leveragestech
0
450
もう一度、 事業を支えるシステムに。
leveragestech
6
5k
ログに対する誤解とベストプラクティス
leveragestech
0
1.4k
We Are PdE!! 〜高価値なプロダクトを作れるようになるための勉強会〜
leveragestech
1
1.9k
Other Decks in Technology
See All in Technology
エンジニアとしてプロダクトマネジメントに向き合った1年半
sansantech
PRO
0
100
ソフトウェアアーキテクトのための意思決定術: Software Architecture and Decision-Making
snoozer05
PRO
17
4k
Creative Pair
kawaguti
PRO
1
130
Makuake*UPSIDER_LightningTalk
upsider_tech
0
200
[2024年10月版] Notebook 2.0のご紹介 / Notebook2.0
databricksjapan
0
1.6k
Grafanaのvariables機能について
tiina
0
180
(Simutrans) 所要時間ベース経路検索のご紹介
teamhimeh
0
100
Autify Company Deck
autifyhq
2
41k
Microsoft Ignite 2024 最新情報!Microsoft 365 Agents SDK 概要 / Microsoft Ignite 2024 latest news Microsoft 365 Agents SDK overview
karamem0
0
190
論文紹介 ”Long-Context LLMs Meet RAG: Overcoming Challenges for Long Inputs in RAG” @GDG Tokyo
shukob
0
270
Postman Vaultを使った秘密情報の安全な管理
nagix
3
140
EDRからERM: PFN-SIRTが関わるセキュリティとリスクへの取り組み
pfn
PRO
0
110
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
133
9.1k
Docker and Python
trallard
43
3.2k
A Tale of Four Properties
chriscoyier
157
23k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
A better future with KSS
kneath
238
17k
Statistics for Hackers
jakevdp
797
220k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
Transcript
技術的負債に立ち向かうために テストを書いてる話 レバテック開発部 前原 宗太朗
| © Leverages inc. 2 自己紹介 お名前 前原宗太朗 所属 レバテック開発部 /
BSD第1開発部 趣味 世界で大人気なゲーム League of Legendsの動画を 見ること
| © Leverages inc. 3 アジェンダ • なぜテストを書くのか • EntrySyncにおけるテストの課題と工夫
1. なぜテストを書くのか
| © Leverages inc. 5 なぜテストを書くのか 社内でテストの重要性が認知されつつある • 社内勉強会 ◦ 単体テストの考え方
/使い方 • レバレジーズテックフェス 2023春のテーマ ◦ 「急がば品質。ワンランク上のレバクオリティへ」 • インシデントの増加 ◦ チーム内でテストを書こうとなったきっかけも 障害から ◦ 複数チームを巻き込む、データリペア作業もあり きっかけこそインシデントだが、テストを書く意義についてもう少し考えてみる Vladimir Khorikov (著), 須田智之 (翻訳) 単体テストの考え方 /使い方
| © Leverages inc. 6 なぜテストを書くのか 積み上げられた仕様 • 改修に改修を重ねたシステムで、正しい仕様の把握が難しい データの項目が多い •
100超えるテーブルもあり、テストケースを用意するのが大変 • どの項目を変化させると、何が変わるのか把握が難しい 連携するシステムが多く、データやビジネスロジックが密に結合している • 業務システムのAPIでデータを取得してビジネスロジックを組み、再度 APIで更新を行っている • 他サービスを立ち上げないといけないので、真面目に取り組もうとすると面倒なことが多すぎる システムの負債が積み重なり、ちょっとした改善でも腰が重いと感じてしまう 重要性は理解している。それでもテストを書くのは腰が重い
| © Leverages inc. 7 なぜテストを書くのか 一人歩きする技術的負債という言葉 技術的負債という言葉はどこか抽象的 リファクタしたい、1から作り直しリニューアルをしたい という声をよく聞くが 、何が問題なのかわからないままリファクタを行っても状況は良くならない
負債を解消するために、まずは負債に対する解像度をあげる必要がある
| © Leverages inc. 8 なぜテストを書くのか ソフトウェアの複雑さには2種類ある 偶発的な複雑さ いわゆる実装の都合によるもの 命名規則やアーキテクチャパターンなどを含む 本質的な複雑さ
問題空間に潜むソフトウェアそのものの複雑さ ソフトウェアの複雑性は本質的な性質であって、偶有的なものではない 複雑性を取り去ったソフトウェア実体の記述は、しばしばその本質も取り去ることになる。 引用 フレデリック・ P・ブルックス , Jr. 著 ピアソン・エディケーション『人月の神話 新装版』
| © Leverages inc. 9 なぜテストを書くのか ソフトウェアの複雑さには2種類ある 偶発的な複雑さ いわゆる実装の都合によるもの 命名規則やアーキテクチャパターンなどを含む 本質的な複雑さ
問題空間に潜むソフトウェアそのものの複雑さ 技術的負債を解消したいと口にした時、偶発的複雑さを指すことが多い しかし本質的な複雑さを軽減しない限り、問題空間全体の複雑さは減らない
| © Leverages inc. 10 なぜテストを書くのか 本質的な複雑さはどうやって減らすのか 問題を分割して考える = 複雑に混じり合った概念を分離する そのために、仕様の直交性に注目する
引用 スケールする要求を支える仕様の「意図」と「直交性」 https://qiita.com/hirokidaichi/items/61ad129eae43771d0fc3#%E4%BB%95%E6%A7%98%E3%81%AE%E7%9B%B4%E4%BA%A4%E6%80%A7 The Art of Unix Programming http://www.catb.org/~esr/writings/taoup/html/ch04s02.html#orthogonality 2つの機能は直交している = 2つの機能が無関係に動作すること モニターには直交コントロールがあります。コントラストレベルに関係なく明るさを変更でき、(モニターに 1つある場合)カ ラーバランスコントロールは両方に依存しません。明るさのノブがカラーバランスに影響を与えるモニターを調整するのが どれほど難しいか想像してみてください。明るさを変更した後は、毎回カラーバランスを調整して補正する必要がありま す。 問題空間全体の複雑さは変わらないが、個別の問題で見た時の複雑さは軽減される
| © Leverages inc. 11 複雑さの正体が分からないと1つの大きな複雑さの塊に見えてしまう 我々は正体不明な複雑性に対して、技術的負債という言葉で片付けてしまう あくまで個人的な見解ですが リプレースは偶発的複雑性を軽減するものでしかなく、本質的な複雑さは軽減されない 複雑に混じり合った概念を分離しない限り、リニューアルをしても本質的な複雑さが軽減されることはない ソフトウェアの本質は複雑さであり、この複雑さに立ち向かいたい
しかし偶発的な複雑さに圧倒されてしまって、本質的な複雑さに立ち向かえずにいる なぜテストを書くのか 1つの大きな複雑さに見えてしまう問題(自戒をこめて) 文字文字してすみません。。。
| © Leverages inc. 12 本質的な複雑さと偶発的な複雑さを同時に対処するのは難しい 偶発的な複雑さを減らした上で、本質的な複雑さに立ち向かいたい そのために継続的改善は必要だし、継続的改善のために既存の資産にもテストが必要 なぜテストを書くのか 複雑さに立ち向かうのは難しい(主観) 文字文字してすみません。。。
2. EntrySyncにおける テストの課題と工夫
| © Leverages inc. 14 我々の扱うシステム オウンドメディア ※ 他にもありますが詳細は割愛 プラットフォーム サブシステム
社内業務システム • 社内業務システムやプラットフォームを支える ための各種マイクロサービス • エージェント業務遂行のためのシステム • 面談や推薦の管理を行う • 求人の閲覧や応募、エージェントの申し込みな ど • ユーザーのマイページ • 求人の応募や作業報告書、請求書の管理など
| © Leverages inc. 15 我々の扱うシステム オウンドメディア ※ 他にもありますが詳細は割愛 プラットフォーム サブシステム
社内業務システム • 社内業務システムやプラットフォームを支える ための各種マイクロサービス • エージェント業務遂行のためのシステム • 面談や推薦の管理を行う • 求人の閲覧や応募、エージェントの申し込みな ど • ユーザーのマイページ • 求人の応募や作業報告書、請求書の管理など EntrySyncとはオウンドメディアと社内業務システムを繋ぐサブシステム
| © Leverages inc. 16 EntrySyncにおけるテストの課題と工夫 オウンドメディアから応募した求職者情報を社内業務システムに連携 オウンドメディアB オウンドメディアA プラットフォーム EntrySync
社内業務システム DB ① 流入情報をDBに保存 ② 流入情報を取得 ③ 営業情報を取得 ⑤ 営業情報を更新 ④ 2、3の情報を元に重複判定 のビジネスロジック
| © Leverages inc. 17 EntrySyncにおけるテストの課題と工夫 EntrySyncでテストを書く上で辛いポイント オウンドメディアB オウンドメディアA プラットフォーム EntrySync
社内業務システム DB ① 流入情報をDBに保存 ② 流入情報を取得 ③ 営業情報を取得 ⑤ 営業情報を更新 ④ 2、3の情報を元に重複判定 のビジネスロジック データを作ってるのが別システム ビジネスロジックのために別システムに問 い合わせが必要 テストで確認したい結果も別システム メディアごとに別のパラメタを持つが、全て 同じテーブルに保存される
| © Leverages inc. 18 認知負荷が高いと感じる • データの項目の数が多い • 確認しないといけないテストの数も多いと感じる 他のアプリケーションとの連携が面倒
• 他のアプリケーションをいい感じに立ち上げないといけない • 初期設定や初期データを用意してあげないといけない これ全てやるのは大変そう、道筋が遠くて腰が重くなる EntrySyncにおけるテストの課題と工夫 “腰が重い状態”を脱したいので、腰が重くなる原因を考える
| © Leverages inc. 19 一つのことに集中して認知負荷を下げる • テストのコンテキストに不要なものはできるだけ隠蔽する ◦ よくよくコードを読むと1つのテストケースに影響する変数はそこまで多くない •
1つのテストで1つのことしか確認しない 複数サービスとの連携は妥協している部分が多い • 本当は複数サービスを立ち上げて CIでe2eとかしたい • まずはローカルで動かせるところから始める EntrySyncにおけるテストの課題と工夫 テストがない状態から、テストがある状態にするのが最重要
| © Leverages inc. 20 一見テストデータの項目数が多くとも、1つのテストケースに影響を与える項目はそう多くはない テスト結果に影響する項目以外はデフォルト値を与えることで、テストに作用する項目がわかりやすくなる EntrySyncにおけるテストの課題と工夫 テストのコンテキストに不要なものは隠蔽する
| © Leverages inc. 21 EntrySyncにおけるテストの課題と工夫 テストの書き方によって認知負荷を軽減する Arrange-Act-Assertパターンによるテストの記述 • テストのフォーマットを準備、実行、結果の確認のフォーマットで記述する •
フォーマットが統一されることでテストを読む際の認知負荷が軽減される 1つのテストでは一つのことしか確認しない • 複数のAssertを1つのテストケースで確認したくなる • 特にArrange-Actが同じ場合はコードを再利用したくなる • 全体の冗長性を許容しても、1つあたりのテストケースの認知負荷を下げる
| © Leverages inc. 22 EntrySyncにおけるテストの課題と工夫 結果として、1つのテストケースが1画面に収まるため視認性が良い
| © Leverages inc. 23 EntrySyncにおけるテストの課題と工夫 他のアプリケーションとの連携 オウンドメディ アB オウンドメディ アA
プラットフォー ム EntrySync 社内業務シ ステム DB ① 流入情報をDBに保存 ② 流入情報を取得 ③ 営業情報を取得 ⑤ 営業情報を更新 ④ 2、3の情報を元に重複 判定のビジネスロジック 本当は全部のサービス起動して e2e なテストを実行したい 現実は全部の環境をシュッと立ち上 げれるほど整っていない 全部を整備するのは億劫
| © Leverages inc. 24 EntrySyncにおけるテストの課題と工夫 腰が重いポイント(再掲) オウンドメディ アB オウンドメディ アA
プラットフォー ム EntrySync 社内業務シ ステム DB ① 流入情報をDBに保存 ② 流入情報を取得 ③ 営業情報を取得 ⑤ 営業情報を更新 ④ 2、3の情報を元に重複 判定のビジネスロジック 他のアプリケーションをいい感じに立ち上げな いといけない ・一旦諦めて最低限ローカル動くことを目指す ・ある程度完成したら CIに移行 初期設定や初期データを用意してあげないと いけない ・ヘルパーを作って beforeAllで呼び出す
| © Leverages inc. 25 EntrySyncにおけるテストの課題と工夫 一部に絞って構築、まずは最低限ローカルで動くように オウンドメディ アB オウンドメディ アA
プラットフォー ム EntrySync 社内業務シ ステム DB ① 流入情報をDBに保存 ② 流入情報を取得 ③ 営業情報を取得 ⑤ 営業情報を更新 ④ 2、3の情報を元に重複 判定のビジネスロジック この部分に絞って構築 残りの環境はDB経由での依存になるためシ ステムを立ち上げる必要はない 初期データをSQLでDBに突っ込むだけでOK データを作る責務はオウンドメディアが持って いるので、そこに作らせたいが、 ここは妥協点
| © Leverages inc. 26 EntrySyncにおけるテストの課題と工夫 自サービスのデータは TypeORMのRepository経由 でEntityを指定して削除 他サービスは最低限のテーブル削除 データの初期化は関数にまとめて、
beforeAllで呼び出す ※ 後日気がついたことですが他サービスでもちょうどテストを書いていて、 最低限のデータを含む Dumpを用意されていたので、今後はそっちを使う予定です サービス単位でこういうのが整備されていると嬉しいですね
| © Leverages inc. 27 まとめ • ソフトウェアには本質的な複雑さと偶発的な複雑さがある ◦ 本質的複雑さに対処するためにも、継続的改善で偶発的な複雑さを減らしていこう ◦
そのために既存の資産にもテスト書いていこう • テストを書こうにも複雑さにやられて嫌になってしまうこともある ◦ 本質的な複雑さは減らせないので、 偶発的な複雑さを積極的に解消していこう
| © Leverages inc. 28 今後 • 負債が溜まっているシステムにテストを書いただけ だと、テストそのものの認知負荷が高く負債となって しまう ◦
テストによってリファクタ耐性がついたので、コードを綺麗にするようなリファクタリングを行う ◦ さらに本質的な複雑さに立ち向かうために概念の分離を行う