上海で実演したテストケースの方針(メモ)

上海出張して、NUnit の作り方を教え/実演してきました。

日本だと google で調べればそれなりに出てくるし「テスト技法」の本を読めば、それなりに分かるんですが、上海チームではそのあたりの資料が不足しております…という訳で、テストを作るときのメモを残しておきます。

■テストコードを書く手順

TDD(テスト駆動)を正確にやるためには、テストコード作成後、実コード(=テスト対象のコード)を書く、という手順になるのですが、時間的な制約やテストコードの記述の慣れ、テストケースの作り方の慣れ≒理解度、もあるので、まぁ、「実コードを書いてからテストコードを書いても構いません」という方針で説明しました。

その中で、ひとつルールとして守ってほしいのは、以下のひとつだけ。

「コードを書いたら、その日のうちにテストコードを書いて確認することッ!!!」

テストコード初心者がやりがちなのは、大量の実コードを書いた後に大量のテストコードを書くことです。全ての実コードを書いた後では、テストコードを書くと、時間が経ってしまっているのでテストが通らないときのデバッグに時間が掛かるし、開発の工数が少ないときにはテストコード自体がばっさり省略されてしまうことがあります。
なので、これを避けるために、その日のうちにテストコードを書いて確認します。
例えば、実コードを15分で書いたらテストコードを1時間という感じ。テスト自体は動作確認を兼ねるので、長めに時間を取ると良いでしょう。慣れれば、実コード 30 分、テストコード 30 分、的な配分も可能です。

■テストコードは省略可能である

QA(品質システム)としては、網羅性テストをしたほうが良いのですが、プロジェクトの状況によっては、網羅性よりも実品質を優先させます。いわゆる、QCD の Delivery を優先させるために、テストの Quality を落とします。
ええ、勿論、製品自体の Quality も落ちるので、そのバランスは大切です。

■テストコードを書く順番

これらを踏まえて、実コードに対してテストコードを書いていきます。

以下は、私の経験を踏まえた順番です(私自身の実コードの癖もあるので、それぞれ自分にあった形で進めてください)。

今回は、SQL 文を内部に持つ DAO(Data Access Object)のテストを例にとります。

0) TestZero

動作確認用のコードを書きます。

1) TestOK

正常動作ができるコードをひとつだけ書きます。

2) TestNG

TestOK とは反対の、エラーになるコードをひとつだけ書きます。

3) TestMulti

TestOK を利用して、複数行呼び出しのテストコードを書きます。

4) TestSelect

TestMulti を利用して、複数行から1行だけ取り出す選択のコードを書きます。

5) TestOrderBy

TestMulti を利用して、insert する順序を逆にしても正常に取れかテストします。

6) TestWhere

TestSelect を利用して、選択時のパラメータを変更させます。

7) TestJoin

TestMulti を利用して LEFT OUTER JOIN が意図通りに動いているかをチェックします。

8) TestMultiCall

TestOK, TestMulti を利用して、実コードを2回以上呼び出しても、問題ないことを確認します。

大体、こんな流れで作ると、単純なパターンから複雑なパターンにテストコードを書き進めることができます。
単純なコードがうまく動いていないと、複雑なパターンは動きませんからね。

実コードの複雑度によって、適度に省略しても構いません。

ちなみにテスト技法的な名前をつけると以下になります。

0) 動作確認
1) 正常系(単数)
2) 異常系(単数)
3) 正常系(複数)
4) 選択性(境界値)
5) 順序性
6) 条件選択(パラメータ指定)
7) 連結、他データとの関連
8) 複数回呼び出し(単一性)

# 正確な名前かどうかはさておき、こんな感じで網羅ができます。

■テストデータの作り方

テストするときのデータは、できるだけわかりやすいものにします。
例えば、業務に即したデータ(ID を “MSD02AX001” のようにするとか)を使う必要はありません。
むしろ、テストの邪魔になります。

正常系のID: “001” or 1
異常系のID: “999” or 999
正常系の名前: “masuda”
異常系の名前: “XXXXXX”

のように違っているとことが分かるように付けます。

// 正常系
public void TestOK() {
	obj.SetData("...")
	string id = obj.GetUserID();
	Assert.AreEqual( "masuda", id );
}

// 異常系
public void TestNG() {
	obj.SetData("...")
	string id = obj.GetUserID();
	Assert.AreEqual( "XXXXXX", id );
}

あと、テストデータを参照させるときは、【できる限り変数を使わないようにします】

// 即値を使う
public void TestOK() {
	obj.SetData("masuda")
	string id = obj.GetUserID();
	Assert.AreEqual( "masuda", id );
}

下記のように変数をつかってはいけません。

// 変数に入れてはいけない。
public void TestOK() {
    string TESTID = "masuda";
	obj.SetData( TESTID )
	string id = obj.GetUserID();
	Assert.AreEqual( TESTID , id );
}

変数に入れると、どれが正しいデータなのかが分かりづらくなります。
また、基本的にテストデータはコピー&ペーストで作るので、コピーした後にテストデータを手軽に変更することができなくなります。

という訳で、もろもろのメモを up しておきます。
整理するのは後ほど(時間があれば)。

カテゴリー: 開発, xUnit パーマリンク