Slide 1

Slide 1 text

良いユニットテストの性質を整理して たら考えるべき設計も⾒えてきたの 2024年6⽉18⽇

Slide 2

Slide 2 text

⾃⼰紹介 名前: bun (今泉⼤樹) 所属: クラスメソッド株式会社 認定試験 AWS認定試験12種 JSTQB(ソフトウェアテスト技術者の試 験) Advanced Level Test Manager / Test Analyst / Technical Test Analyst 憧れた異能⼒ アンサー‧トーカー / = Japan AWS Top Engineer(Service)

Slide 3

Slide 3 text

皆さん良いユニットテストのコードはかけ ていますか?

Slide 4

Slide 4 text

テストコードというくらいだから、設計やデザイン が⼤事ですよね テストコードに限らないプロダクションコードの設計 追加したいとき、変更したい時にすぐに書ける テストを書き始めるのにハードルが低い テストコード⾃体のノウハウ どういうことをテストしているのか⾮技術者にもわかりやすい命名など 有⽤なテストケースを作成するためのノウハウ ブラックボックステストの技法など

Slide 5

Slide 5 text

でも設計(How)を考える前に、「理由」や「何 を?」ということも⼤事じゃないですか? 要求を仕様化するときも理由を整理すると良いじゃないですか?「アーキテクチャはこう!」って⾔わ れるより根底の思想を知っておくと深みが出ません? なにを得たくてユニットテストコードを書くのか? ⽬的は?⼼理的安全性? なんとなくで良いテストを整備し続けられるほど⼈間は強いのか? → 唯⼀の定義の押し付けをしたいんじゃなくて、良いユニットテストって何ってことを整理してチームで 同じ⽅向を向いてコード‧テストコードの設計をしていきたいんだけなんだ。私は。

Slide 6

Slide 6 text

やりたいことの道筋 ユニットテストの名著から「良いユニットテストを書くた めのノウハウ」をインプット ユニットテスト‧インテグテストの違い、⽬的の違いを整 理する(今⽇話します) じゃあ、⽬的を果たすためにどういう設計やコーディング をすればよいのか(また今度)

Slide 7

Slide 7 text

1.ユニットテストの 名著たち 最近読了して特に響いた書籍を抜粋

Slide 8

Slide 8 text

今回読んだ本はこちらの3冊 単体テストの考え⽅/使い⽅|マ イナビブックス The Art of Unit Testing, Third Edition テストから⾒えてくるグーグル のソフトウェア開発

Slide 9

Slide 9 text

3冊の書籍の内容の前に‧‧‧ユニットテストとは とても定義があいまい ISTQB という国際的なソフトウェア認定資格の機関の⽤語集にも乗っていない(2024/06/14調べ) コンポーネントテストという表現をよく利⽤されている印象 以下⾼橋寿⼀⽒の書籍にて以前は⽤語集にあったものの、今はない旨が書かれていました Shoeisha ソフトウェア品質を⾼める開発者テスト 改訂版 アジャイル… ウォーターフォールでもアジャイルでも、 上流品質を上げまくって、 よい製品を楽に作ろう! テスト界の第⼀⼈者、⾼橋寿⼀⽒執筆の…

Slide 10

Slide 10 text

各著書では「良いユニットテストの特徴」 みたいなのをどう捉えているのだろう?

Slide 11

Slide 11 text

単体テストの考え⽅/使い⽅ 良い単体テストを構成する4つの柱 1: 退⾏(リグレッション)に対する保護 何らかの変更があった時に以前の挙動が壊れていないかといった観点だと思います 2: リファクタリングへの耐性 テストが失敗することなく、どのくらいプロダクションコードへの変更を加えられ るか 3: 迅速なフィードバック 4: 保守性 ※ 著者はユニットテストにおいては、2と3は1より優先して備えさせる旨述べている(4は1~3と 競合しないのでいずれでも備えさせると良い)

Slide 12

Slide 12 text

The Art of Unit Testing Third Edition 良い単体テストが備えている性質 素早く動作する テスト対象のものを完全に制御できている 例えば外部ライブラリのソースは完全にはコントロールできないので、適切にテス トダブルに置き換えられるようになっている 他のテストケースから独⽴して実⾏される ファイルシステム、ネットワーク、データベースを必要とせずメモリ上で実⾏される 可能な限り直列に実⾏される(並列スレッドを使⽤しない)

Slide 13

Slide 13 text

テストから⾒えてくるグーグルのソフ トウェア開発 ユニットテストという定義を明確に避けて、「テストサイズ(S/M/L)」という定義を利⽤ Sサイズテスト(⼀般にユニットテストとイメージされるもの) 環境から切り離してコードの⼀単位のふるまいをチェックする ファイルシステム、ネットワーク、データベースなどの外部サービスはモック‧フェイ クを使⽤する Sサイズテストのメリット 分離され、外部依存がないので、⾮常に⾼速に実⾏できる 頻繁に実⾏され、バグをすみやかに⾒つけることも多い すぐにフィードバックを提供できる あらゆる環境で⾼い信頼性のもとで実⾏できる など

Slide 14

Slide 14 text

