下準備
テストドライバの導入
第07回目分のテストドライバを導入する。以下の手順で行う。
- ダウンロード のページを開く (ここをクリック)
- プロジェクト「java20XX」にある「test」の左側の「+」をクリック
- ツリーが展開されるので「install-libraries.xml」を右クリック
- 「実行(R)」にマウスカーソルを合わせる
- 「1 Ant ビルド」をクリック
- 「コンソール」タブに"BUILD SUCCESSFUL"と表示されれば成功
- eclipseの画面でプロジェクト「java20XX」を右クリック
- メニューが表示されるので、「更新」あるいは「最新表示」をクリック
- "week07.zip" をデスクトップなどにダウンロード
- eclipseの画面でプロジェクト「java20XX」を右クリック
- メニューから「インポート(I)」を選択
- 「インポート」ウィンドウが表示されるので、「Zip ファイル」を選択
- 「次へ(N)」をクリック
- 宛先フォルダー(L): が「java20XX」になっていることを確認
- From archive file: の右側にある 「参照(R)...」あるいは「ブラウズ(R)...」をクリック
- ファイルダイアログが表示されるので、ダイアログ内に表示されたダウンロードしたファイルをダブルクリック
- 前の画面に戻るので、From archive file: のエリアに正しいパスが入力されていることを確認
- フォルダ「/」の左にチェックがついていることを確認 (ついていなければチェックボックスをクリック)
- 「警告を出さずに既存リソースを上書き」にチェックがついていることを確認 (上書きしたくないファイルがある場合はチェックを外す)
- 「終了 (F)」をクリック
第07週目テストドライバの導入に成功すると、java20XX プロジェクトの test フォルダに j1.lesson07.xml というファイルが作成される。
パッケージの作成
過去の演習を参考にして、「j1.lesson07」というパッケージを作成する。
演習の前に
今週より「骨格テスト」の内容が変わる。今までは以下のようなことを行っていた。
- クラス
- クラスは存在するか
- mainメソッド
- mainメソッドは存在するか
- public static void ... で宣言されているか
- throws IOException が必要なら付いているか
今週からは、main以外のメソッドについても正当性が検証される。よって、骨格テストを実行するタイミングは、「クラスとその中に必要な全てのメソッドを宣言した後」になる。
また、「骨格テスト」「機能テスト」の他に「単体テスト」というものを取り入れる。単体テストとは、それぞれのメソッドが単独で呼び出された際に、正しい動作を行ってくれるかどうかを調べるものである。このテストによって、どのメソッド内で問題が発生したかなど、プログラムの誤りをより特定しやすくなる。
メソッドを使ったプログラム
main以外のメソッドを用い、より効率のよいプログラムを作成する。
演習
クラスの作成
以下の手順で、パッケージ「j1.lesson07」に「Print3Method」クラスを作成する。
- 先ほど作成したパッケージ 「j1.lesson07」の上で右クリック
- マウスカーソルを「新規」に合わせる
- 「クラス」をクリック
- クラス名は Print3Method とする
- 先週までと同じ手順でクラスを作成する
mainメソッドの作成
クラス「Print3Method」内にpublic static void main(String[] args) から始まるメソッドを作成する。
printHello メソッドの作成
クラス「Print3Method」内に 「printHello」という名前を持ち、仮引数が何もないメソッドを作成する。骨格だけでよいのでメソッドの中身は空でよい。
printBye メソッドの作成
クラス「Print3Method」内に 「printBye」という名前を持ち、仮引数が何もないメソッドを作成する。骨格だけでよいのでメソッドの中身は空でよい。
全体の骨格
ここまでのプログラムの骨格は以下のようになる。
package j1.lesson07; public class Print3Method { public static void main(String[] args) { } public static void printHello() { } public static void printBye() { } }
main メソッドのほかに、printHello, printBye メソッドを作成している。
骨格テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
「Print3Method に対する骨格テスト」 を実行する。
骨格テストを行った際に緑のバーが表示されれば、外側から見たプログラムの骨格は正しくなっている。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「実行」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
(クラス名), existence | j1.lesson07 に Print3Method クラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
メソッドの実装 (printHello)
メソッド printHello を実装する。このメソッドは、実行されると Hello! と表示した後に改行を行う。
public static void printHello() { System.out.println("Hello!"); }
メソッドの実装 (printBye)
メソッド printBye を実装する。このメソッドは、実行されると Bye. と表示した後に改行を行う。
public static void printBye() { System.out.println("Bye."); }
単体テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
mainメソッド内に各メソッドを呼び出すプログラムを書いてみる。例えば以下の様な形。
public static void main(String[] args) { printHello(); printBye(); }
このプログラムを実行し、各メソッドが期待通りに動いていることを確認する。確認したら、mainメソッドの中身は空にして良い。
「Print3Method に対する単体テスト」 を実行する。
単体テストを行った際に緑のバーが表示されれば、各メソッドはある程度正しく作成されていると思われる。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「実行」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
(メソッド名), 期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。下記のテスト項目を参照 |
テスト項目は以下の通りである。
項目名 | 詳細 |
---|---|
testInvoke_printHello | printHello を起動した |
testInvoke_printBye | printBye を起動した |
main メソッドの実装
続けて、先ほど作成した Print3Method クラスのmainメソッドの中身を記述する。mainメソッドでは、printHelloを3回起動した後に、printByeを1回だけ起動する。
全体的には下記のようなプログラムにする。ただし、一文書くごとにCtrl+Sで保存とコンパイルを行い、常に文法エラーが発生していないことを確認すること。
package j1.lesson07; public class Print3Method { public static void main(String[] args) { printHello(); printHello(); printHello(); printBye(); } public static void printHello() { System.out.println("Hello!"); } public static void printBye() { System.out.println("Bye."); } }
プログラムの実行
先週までと同じ手順でプログラムを実行する。
実行が成功すると、以下のように表示される。
Hello! Hello! Hello! Bye.
機能テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
「Print3Method に対する機能テスト」 を実行する。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「実行」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。 |
機能テストの項目
項目名 | テストの内容 |
---|---|
testRun | プログラムを実行 |
解説
解説のために、プログラムに行番号をつけて解説する。
01: package j1.lesson07; 02: 03: public class Print3Method { 04: 05: public static void main(String[] args) { 06: printHello(); 07: printHello(); 08: printHello(); 09: printBye(); 10: } 11: 12: public static void printHello() { 13: System.out.println("Hello!"); 14: } 15: 16: public static void printBye() { 17: System.out.println("Bye."); 18: } 19: }
- 6行目
- メソッド printHello() を呼び出す
- 7行目
- メソッド printHello() を呼び出す
- 8行目
- メソッド printHello() を呼び出す
- 9行目
- メソッド printBye() を呼び出す
- 10行目
- (プログラムの終了)
- 12行目
- メソッド printHello() を宣言
- 13行目
- "Hello!" と表示
- 16行目
- メソッド printBye() を宣言
- 17行目
- "Bye." と表示
引数を伴ったメソッドを使ったプログラム
1から9をそれぞれ10倍したものを表示する。また、1から9をそれぞれ2乗したものを表示する。
演習
クラスの作成
以下の手順で、パッケージ「j1.lesson07」に「PrintMult」クラスを作成する。
- 先ほど作成したパッケージ 「j1.lesson07」の上で右クリック
- マウスカーソルを「新規」に合わせる
- 「クラス」をクリック
- クラス名は PrintMult とする
- 先週までと同じ手順でクラスを作成する
main メソッドの作成
クラス「PrintMult」内にpublic static void main(String[] args) から始まるメソッドを作成する。
printMult メソッドの作成
クラス「PrintMult」内に「printMult」という名前を持ち、仮引数に2つのint型の変数をとるメソッドを作成する。
仮引数の名前は何でも良いが、ここでは順に a, b という名前をつけることにする。
printSquare メソッドの作成
クラス「PrintMult」内に「printSquare」という名前を持ち、仮引数に1つのint型の変数をとるメソッドを作成する。
仮引数の名前は何でも良いが、ここでは a という名前をつけることにする。
全体の骨格
ここまでのプログラムの骨格は以下のようになる。どんなものを作成するかイメージを与えるため、コメントをつけている。
package j1.lesson07; public class PrintMult { public static void main(String[] args) { // 1 から 9 をそれぞれ 10 倍したものを表示 // 1 から 9 をそれぞれ 2 乗したものを表示 } // 与えられた 2 つの整数に対して、その積を表示 public static void printMult(int a, int b) { } // 与えられた整数に対して、その 2 乗を表示 public static void printSquare(int a) { } }
骨格テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
「PrintMult に対する骨格テスト」 を実行する。
骨格テストを行った際に緑のバーが表示されれば、外側から見たプログラムの骨格は正しくなっている。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「Run」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
(クラス名), existence | j1.lesson07 に Print3Method クラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
メソッドの実装 (printMult)
メソッド printMult を実装する。このメソッドは、与えられた 2 つの整数に対して、その積を以下のように表示するメソッドである。
a * b = c
ただし、a, b にはそれぞれ引数に与えられた値、c には a と b の積を計算した結果が入っているものとする。
メソッドの実装 (printSquare)
メソッド printMult を実装する。このメソッドは、与えられた 1 つの整数に対して、その二乗の値を以下のように表示するメソッドである。
a * a = c
ただし、a には引数に与えられた値、c には a の二乗を計算した結果が入っているものとする。
単体テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
mainメソッド内に各メソッドを呼び出すプログラムを書いてみる。例えば以下の様な形。
public static void main(String[] args) { printMult(2, 3); printSquare(10); }
このプログラムを実行し、各メソッドが期待通りに動いていることを確認する。確認したら、mainメソッドの中身は空にして良い。
「PrintMult に対する単体テスト」 を実行する。
単体テストを行った際に緑のバーが表示されれば、各メソッドはある程度正しく作成されていると思われる。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「実行」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
(メソッド名), 期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。下記のテスト項目を参照 |
テスト項目は以下の通りである。
項目名 | 詳細 |
---|---|
testPrintMult_M1_M1 | printMult を実引数 (-1, -1) で起動した |
testPrintMult_0_100 | printMult を実引数 (0, 100) で起動した |
testPrintMult_5_7 | printMult を実引数 (5, 7) で起動した |
testPrintSquare_1 | printSquare を実引数 (1) で起動した |
testPrintSquare_M1 | printSquare を実引数 (-1) で起動した |
testPrintSquare_10 | printSquare を実引数 (10) で起動した |
プログラムの作成
続けて、先ほど作成したPrintMultクラスのmainメソッドの中身を記述する。main メソッドでは、i = {1..9} においてprintMultを実引数 (10, i) で順番に起動したあとに、i = {1..9} においてprintSquareを実引数 (i) で順番に起動する。
全体的には下記のようなプログラムにする。ただし、一文書くごとにCtrl+Sで保存とコンパイルを行い、常に文法エラーが発生していないことを確認すること。
package j1.lesson07; public class PrintMult { public static void main(String[] args) { // 1 から 9 をそれぞれ 10 倍したものを表示 for (int i = 1; i <= 9; i++) { printMult(10, i); } // 1 から 9 をそれぞれ 2 乗したものを表示 for (int i = 1; i <= 9; i++) { printSquare(i); } } // 与えられた 2 つの整数に対して、その積を表示 public static void printMult(int a, int b) { int c = a * b; System.out.println(a + " * " + b + " = " + c); } // 与えられた整数に対して、その 2 乗を表示 public static void printSquare(int a) { printMult(a, a); } }
プログラムの実行
先週までと同じ手順でプログラムを実行する。
実行が成功すると、以下のように表示される。
10 * 1 = 10 10 * 2 = 20 10 * 3 = 30 10 * 4 = 40 10 * 5 = 50 10 * 6 = 60 10 * 7 = 70 10 * 8 = 80 10 * 9 = 90 1 * 1 = 1 2 * 2 = 4 3 * 3 = 9 4 * 4 = 16 5 * 5 = 25 6 * 6 = 36 7 * 7 = 49 8 * 8 = 64 9 * 9 = 81
機能テスト
ここまでの作業をCtrl+Sを押して保存し、コンパイルを行う (保存時に自動で行われる)。ここでエラーが発生していたら文法エラーなので見直す。
「PrintMult に対する機能テスト」 を実行する。
赤いバーが表示された場合、メッセージを元にプログラムを見直すこと。修正を行い、Ctrl+Sで保存した後に「実行」ボタンをクリックする。
メッセージ | 詳細 |
---|---|
無限ループの可能性 | 繰り返し部分が無限に繰り返されていないか確認 |
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較 (エラーメッセージが出力されているエリアの下のほうにあるバーをスクロールさせれば見ることができる) し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テスト失敗時のヒント
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。 |
機能テストの項目
項目名 | テストの内容 |
---|---|
testRun | プログラムを実行 |
解説
解説のために、プログラムに行番号をつけて解説する。
01: package j1.lesson07; 02: 03: public class PrintMult { 04: 05: public static void main(String[] args) { 06: // 1 から 9 をそれぞれ 10 倍したものを表示 07: for (int i = 1; i <= 9; i++) { 08: printMult(10, i); 09: } 10: 11: // 1 から 9 をそれぞれ 2 乗したものを表示 12: for (int i = 1; i <= 9; i++) { 13: printSquare(i); 14: } 15: } 16: 17: // 与えられた 2 つの整数に対して、その積を表示 18: public static void printMult(int a, int b) { 19: int c = a * b; 20: System.out.println(a + " * " + b + " = " + c); 21: } 22: 23: // 与えられた整数に対して、その 2 乗を表示 24: public static void printSquare(int a) { 25: printMult(a, a); 26: } 27: }
- 7行目
- 以下の条件で繰り返しを開始する
- int 型の変数 i を宣言し、初期値を1に設定する
- 毎回の繰り返しの最初に i <= 9 が成立するか調べ、成立しなければ繰り返しを終了する (10行目へジャンプ)
- 毎回の繰り返しの最後に、iの値を1だけ増やす
- 8行目 (7行目から始まるforループの中身)
- 引数にそれぞれ 10 と i を入れ、メソッド printMult(int, int) を呼び出す
- 12行目
- 以下の条件で繰り返しを開始する
- int 型の変数 i を宣言し、初期値を1に設定する
- 毎回の繰り返しの最初に i <= 9 が成立するか調べ、成立しなければ繰り返しを終了する (15行目へジャンプ)
- 毎回の繰り返しの最後に、iの値を1だけ増やす
- 13行目 (12行目から始まるforループの中身)
- 引数に i を入れ、メソッド printSquare(int) を呼び出す
- 15行目
- (プログラムの終了)
- 18行目
- メソッド printMult(int, int) を宣言
- 19行目
- int型の変数 c を宣言
- c の中身を a * b で初期化
- 20行目
- 以下を結合したものを表示
- a (整数型の第1引数)
- 文字列 " * "
- b (整数型の第2引数)
- 文字列 " = "
- c (a * b の結果)
- 24行目
- メソッド printSquare(int) を宣言
- 25行目
- 引数にそれぞれ a を入れ、メソッド printMult(int, int) を呼び出す