2023-02-01
プログラマのためのTDD コンセプト編

“コード書ける人”から「真のプログラマ」になるための技術
~TDD~

みんな、はろー!
しもてぃやよ!

  • メンバー変更や欠席によって、開発が遅延する
  • 要求の変更があるたびに、コードが汚くなり、変更に自信がなくなる

こんな状況になっているなら、そのチームはとてもマズい状態やよ!

プログラミングは、コツさえ掴めば簡単に始められるし、とっても役に立つ!
でも実は、学校や書籍で学習したプログラミングの技術だけでは「真のプログラマ」には不十分!
そんな”コード書ける人”から「真のプログラマ」になるための必須技術を紹介するよ!

“コード書ける人”と「真のプログラマ」は全然違う!

なんと! プログラマの仕事は、”コードを書く”ことではない!
だから、”コード書ける人”と「真のプログラマ」とは、ぜーんぜん違う!

「真のプログラマ」は”コードが書ける”上に、こんなことができる!

自分の書いたコード・その結果(品質)に責任が持てる!

プログラマには、自分が書いたコードや、そのコードが動いた結果に責任が伴う

“コード書ける人”は、「私はちゃんとやりました」って言うか、結果をサラッと見て「うまく動いてそう」って思う以外できない
「真のプログラマ」は、きちんと責任を持つことができる
「オレを信じろ!」って言い張るのではなく、客観的事実として「要求を満たした」ということを示すことができる

(自分を含む)メンバーに欠席・離脱・追加があっても、プロジェクトが正常に続けられる!

プログラムは、ほとんどの場合、複数人のチームで開発する
しかも、そのメンバーは、いろんな理由ですぐに変わる!
体調が悪くてリリース直前にお休みするかもしれないし、別プロジェクトに移動になるかもしれない
転職でメンバーが離脱するかもしれないし、新入社員がチームにjoinするかもしれない

“コード書ける人”のチームでは、メンバーに変更があった際、開発速度が圧倒的に落ちる
特に、メンバーの離脱は速度も品質も、もはやプロジェクト存続の危機レベルまで落ちることがある
「真のプログラマ」で構成されたチームでは、チームメンバーが常に変化する中でも、結果を出し続けることができる!

要求の追加・変更にも、早く確実に対応できる!

世界は常に変化しているから、顧客からの要求も常に変わる
顧客も開発者も、最初から完璧にニーズを把握していることなんてほぼ無いから、要求は絶対変わる

要求の変更があった場合、当然プログラムを変更することになるけど、開発規模が大きくなるほど、変更が難しくなる

思い通りの変更ができているのか…
その変更によって、他の場所で予期せぬ副作用(バグやエラー)が起きていないか…

“コード書ける人”は、開発規模が小さいプロジェクト開始時は、素早く思い通りのコードを書くことができるが、開発が進み、規模が大きくなるにつれ、少しの変更にもとても時間がかかり、副作用のせいで品質がどんどん落ちていく
「真のプログラマ」は、変更要求を受けても、副作用が無いことを常に確認し、早く・確実に・品質高く変更に対応できる

どう?
「真のプログラマ」は、”コード書ける人”が持っていない「すごさ」があるでしょ?

「真のプログラマ」の必須スキル ~テスト~

“コード書ける人”と「真のプログラマ」は何が違うのか?
それは、「テスト」を書くこと!

テストとは「期待される動作」をコードで定義する方法

プログラミングには、「テスト」ってすごい技術がある!

テストは「期待される動作」をコードで定義・表現するもの
それを実行することで、「コードは期待された動作を行っている」ということが確認できる!

全プログラマに必要なスキルは単体テスト

「テスト」って聞いてイメージするのは、どんなもの?
製品が出来上がってから、その動作確認をする?
バグや不具合を見つけるための行動?

テストは、2つの考え方で、4つの分類ができるよ!

  • 技術面 ⇔ ビジネス面
  • チームを支援する ⇔ 製品を批評する

この中で、「真のプログラマ」になるための、全プログラマ必須なテストは「技術面 & チームを支援する」テスト!
単体テストや、コンポーネントテストってのが、それに当てはまるよ

単体テストは「テスト対象に対して」「こんな環境を与えると」「こーなる」を最小単位で表現する

単体テスト(ユニットテスト)っていうのは、「ある関数にある引数を渡すと、こういう値がreturnされるハズ」とか、「このメソッドを実行すると、クラスのプロパティがこう変更されるハズ」とかをテストするもの

テストに出てくる要素は↓3つ!

  • テスト対象
  • 与える環境(入力する値等)
  • 期待する状態

つまり「あるテスト対象に対して」「こんな環境を与えると」「こーなる」ってのを、コードで表すよ!
例えば、「足し算する関数(add)に対して」「3と5を与えると」「8がreturnされる」みたいな感じ

そんな難しくなさそうでしょ?

しかも、単体テストは、その関数”単体”をテストするもの
他のモジュールや、コンポーネントとの相互作用は考慮しない!
ただその「関数」や「メソッド」とかが、期待通りの動作をしているかを確認するだけやよ!

