こんにちは。エンジニアの竹野です。
プロダクトに関わるチーム全員が、「新しい価値(機能)を、もっと速くユーザーに届けたい 」と願っているはずです。
しかし、サービスが成長して機能が増えれば増えるほど、 「ここを修正したら、別の場所が壊れてしまうかもしれない…」 という見えない不安も大きくなっていきます。
この「変更に対する不安」を取り除き、チームが安心して開発スピードを維持できるようにするための技術が 「テストコード 」です。
この記事では、「そもそもテストコードって何をしてくれるの? 」疑問から、エンジニアの方に向けて「開発を加速させる、良いテストコードの書き方 」を、実際のコードも交えながらご紹介します。
「テストコード」とは、
システムに新しい機能を追加したり、デザインを変えたりした後には、必ず「正しく動くか」を確認するテスト作業が発生します。
非エンジニアの方がイメージするテストは、実際にスマホやPCを触って確認する「手動テスト」だと思います。 もちろんこれも重要ですが、エンジニアが書く「テストコード」は役割が少し異なります。
「手作業の確認」は雪だるま式に増えていく
システムは様々な機能が複雑に絡み合って動いています。そのため、
「新しくAという機能を追加したら、昨日まで正常に動いていたBという機能が突然壊れてしまった」
ということがよく起こります。
これを防ぐためには、Aを追加した後に、AだけでなくBもCも、既存の機能すべてをテストし直さなければなりません。
機能が10個のうちは手作業でも確認できますが、100個、1000個と機能が増えていくと、手作業の確認にかかる時間は雪だるま式に膨れ上がり、やがて新機能を作る時間がなくなってしまいます。
テストコードが「安心」と「スピード」をもたらす
そこでエンジニアは、プログラムを使ってプログラムを自動でチェックする仕組みを作ります。これが「テストコード」です。
「ユーザーが商品をカートに入れて、決済ボタンを押したら、正しく購入完了画面が出るか」
といった一連の動作確認を、人間の代わりにプログラムに記憶させておくのです。
一度テストコードを書いておけば、その後は何度でも、数千項目のチェックをたった数秒〜数分で終わらせてくれます。
これがあるおかげで、エンジニアは「既存の機能が壊れていないこと」を瞬時に確認でき、自信を持って、圧倒的なスピードで新しい機能の開発に集中できる ようになります。テストコードは、未来の開発スピードを落とさないための重要な「投資 」なのです。
【エンジニア向け】負債にしない、価値を生むテストコードの書き方
ここからはエンジニア向けの話です。
テストコードは書けば書くほど良いわけではありません。書き方を間違えると、少しコードを整理しただけでテストが失敗するようになり、かえって開発スピードを落とす「負債」になってしまいます。
開発を加速させる、正しいテストコードを書くための3つのポイントを紹介します。
① 「どう作られているか」ではなく「どう動くか」をテストする
「特定の内部メソッドが呼ばれたか」といった、コードの内部構造(実装の詳細)に依存したテストは避けましょう。
テストすべきなのは、「この入力に対して、期待通りの出力が返ってくるか」というユーザーから見た振る舞い です。振る舞いさえテストしておけば、後から内部のロジックをより綺麗に書き直した(リファクタリングした)としても、テストコードを修正する手間は発生しません。
② 全てを100%網羅しようとしない(重要な機能に絞る)
すべてのコードに対してテストを書こうとすると、開発工数が膨れ上がってしまいます。「利用規約のテキストが正しいか」といった変更頻度が低く、壊れても影響が少ない部分に時間をかける必要はありません。
「決済処理」「ログイン」「中核となる計算ロジック」など、そこが壊れたらサービスが成り立たないコア機能 から優先的に、手厚いテストを書きましょう。
③ 生きた仕様書として、読みやすく書く(実際のコード例)
テストコードは、システムがどう動くべきかを示す「生きた仕様書」です。後からチームに参加したメンバーが読んですぐに理解できるよう、Given(前提) – When(操作) – Then(結果) の3ブロックに分けて記述するよう心がけましょう。
実際のテストコード(PHP / Laravelの例)を見てみましょう。
PHP
<?php
namespace Tests\Unit;
use Tests\TestCase;
use App\Models\Cart;
use App\Models\Item;
class CartTest extends TestCase
{
public function test_20パーセントOFFクーポンを適用すると合計金額が800円になること()
{
// ① Given(前提条件): カートに1000円の商品が入っている
$cart = new Cart();
$cart->addItem(new Item('Tシャツ', 1000));
// ② When(操作): 20%OFFクーポンを適用して、合計金額を計算する
$totalPrice = $cart->calculateTotal([
'coupon_code' => '20_PERCENT_OFF'
]);
// ③ Then(期待される結果): 合計金額は800円になっているはず!
$this->assertSame(800, $totalPrice);
}
}
このように綺麗に整理されたテストコードは、そのまま「この機能はどう動くのが正解か」を示すドキュメントとして、チーム全体の貴重な資産になります。
まとめ:テストコードは今後も最速でユーザーに新機能を届け続けるための土台作り
テストコードの作成に時間を使っている時、エンジニアは決して立ち止まっているわけではありません。
「この先もずっと、最速でユーザーに価値を届け続けるための土台」
を作っているのだと理解していただけると嬉しいです。
そして、エンジニアはそのテストコードは「本当に開発を楽にし、変更への恐怖をなくすもの 」になっているのか、目的を見失わず、価値のあるテストコードを育てていきましょう。
こんにちは。エンジニアの竹野です。
プロダクトに関わるチーム全員が、「新しい価値(機能)を、もっと速くユーザーに届けたい」と願っているはずです。
しかし、サービスが成長して機能が増えれば増えるほど、
「ここを修正したら、別の場所が壊れてしまうかもしれない…」
という見えない不安も大きくなっていきます。
この「変更に対する不安」を取り除き、チームが安心して開発スピードを維持できるようにするための技術が
「テストコード」です。
この記事では、「そもそもテストコードって何をしてくれるの?」疑問から、エンジニアの方に向けて「開発を加速させる、良いテストコードの書き方」を、実際のコードも交えながらご紹介します。
「テストコード」とは、
システムに新しい機能を追加したり、デザインを変えたりした後には、必ず「正しく動くか」を確認するテスト作業が発生します。
非エンジニアの方がイメージするテストは、実際にスマホやPCを触って確認する「手動テスト」だと思います。
もちろんこれも重要ですが、エンジニアが書く「テストコード」は役割が少し異なります。
「手作業の確認」は雪だるま式に増えていく
システムは様々な機能が複雑に絡み合って動いています。そのため、
「新しくAという機能を追加したら、昨日まで正常に動いていたBという機能が突然壊れてしまった」
ということがよく起こります。
これを防ぐためには、Aを追加した後に、AだけでなくBもCも、既存の機能すべてをテストし直さなければなりません。
機能が10個のうちは手作業でも確認できますが、100個、1000個と機能が増えていくと、手作業の確認にかかる時間は雪だるま式に膨れ上がり、やがて新機能を作る時間がなくなってしまいます。
テストコードが「安心」と「スピード」をもたらす
そこでエンジニアは、プログラムを使ってプログラムを自動でチェックする仕組みを作ります。これが「テストコード」です。
「ユーザーが商品をカートに入れて、決済ボタンを押したら、正しく購入完了画面が出るか」
といった一連の動作確認を、人間の代わりにプログラムに記憶させておくのです。
一度テストコードを書いておけば、その後は何度でも、数千項目のチェックをたった数秒〜数分で終わらせてくれます。
これがあるおかげで、エンジニアは「既存の機能が壊れていないこと」を瞬時に確認でき、自信を持って、圧倒的なスピードで新しい機能の開発に集中できるようになります。テストコードは、未来の開発スピードを落とさないための重要な「投資」なのです。
【エンジニア向け】負債にしない、価値を生むテストコードの書き方
ここからはエンジニア向けの話です。
テストコードは書けば書くほど良いわけではありません。書き方を間違えると、少しコードを整理しただけでテストが失敗するようになり、かえって開発スピードを落とす「負債」になってしまいます。
開発を加速させる、正しいテストコードを書くための3つのポイントを紹介します。
① 「どう作られているか」ではなく「どう動くか」をテストする
「特定の内部メソッドが呼ばれたか」といった、コードの内部構造(実装の詳細)に依存したテストは避けましょう。
テストすべきなのは、「この入力に対して、期待通りの出力が返ってくるか」というユーザーから見た振る舞いです。振る舞いさえテストしておけば、後から内部のロジックをより綺麗に書き直した(リファクタリングした)としても、テストコードを修正する手間は発生しません。
② 全てを100%網羅しようとしない(重要な機能に絞る)
すべてのコードに対してテストを書こうとすると、開発工数が膨れ上がってしまいます。「利用規約のテキストが正しいか」といった変更頻度が低く、壊れても影響が少ない部分に時間をかける必要はありません。
「決済処理」「ログイン」「中核となる計算ロジック」など、そこが壊れたらサービスが成り立たないコア機能から優先的に、手厚いテストを書きましょう。
③ 生きた仕様書として、読みやすく書く(実際のコード例)
テストコードは、システムがどう動くべきかを示す「生きた仕様書」です。後からチームに参加したメンバーが読んですぐに理解できるよう、Given(前提) – When(操作) – Then(結果) の3ブロックに分けて記述するよう心がけましょう。
実際のテストコード(PHP / Laravelの例)を見てみましょう。
PHP
このように綺麗に整理されたテストコードは、そのまま「この機能はどう動くのが正解か」を示すドキュメントとして、チーム全体の貴重な資産になります。
まとめ:テストコードは今後も最速でユーザーに新機能を届け続けるための土台作り
テストコードの作成に時間を使っている時、エンジニアは決して立ち止まっているわけではありません。
「この先もずっと、最速でユーザーに価値を届け続けるための土台」
を作っているのだと理解していただけると嬉しいです。
そして、エンジニアはそのテストコードは「本当に開発を楽にし、変更への恐怖をなくすもの」になっているのか、目的を見失わず、価値のあるテストコードを育てていきましょう。