1 of 41

テスト駆動での実装の使い所

第157回 PHP勉強会

@docomo R&D OPEN LAB ODAIBA

2023年10月25日 新倉涼太

Copyright© M&Aクラウド

2 of 41

niisan -i

2

  • PHP歴12年くらい
  • 最近はLaravelを使っているけど、実はそんなにこだわりない
    • DIがあるといいな
    • テストが書きやすいといいな
  • 2023/2 からM&A クラウドにジョイン

AI(Stable Diffusion)君に作ってもらった自分の似顔絵

Copyright© M&Aクラウド

3 of 41

お品書き

  • テスト駆動開発やってる?
  • テスト駆動での実装をしたい時の実例
  • まとめ

3

Copyright© M&Aクラウド

4 of 41

テスト駆動開発やってますか?

4

Copyright© M&Aクラウド

5 of 41

テスト駆動開発やってますか?

5

すんません

やってないっす

Copyright© M&Aクラウド

6 of 41

テスト駆動開発ってなんだっけ

そもそもテスト駆動開発ってなんだっけ?

6

  1. 今回のタスクでやりたいことを書き出す
  2. やりたいことのリストから一つ選び、テストを書く
    1. ここでテストが失敗することを確認する
  3. テストが通る最小限の実装をする
    • ここでテストが通ることを確認する
  4. テストが通る状態を維持しながらコードを整理する( リファクタリング )
  5. 2~4を、やりたいことがなくなるまで繰り返す
  6. やりたいことが追加されたら、リストに加える
  7. やりたいことがなくなったらタスク完了!

Copyright© M&Aクラウド

7 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

7

まず、ゴール地点を定める( やりたいこと・TODOリストの作成 )

Copyright© M&Aクラウド

8 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

8

やりたいことから一つを選び、テストを書く。この時、テストが失敗していることを確認することで、実装が必要なことを確認する

テスト

Copyright© M&Aクラウド

9 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

9

テストが通るように実装をする。テストが通ることを確認することで、やりたいこと・TODOの一つを確実にクリアすることができる。

テスト

Copyright© M&Aクラウド

10 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

10

実装を修正し、コードを整理して綺麗にすることで、可読性を改善したり、動作効率を良くしたりする。

テストが通った状態を維持しているので、やりたいことは達成できている

テスト

Copyright© M&Aクラウド

11 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

11

ゴールまで実装しきれば、タスク完了

テスト

テスト

タスク完了!!

Copyright© M&Aクラウド

12 of 41

テスト駆動開発ってなんだっけ

テスト「駆動」とはどういうことか

12

  • テストを書くことで、実装の目標を立てることができる!
  • 実装でテストが通ると、ゴールに向けた前進を実感できる
  • リファクタリングで都度コードを綺麗にしていくことで、完成品の品質を上げることができる!

Copyright© M&Aクラウド

13 of 41

テスト駆動開発ってなんだっけ

いや、お前、テスト駆動やっていない言うたやんけ

13

Copyright© M&Aクラウド

14 of 41

テスト駆動開発ってなんだっけ

なぜテスト駆動をやっていないのか

14

一発でいけるよ

テスト

テスト

テストに駆動してもらわなくても、実装できるケースが多いので、結局テスト駆動でやらないことが多い

Copyright© M&Aクラウド

15 of 41

テスト駆動で実装したい時

15

Copyright© M&Aクラウド

16 of 41

テスト駆動開発で実装したい時

16

テスト駆動開発をしているわけではないが、たまにテスト駆動で実装することはある

Copyright© M&Aクラウド

17 of 41

テスト駆動で実装したい時

たまに現れる実装方針がわからんやつ

17

Copyright© M&Aクラウド

18 of 41

テスト駆動で実装したい時

たまに現れる実装方針がわからんやつ

18

💡

テスト

テスト駆動で着実に実装を前進させれば、完成に迎えるはず

Copyright© M&Aクラウド

19 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

19

https://gist.github.com/niisan-tokyo/613a12edb2e71fe3f755ad06dd475033

実際のコードを例にして、実装の方針が立てにくい場合でも、実装を着実に前進させることをみてみよう

Copyright© M&Aクラウド

20 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

20

全文検索エンジンのElasticSearchのクエリビルダを作ろう!

https://www.elastic.co/jp/elasticsearch

RESTチックなAPIを利用して、インデックスから全文検索を実行し、結果を得ることができ。検索クエリはJSONで指定できる

ここが検索クエリの部分。人間の手でここを書くのが面倒なので、今回はここを生成するphp製のビルダを実装する

Copyright© M&Aクラウド

21 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

21

こんな感じで使えるようになればいいね!

連想配列をjsonに変換すればクエリとして使える

Copyright© M&Aクラウド

22 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

22

