私はボードを2つのフォーマット、すなわちlong positionID
とbyte[][] board
で表すミニチェッカーを書いた。以前は保存するのが安く、後者を表現/操作する方が簡単です。変換自体は簡単です(下のコードを参照)。テスト駆動開発。メソッドが作成される前に、この変換の単体テストを書く方法は?
TDDは「1つのテストを書き留めてから、実動コードを書く」と述べています。表現変換でこれをどのように行うべきですか?
assertEquals(0L, toIndex(new byte[6][6]))
のようなユニットテストは、それほどのカバレッジを提供しません。 Long myPosID = 42L; assertEquals(myPosID, toIndex(toBoard(myPosID))
のテストでは、大きな価値はありません。テスト全体の範囲は永遠にかかるでしょう。いくつかのランダムなmyPosID
値(モンテカルロシミュレーション)の単体テストを実行する方が良いようですが、合格テストでさえ意味はありません。
TDDでどのように行う必要がありますか?
/*
This class manipulates checkers board representation. Position is stored as long and represented as byte[height][width] board.
For board representation white = 0, black = 1, empty = 2.
Long positionID to byte[][] board:
get ternary numeral system representation of positionID, place positional values to corresponding squares.
For conversion from byte[][] board to long positionID:
long positionID = 0; for each (byte playableSquare : board){playable square positionID = positionID*3. positionID+= playableSquare}
*/
public final int boardHeight = 6;
public final int boardWidth = 6;
public long toIndex(byte[][] board) {
byte coords[] = new byte[boardHeight * boardWidth/2];
int totalSquares = boardHeight * boardWidth/2;
byte k = 0;
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth/2; j++) {
byte makeItCheckers = (byte) ((i + 1) % 2);
coords[k] = board[i][j * 2 + makeItCheckers];
k++;
}
}
long positionID = 0;
for (int i = totalSquares - 1; i >= 0; i--) {
positionID = positionID * 3 + coords[i];
}
return positionID;
}
public byte[][] toBoard(long positionID) {
int totalSquares = boardHeight * boardWidth/2;
int[] coords = new int[totalSquares];
for (int i = 0; i < totalSquares; i++) {
coords[i] = (int) (positionID % 3L);
positionID = positionID/3L;
}
byte[][] board = new byte[boardHeight][boardWidth];
Arrays.fill(board, 2);
byte k = 0;
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth/2; j++) {
byte makeItCheckers = (byte) ((i + 1) % 2);
board[i][j * 2 + makeItCheckers] = (byte) coords[k];
k++;
}
}
return board;
}
はい、TDDでは、最初に失敗したテストを書き、次にテストに合格するプロダクションコードを書きます。私は最初に自分のコードを書いた。今私はTDDのように見えるだろうと思っています。彼らは最初に変換機能やテストを持っていなかったでしょう。彼らはテストを書くだろう。テストはどのように見えますか? – Stepan
TDDを行う場合、必要とするすべての処理を事前に知っているわけではありません。アプリケーションには、まずビジネス要件がTDDでコード化されます。ノーマル:最初のビジネスニーズから始め、テストの作成と実装を始めます。開発中は、より細かいニーズや技術的な要件が発生します(ここでは、データをフォーマットから別のフォーマットに変換します)、最初のビジネスニーズを満たすにはそれを取得する必要があります。だからあなたはTDDでそれらを指定します。 – davidxxx
この論理を私の質問に適用します。私はTESTを必要とし、後で、 'Long positionID'の十進数表現から三項数値システムに行く方法を" for positionID'の三進数表現で対応する位置の各四角値に割り当てます。このテストを書くには?それは何もカバーしていません(0L、1L、2Lをチェックし、 "私たちは合格!"と言っています - テストとトリッキーな大学を意味しませんでした)。メソッド自体は簡単です。しかし、テストがとても難しい場合は、TDDのポイントは何ですか? – Stepan