テストを完璧に活かす開発手法 ~TDD~

テストって技術を完璧に活かす「TDD」という開発手法があるよ!
TDD は Test-Driven Development (テスト駆動開発)のこと
よーするに、「テストを書くことを中心として、開発を進める」ってこと!

TDDの流れ

TDDはシンプルな行動を繰返すことで、開発を進めていくよ

  1. 実現したい機能を”テスト”の形で表現する!
  2. それを実現するプロダクトコードを書く!

(注) 原典では、TDDをアルゴリズム的に実行するための別の書き方がされてるけど、ここでは、”TDDの気持ち”を伝えるために、↑みたいに書いてるよ

TDDは↓のルールを守って開発すれば、誰でも簡単に実践できるよっ!

ルール①: 「プロダクトコードを書く前に、テストコードを書く」

プロダクトコードを書く前に、テストコードを書こう!

機能を担うコードが「プロダクトコード」
例えば、↓の感じ

def add(a, b):
    return a + b

機能をテストするコードが「テストコード」
↓の感じ

def test_when_3と5を渡す_then_8を返す():
    actual = add(3, 5)
    expected = 8
    assert actual == expected

これを、まず、テストコードをから書くってのが、TDDのルールその①!

先にテストコードで「期待される理想の状態」を定義するから、「テストされていない機能」が存在しない状態をずっと保てる!

ルール②: 「常にテストコードがパスするように保つ」

テストコードを1つ追加したら、それをパスする(OKになる)ように、プロダクトコードを書こう!

今追加したテストも、今まであった他のテストも、すべてのテストがパスしたことが確認できれば、「今追加した機能が、副作用なく追加できた」と自信をもって言い切れる!

他にも気にしたいこととか、Tipsはいっぱいあるけど、まずはここから始めよう!

TDDの圧倒的メリット

「こんな簡単なルールに従うだけで、そんな良いことある?」って思うかもしれない
でも、安心して!
すごい良いことがいっぱいあるよ!

メリット①: いつでも期待通り動くことを確認できる!

テストを見ると「どんな動作が期待されているのか」がすべて書いてある!
それを実行するだけで「今、期待通り動くのか」を確認できる!

しかも開発中は、ターミナルで1行書けば実行できて(普段は「↑」 押して Enter 押せば実行できる)、ほとんどは数秒でテストが完結する(長くても数分)!

つまり、テストを常に、最新の要求を反映した状態にしておくことで、いつでも「要求通りの動作を行う」ことが確認できるっ

メリット②: 情報共有のためのドキュメントが不要になる!

しもてぃはドキュメントを書くの、めんどくさくて、好きじゃない!
っていうか、今まで、ドキュメント書くの大好きって言ってる人なんて、見たことない!
開発途中で(引継資料等として)作成されたドキュメントが、1か月後も現実を反映するように更新されている現場も見たことないw
みんなも、ドキュメントなんて書きたくないでしょ?

もし、全ての機能に適切なテストがあると、テストが”機能一覧”になる!
つまり、(チーム内情報共有のための)仕様書的なドキュメントを書かなくて良くなる!
メンバー離脱のときも、新メンバー追加の引継のときも、テストさえ見れば、プログラムの仕様はわかるのだ!

顧客に対する説明のためのドキュメントは、テストで代わりにはでけへんよ
でも、少なくとも、ガンガン変更されていく開発中に、

  • ドキュメントを整備する必要が無い
  • 引継に長時間かける必要もない
  • 急に休んでも大丈夫

なのは、圧倒的なメリットじゃない?

メリット③: 「ここまでは絶対できてる」って言えるので、圧倒的にメンタルが楽になる

すべての機能にテストがついていて、そのすべてがOKな状態なので、新たに追加した機能や、変更があった機能が、「他に悪影響を与えているかもしれない…」って不安になることが絶対にない!

今書いたコードで確実に前に進んだ!って思えるのは、特に緊急対応時のメンタルとしては、すごい重要で心強いよ!

まとめ

“コード書ける人”から「真のプログラマ」になるためには、TDDは必須のスキルやよ!
学校やお本で勉強したプログラミングスキルを、お仕事とかで実際に役立てるのに、絶対に必要!
なのに、なかなか教えてもらえないってのが、びっくりポイント!
でも、1回経験してしまったら、TDDで開発されていない・テストが書かれていないプロジェクトには、もう二度と関わりたくないって思うぐらい、素晴らしい手法やよ!

みんなも責任と自信を持った、「真のプログラマ」生活を今すぐTDDで始めよー!

P.S.

今回は「テスト」とか「TDD」について、大事な”気持ち”をご紹介したよ!
具体的にどうするの? とか、TDDのプラクティスとか、気になることがあったら、是非しもてぃに教えてほしい!

今回、これを読んだ感想とかも教えてくれると、しもてぃ超うれしい!
みんなの感想・フィードバック、なんでもおしえて~!

原著

しもてぃはTDDをこのお本で学んだよ!
TDDの流れをペアプロで教えてもらえるみたいに理解できるよ!

いいね!
0