そもそもクエリビルダってどう作るの?

Copyright© M&Aクラウド

23 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

23

やりたいことは大体わかっている

でも、実装の方針が立たない

手が止まってしまう

とりあえず、TODOリストは作れるので、作ってしまえ!

そこからテストを作って、実装の起点にしていこう!

💡

Copyright© M&Aクラウド

24 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

24

実装方針が立たないけど、とりあえず、やりたいことをリストにしてみる

ElasticSearchのクエリビルだってことで大体こんなことくらいはやりたいかな?

・ ワード検索ができる

・ IDなどで検索ができる

・ 複数のIDのどれかに一致する検索ができる

・ AND検索ができる

・ OR検索ができる

・ 特定のIDを除外する検索ができる

・ 値の範囲検索ができる

・ 部分的にOR検索ができる

Copyright© M&Aクラウド

25 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

25

適当に空のテストを書いてみる

./vendor/bin/phpunit tdd/ElasticSearch/QueryBuilderTest.php --testdox

Copyright© M&Aクラウド

26 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

26

まずは、ワード検索のテストを書いてみる

テストが失敗しているのを確認できる。

Copyright© M&Aクラウド

27 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

27

テストが通るように実装する

テスト成功!次に進もう

Copyright© M&Aクラウド

28 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

28

どんどん進めていくぞ!

Copyright© M&Aクラウド

29 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

29

どんどん進めていくぞ!

Copyright© M&Aクラウド

30 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

30

and検索行きたいが・・・

Copyright© M&Aクラウド

31 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

31

一気に配列の階層が増えているので、これに対応しなければならないな

Copyright© M&Aクラウド

32 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

32

テストが通ったぞ!これで先に・・・

Copyright© M&Aクラウド

33 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

33

今までのテストが全部落ちたー!?

AND検索はできるようになったけど、これまでのテストが落ちてる。

何らかの対応が必要だ!

Copyright© M&Aクラウド

34 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

34

現れる二つの選択肢

現在の仕様に合わせ、条件を一つだけ指定した場合と、複数指定した場合で返却する方法を変えるか

とりあえず、条件の数に関わらず、

[‘bool’ => [‘must’ => [...]]]

という形で出力するように実装するか

( テストを修正する必要がある )

Copyright© M&Aクラウド

35 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

35

クエリーの数に従って返却値を修正する

これで前進したぞ!

Copyright© M&Aクラウド

36 of 41

テスト駆動で実装したい時

実際の例: ElasticSearchのクエリビルダ

36

実装を進め、全部テスト通ったらタスク完了!

改善点とか、まだやるべきところはあるけど、一旦今回は完了になる

Copyright© M&Aクラウド

37 of 41

テスト駆動で実装したい時

テスト駆動での実装

37

  • どうやって実装進めたらいいかわからない時に、テスト駆動開発の手法を使って実装することをそう呼んでる
    • 常にテスト駆動で実装しているわけではないので、テスト駆動開発をやってるとはいうのを憚られる
  • テストを書いてから、それに従う最小の実装を書き、とにかく着実に実装を進めていく
  • 新しい実装が、これまで実装してきたものと合わなくなる場合は、以前のテストが落ちるという形で気づくことができる
  • テストが落ちた時、実装を直すのではなく、仕様を修正する(=テストを修正する)という手段もある
    • この場合は、チームとの相談などが必要かもしれない

Copyright© M&Aクラウド

38 of 41

テスト駆動で実装したい時

テスト駆動での実装の超重要なこと

38

コードを書く手が止まらない

Copyright© M&Aクラウド

39 of 41

まとめ

まとめ

39

  • テスト駆動開発は、TODOリストに従い、小さくテストを作り、実装のチェックポイントを作りながら着実に実装を前に進める開発手法
  • 現在は実装方針があらかじめわかる場合が多いので、テスト駆動じゃなくても実装できちゃうので、面倒になってテスト駆動開発をやっていない
  • 実装方針がたちにくい、どこから手をつけたらいいのかわからないような仕様が出てきた場合は、テスト駆動で実装進める技が使える
  • もし、実装の手が止まっちゃったら、その時だけテスト駆動で実装進めてみるというのどうでしょうか?

Copyright© M&Aクラウド

40 of 41

おまけ

バグ修正はテスト先に書くのがおすすめ

40

  • テストを先に書いて、どこでバグが発生していたかを特定してから修正をすると、確実にそのバグを直せて、しかも再発しないのでおすすめ
  • むしろ、テストを先に書いて、そのテストが落ちている状態をコミットして証拠を残しておくと、少なくともその時点で発生していたバグは修正されているということを、後から確認できるので、再発防止だけでなく、事象の共有という意味でもおすすめ

Copyright© M&Aクラウド

41 of 41

41

Copyright© M&Aクラウド