それぞれのテストサイズについて、「実⾏ 時間が何ms以下」「モック化する外部依 存」など定義されていました

Slide 15

Slide 15 text

twada⽒の資料にも記載があります(⾮ 常に勉強になる) Speaker Deck サバンナ便り〜⾃動テストに関する連載で得られた知⾒のま… 2023/05/17(⽔) Qiita Conference 2023

Slide 16

Slide 16 text

さて

Slide 17

Slide 17 text

3冊とも共通しているっぽい「良いユニットテストの 性質」 実⾏速度が早い 環境依存性が低く、迅速にフィードバックをくれる いつでも⼿軽に実⾏できる コマンド⼀発、ボタン⼀発で特に⼿動の前処理などせずともすぐに実⾏できる的な 安定感があり、失敗して欲しい時に失敗する ビジネス上の要求が変わるなど、システムのふるまいが変わったときには失敗する 逆にふるまいが変わってないのに、内部の実装を変えただけで失敗しないなど

Slide 18

Slide 18 text

ちなみに「失敗してほしい時に失敗する」 の⼀例

Slide 19

Slide 19 text

よさそうな例

Slide 20

Slide 20 text

いまいちそうな例

Slide 21

Slide 21 text

話を戻して‧‧‧

Slide 22

Slide 22 text

実⾏速度(フィードバック)が早い 失敗して欲しいときにだけ失敗する いつでも⼿軽に実⾏できる

Slide 23

Slide 23 text

はやい‧やすい‧うまい みたいですね

Slide 24

Slide 24 text

さておき‧‧‧その裏返しとして 「ユニットテストをパスしたぞ!これで安⼼だ!」という安⼼感は他のサイズのテストより少なそう 単純に「本当の外部依存」を含むことが少なそうなので、システム全体がうまく動作しているかは わからなくなりがち 断じて安⼼しないという意味ではなく‧‧‧「システム全体がちゃんと動いているぜ!」という安 ⼼感ですね

Slide 25

Slide 25 text

インテグレーションテスト(統合テスト)は‧‧‧ 「ユニットテストが持っていて欲しい性質を⼀つでも満たさないもの」と表現される書籍もあった 良いユニットテストの性質との対⽐ いくつかの外部依存を含む(DBやファイルシステムなど) どうしても「外部の状態」を持つことになるため、ユニットテストよりは⼿軽に実⾏できな い、やや不安定になる 必然的にユニットテストほど⾼速には動作しない(もちろんUIテストなどよりは速い) 「テストパスした!よかった。リグレッションしてなさそう」という安⼼感はユニットテストより ⾼い

Slide 26

Slide 26 text

「実⾏速度」と「パスした時の安⼼感」の2軸で考え ると、こんな感じ?

Slide 27

Slide 27 text

2. ここから⾒えてくるテ ストコードのデザイン 時間の都合上今⽇は少しだけ‧‧‧

Slide 28

Slide 28 text

ユニットテストに期待すること とにかく迅速にフィードバックをくれること 失敗して欲しい時に失敗して、失敗してほしくないときには失敗しないこと いつでも(どこでも)実⾏できる 気になった時にいつでも⼿軽に追加‧変更できる

Slide 29

Slide 29 text

超ざっくり整理するとすれば? テスト種類 実⾏するタイミング 検証対象のロジック ユニット(Sサイズテスト) とにかく頻繁。極端な話、変更を ウォッチして保存するたびとか? ⾃然とビジネスロジ ックが中⼼になりそ う インテグ(Mサイズテスト) コミット前やPull Request時とか Controller や DBな どのビジネスロジッ クではない技術側の 都合も含みそう

Slide 30

Slide 30 text

じゃあそれを満たすためにどういうことを 意識して設計しないといけないのか?

Slide 31

Slide 31 text

期待することが分かれば考えるべきこ とが⾒えてくる 「ビジネスロジック」と「外部への依存」が密に結合しないためには? DBや外部システムなどのシステムプロセス外の外部依存との接地⾯を少なくするには? ユニットテストとインテグテストの実⾏タイミングが違うなら、どういうふうに分けて実 ⾏できるようにするの? じゃあテストダブル(モック·スタブなど)ってどうやって使うのさ? モックは極⼒使わないって聞いたこともあるんだけど? 「ふるまいを検証する」というけど、「ふるまい」ってなんやねん

Slide 32

Slide 32 text

などなど、いくら時間があっても⾜りない

Slide 33

Slide 33 text

これらの話はまた今度させてください (機会があれば)

Slide 34

Slide 34 text

まとめ ユニットテストの定義はISTQBの⽤語集にもないくらい曖昧な⾔葉 でも、名著を読むことで「ユニットテストに持っていて欲しい性質」「ユニットテストから得たい利 益」が⾒えてくる → ⽬的について⼼から納得していると、忘れないしアーキテクチャに深みが出るはず それらを踏まえておくと、ソフトウェアアーキテクチャや、テストの実装⽅針などいろいろなことが⾒ えてくる 機会があればまた今度お話をしたい‧‧‧

Slide 35

Slide 35 text

ご清聴ありがとうございまし た!