y_megane.log

日々の勉強や改善ネタの備忘。

伝統的な単体テストと一般的な単体テストの違い

SIer, メーカー, IT子会社などトラディショナルなシステム開発現場における「単体テスト」は正しい(?)意味での単体テストと違う意味で使われていることが多い。
そんな現場でもCI/CDとか自動テストとか頑張っていこうね、という空気はあったりなかったりするが、そもそも単体テストの概念が違うのでテストの粒度とかテストコードとか、会話が噛み合わない。

そんなトラディショナルな現場でテストコード書いていくには、言葉を正しく理解して根本的なところから攻めていかない何も始まらないよね、というポエム。

トラディショナルな手法を否定するとかこうするべき、という話はとくになく単にこういう齟齬がありますよ、というお話。

言葉の意味としての単体テスト

単体テスト - Wikipedia

コンピュータプログラミングにおいて単体テスト(たんたいテスト)あるいはユニットテスト(英語: Unit test)とは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュータプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御データ、使用手順、操作手順とともにテストする手法である。

テストの粒度に関して同じくWikipediaより

手続き型プログラミングでは、ユニットは、モジュール全体のこともあるが、より一般的には、個々の関数や手続きである。オブジェクト指向プログラミングでは、ユニットは、クラスなどのインタフェース全体だが、個々のメソッドであることもある。

テスト技術者資格制度のシラバスでも同じように書いてある。
JSTQB-SyllabusFoundation_Version2018.J03

テスト対象
コンポーネントテストの典型的なテスト対象の例:
コンポーネント、ユニット、またはモジュール
• コードとデータ構造
• クラス
• データベースモジュール

トラディショナルな単体テスト

トラディショナルな文脈での単体テストはクラスやメソッドというユニット単位ではなく、「単機能」を指すことが多い。

SierやメーカーITの開発現場では「単体テスト仕様書」というものがあり、データのパターンや画面入力のパターンがケースとして羅列されている。
この「単体テスト」仕様書は基本的に機能単位で作られる。
もっと具体的にいうと、画面単位やバッチ単位の「単体テスト」仕様書となる。
単体テストを実施する際は、アプリは開発サーバーにデプロイされ開発機DBに接続しており、開発者はブラウザからアクセスしてテストする。
で、画面をスクショとってExcelに貼るわけだが、それはまた別のお話…

以下のサイトがまさにそういう表現になっていた。
単体テスト・結合テスト・総合テストの違い、観点や注意点を簡単に説明する | 若手プロマネの羅針盤

「関数やメソッド単位にロジックの不具合を検出する」と定義されるのが一般的だが、どの単位で単位テストを実施するのかは、プロジェクト毎に定義すべきである。 つまり、単体テストを画面やバッチ機能単位で実施しても良い。

テストコードやCIが一般的じゃなかった頃は、どこもこういうものだったのだろうか?
いずれにせよ、単体テストを上のように定義するとテストコード書いてどうこうなる世界ではなく、ユニットテストかとEnd to Endテストとかゴチャ混ぜというか、区分がない。

加えて、テスト仕様書はだいたい会社としての標準フォーマットとか開発ルールとして定められている。
「次の案件はテストのやり方変えよう!テストコード書いていこう!」
となったとしても、ルール側にも干渉しないと、多分テストコード書いた上でいつもの「単体テスト」も実施する羽目になる。

おしまい

トラディショナルな現場で脱レガシー、というか生まれた瞬間からレガシー化していく事象と戦っている人はたくさんいて、テストコード書きたいしリリース頻度も上げたいけど、そもそもテストコードを書く技術とかCI環境とか、そういう技術的な話以前の壁が険しくてつらいね、というお話。

Sierとか大企業の内製とかでこういう呪縛を脱した事例を知りたい。
テストコードの書き方は勉強できるし教えれるけど、この壁に対して現場のエンジニアレベルでどう戦っていいのかわからん…

あとこういう事象はエンプラ界隈だと常識だと思うけど、Web系とか自社開発系だと驚愕の事実だったりするんだろうか。