xUnit Test Patternsの直接入力と間接入力って何?
出典
xUnit Test Patterns
Summary
- どこから入力値を受取るかの違いで直接、間接と呼称が別れている
- 間接入力の多くはテストスタブを用いることになる
用語
-
SUT: System Under Test
和訳は「テスト対象システム」や「被試験システム」。テスト対象のこと。
http://xunitpatterns.com/SUT.html -
Test Double
和名は「テストダブル」で読みのまま。テスト対象が依存するコンポーネントのうち、そのテストのために仮のものに置き換えたオブジェクトの総称。役割やふるまいに応じてスタブとかスパイとかなんとか、合計で 5 種類ある。
http://xunitpatterns.com/Test Double.html -
direct input
和訳は「直接入力」
http://xunitpatterns.com/direct input.html -
indirect input
和訳は「間接入力」
http://xunitpatterns.com/indirect input.html
解説
直接入力
ざっくり訳
テスト対象の動作に影響のあるパラメータのうち、(public メソッドの引数とか)からの入力などの外部から受取可能と公開している情報(フロントドア)と、メソッド内部で呼び出している他コンポーネントからの戻り値などの外部に対して隠蔽されている情報(バックドア)とがある。前者を直接入力と言う。
原文、および機械翻訳
A test may interact with the system under test (SUT) directly (via it's "front door" or public API) or indirectly via it's "back door". We call the stimuli injected by the test into the SUT via its front door direct inputs of the SUT. Direct inputs may be method or function calls to another component or messages sent on a message channel (e.g. MQ or JMS) and the arguments or contents thereof.
テストは、被試験システム(SUT)と直接(「フロントドア」または公開 API 経由で)相互作用することも、「バックドア」経由で間接的に相互作用することもある。テストがフロントドアを介して SUT に注入する刺激を、SUT の直接入力と呼ぶ。直接入力は、他のコンポーネントに対するメソッドまたは関数呼び出し、あるいはメッセージチャネル(例: MQ または JMS)上で送信されるメッセージ、およびその引数または内容である。
:::
サンプルコード
// SUT: 被試験対象のクラス
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
// テストコード
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class CalculatorTest {
@Test
public void testAdd() {
// 直接入力: addメソッドを呼び出してSUTに直接値を渡す
Calculator calculator = new Calculator();
int result = calculator.add(3, 5);
// 検証: 期待値と実際の値を比較する
assertEquals(8, result);
}
@Test
public void testSubtract() {
// 直接入力: subtractメソッドを呼び出してSUTに直接値を渡す
Calculator calculator = new Calculator();
int result = calculator.subtract(7, 4);
// 検証: 期待値と実際の値を比較する
assertEquals(3, result);
}
}
間接入力
ざっくり訳
試験対象内のロジックで、他のコンポーネントから入力を受け付けていてその影響を受ける場合、その入力のことを関節入力と言う。間接入力には他のコンポーネントが返す戻り値、他のコンポーネントの処理によって変更されたパラメータ、他のコンポーネントが発生させるエラーまたは例外が該当する。試験対象内の他のコンポーネントは、言わばテスト対象の裏側で動いているため、適切な制御が必要である。多くの場合はテストスタブを用いて間接入力を行う。
原文、および機械翻訳
When the behavior of the system under test (SUT) is affected by the values returned by another component whose services it uses, we call those values indirect inputs of the SUT. Indirect inputs may be actual return values of functions, updated (out) parameters of procedures or subroutines, and any errors or exceptions raised by the depended-on component (DOC). Testing of the SUT behavior with indirect inputs requires the appropriate control point on the "back side" of the SUT. We often use a Test Stub to inject the indirect inputs into the SUT.
被試験システム(SUT)の動作が、そのサービスを使用する他のコンポーネントから返される値によって影響される場合、その値を SUT の間接入力と呼ぶ。間接入力は、関数の実際の戻り値、手続きまたはサブルーチンの更新された(out)パラメータ、および依存コン ポーネント(DOC)が発生させるエラーまたは例外である。間接入力による SUT 動作のテストには、SUT の「裏側」にある適切な制御点が必要である。多くの場合、テストスタブを使用して、間接入力を SUT に注入します。
サンプルコード
// SUT: 被試験対象のクラス
class DataProcessor {
private DataService dataService;
public DataProcessor(DataService dataService) {
this.dataService = dataService;
}
public int process() {
int data = dataService.getData();
// データを処理する複雑なロジックがここにあると想定します
return data * 2;
}
}
// 依存コンポーネント(Depended-On Component)
class DataService {
public int getData() {
// 仮にここでは簡単なデータを返すとします
return 42;
}
}
// テストコード
public class DataProcessorTest {
public static void main(String[] args) {
// テストスタブを使用してテストを実行
DataService stubbedDataService = new TestDataStub();
DataProcessor sut = new DataProcessor(stubbedDataService);
int result = sut.process();
// テストスタブが提供したデータに基づいて期待される結果を確認
assert result == 20;
}
}
// テストスタブ
class TestDataStub extends DataService {
@Override
public int getData() {
// テストの際に注入するデータをここで定義
return 10;
}
}
感想
紐解くと概念自体は簡単だけども、表現として十分な認知があるかというと怪しい気がする。
なので自分の理解の助けのため、脳内でメンタルモデルを構築するために留め、他の人と
コミュニケーションを取るときはその場に応じて分かりやすい言葉を選んだほうが良いと思う。
Discussion