2013年7月26日金曜日

Title

StackEditで投稿テスト

ChromeアプリのStackEditなら、Markdownで描いてbloggerに投稿できるらしいので、 試してみます。

StackEditは以下を参照してください。

Written with StackEdit.

2012年11月2日金曜日

JUnit入門―導入・実行編(Ant ver.)

今回はJUnitをAntから使うための環境について試してみます。

使用している環境は以下の通りです。
それぞれ、JDK・JUnitは導入済みとします。
・Windows 7 SP1
・JDK 1.7.0 (64bit ver.)
・JUnit 4.10
・Antの導入
Antとは、Javaベースのビルドツールの1つで、build.xmlというファイルにxml形式で目的ごとの処理を記述していきます。
導入の方法としては、バイナリを手に入れる方法とソースからビルドする方法があります。
ここでは、バイナリを使用する方法について説明します。
まず、Antのバイナリを以下のページからzipファイルをダウンロードします。
http://ant.apache.org/bindownload.cgi
zipファイルを適当なところに展開しておきます。
次に環境変数を設定します。
設定の必要があるのは、以下の3つです。
JAVA_HOME ・・・JDKがインストールされているフォルダ。
ANT_HOME ・・・Antがインストールされているフォルダ
PATH ・・・Antの実行ファイルがあるフォルダを追加する。ANT_HOME以下のbinに実行ファイルがある
以上で導入は完了です。
コマンドプロンプトを開いて、以下のコマンドを実行したときにバージョン番号等が表示されればOKです。
ant -version
・1分で分かった気になるAnt
Antでは、「ビルドする」・「テストする」などの目的を「ターゲット」、目的を達成するために実行する「フォルダを作成する」・「javacを実行する」などの個々の処理を「タスク」と呼んでいて、ターゲットごとにいくつかのタスクを実行します。
以下がbuild.xmlの簡単なサンプルです。


これは「SimpleAnt」という名前のプロジェクトのためのbuild.xmlで、「compile」「test」という2つのターゲットを持っています。
「compile」と「test」のそれぞれのターゲットでは、「echo」というタスクを実行するように指定しています。
このタスクは文字列を表示するだけの単純なタスクです。
2行目でデフォルトを「compile」に指定しているため、ターゲットを指定せずにAntを実行した場合、自動的に「compile」ターゲットのタスクを実行します。
実行するときは、build.xmlがあるフォルダでantコマンドを実行します。
C:\Users\siguremon>ant
Buildfile: C:\Users\siguremon\build.xml
compile:     [echo] compileだけど表示するだけで何もしない
BUILD SUCCESSFULTotal time: 0 seconds
また、「test」ターゲットでは6行目で依存関係に「compile」を指定しています。
そのため、Antで「test」を指定して実行すると、以下のように「test」のタスクの前に「compile」のタスクが実行されます。
C:\Users\siguremon>ant test
Buildfile: C:\Users\siguremon\build.xml
compile:     [echo] compileだけど表示するだけで何もしない
test:     [echo] testだけど表示するだけで何もしない
BUILD SUCCESSFULTotal time: 0 seconds
・JUnitを使うためのbuild.xmlの記述
AntからJUnitを使うためには、3つのポイントがあります。
  1. junitタスクを使ってテストを実行する (単一のテストクラスを指定)
  2. junitタスクを使ってテストを実行する (複数のテストクラスを指定)
  3. junitreportタスクを使ってテストの実行結果を整形する
1.junitタスクを使ってテストを実行する(単一のテストクラスを指定)
単一のテストクラスを指定する場合には、以下のように<test>プロパティを使います。
この場合、my.test.TestCaseがテストクラスです。

<junit printsummary="yes" fork="yes" haltonfailure="yes">
  <formatter type="plain" />
  <test name="my.test.TestCase" />
</junit>
その他、<formatter>プロパティでjunitの出力形式を指定しています。

2.junitタスクを使ってテストを実行する(複数のテストクラスを指定)

複数のテストクラスを指定する場合には、以下のように<batchtest>プロパティを使います。
<batchtest>プロパティの中では、filesetでテストクラスを指定します。

<junit printsummary="yes" haltonfailure="yes">
  <classpath>
    <pathelement location="${build.tests}" />
    <pathelement path="${java.class.path}" />
  </classpath>

  <formatter type="plain" />

  <batchtest fork="yes" todir="${reports.tests}">
    <fileset dir="${src.tests}">
      <include name="**/*Test*.java" />
      <exclude name="**/AllTests.java" />
    </fileset>
  </batchtest>
</junit>

3.junitreportタスクを使ってテストの実行結果を整形する

junitの実行結果は上でも少し触れましたが、<formatter>プロパティで指定することができます。
デフォルトでは"plain"、"brief”、"xml"の3つを指定することができます。
しかし、junitreportタスクを使うとさらに結果を見やすくすることができます。
このタスクを使うためには、junitの<formatter>プロパティで"xml"を指定する必要があります。
その上で、出力結果ファイルを<fileset>で指定し、<report>で最後に出力します。
<junitreport todir="./reports">
  <fileset dir="./reports">
    <include name="TEST-*.xml"/>
  </fileset>
  <report format="frames" todir="./report/html"/>
</junitreport>
・サンプル
以下にサンプルを置きました。
複数のテストクラスを実行し、junitreportで整形した出力結果を作成しています。
https://github.com/siguremon/AntExample/tree/simpleant
・参考
Ant | TECHSCORE(テックスコア)
JUnit Task
JUnitReportタスク

2012年4月7日土曜日

JUnit入門―導入・実行編(コンソールver.)


今回は、JUnitをコンソールから使うための環境作りについて試してみます。
ここでは、JDKはすでにインストールされているものとします。
JDKのインストールについては、以下のページなどを参考にしてみてください。

http://www.javadrive.jp/install/jdk/

使用している環境は以下の通りです。
・Windows 7 SP1
・JDK 1.7.0 (64bit ver.)

・JUnitの導入

まず、JUnitのJarファイルなどをダウンロードします。

現時点(2012/3)での最新版である4.10は、github上にあります。
github上には、4.7までのJUnitをダウンロードすることができるようになっています。
https://github.com/KentBeck/junit/downloads

それより以前のバージョンのものはsorceforgeにあります。
よく見ると、sorceforge上にも4.10まであるようです。
http://sourceforge.net/projects/junit/files/junit/

上記ページから、zipファイルかtarファイルをダウンロードして、適当なところに展開します。
ここでは比較のため、4.10と3.8.1をダウンロードします。
それぞれ、「junit4.10」、「junit3.8.1」というディレクトリに展開すると、各ディレクトリ直下に「junit-4.10.jar」または「junit.jar」があります。

・テストの実行

3.x系と4.x系で実行の仕方が大きく異なります。

3.x系

3.x系では、CUIで実行する方法・swingのGUIで実行する方法・awtのGUIで実行する方法の3週類があります。
ここでは、junitに付属しているサンプルをそれぞれの方法で実行してみます。

1.CUIで実行する方法

先程展開したディレクトリで、以下のコマンドを実行します。

\junit3.8.1> java -cp junit.jar;. junit.textui.TestRunner junit.samples.SimpleTest

junit.texui.TestRunnerというものがテストクラス実行のためのクラス(テストランナー)になります。
その後に、テストクラス名を引数で指定します。
テストクラスは1つしか指定できないようです。
実行結果は以下のようになります。

.E.F.F
Time: 0.002
There was 1 error:
1) testDivideByZero(junit.samples.SimpleTest)java.lang.ArithmeticException: / by zero
        at junit.samples.SimpleTest.testDivideByZero(SimpleTest.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
There were 2 failures:
1) testEquals(junit.samples.SimpleTest)junit.framework.AssertionFailedError: Size expected:<12> but was:<13>
        at junit.samples.SimpleTest.testEquals(SimpleTest.java:56)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
2) testAdd(junit.samples.SimpleTest)junit.framework.AssertionFailedError
        at junit.samples.SimpleTest.testAdd(SimpleTest.java:45)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
FAILURES!!!
Tests run: 3,  Failures: 2,  Errors: 1

3つのテストケースを実行して、検証の失敗(Failures)が2つ、実行時のエラー(Errors)が1つという結果になっています。
失敗とエラーの違いは、assertionによる例外か、それ以外の例外かというものです。

2.swingのGUIで実行する方法

先程と同様にjunitのディレクトリで、以下のコマンドを実行します。

\junit3.8.1> java -cp junit.jar;. junit.swingui.TestRunner junit.samples.SimpleTest

すると、以下のようなGUIが表示されます。



結果は先ほどと同様ですが、中央に赤いバーが表示されていて、結果を視覚的に確認することができます。
また、上段の「Run」ボタンを押下するとテストクラスの再実行が、中段の「Run」を押下すると各テストケースごとの実行ができます。

3.awtのGUIで実行する方法

awtの場合も、swingと同様の実行法になります。

\junit3.8.1> java -cp junit.jar;. junit.awtgui.TestRunner junit.samples.SimpleTest

すると、以下のようなGUIが表示されます。


こちらのGUIでもテストクラスの再実行とテストケースごとの実行ができるようになっています。

4.x系

4.x系では、3.x系のようなGUIのテストランナーのクラスは用意されていません。
さらに、コマンドライン上で実行するためのテストランナークラスも変更されています。
コマンドは以下の通りです。

\junit4.10> java -cp junit-4.10.jar;. org.junit.runner.JUnitCore junit.samples.SimpleTest

こちらでは「org.junit.runner.JUnitCore」というクラスがテストランナーになっています。
出力結果も若干変わっています。

JUnit version 4.10
.E.E.E
Time: 0.005
There were 3 failures:
1) testDivideByZero(junit.samples.SimpleTest)
java.lang.ArithmeticException: / by zero
        at junit.samples.SimpleTest.testDivideByZero(SimpleTest.java:54)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
2) testAdd(junit.samples.SimpleTest)
junit.framework.AssertionFailedError
        at junit.framework.Assert.fail(Assert.java:48)
        at junit.framework.Assert.assertTrue(Assert.java:20)
        at junit.framework.Assert.assertTrue(Assert.java:27)
        at junit.samples.SimpleTest.testAdd(SimpleTest.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
3) testEquals(junit.samples.SimpleTest)
junit.framework.AssertionFailedError: Size expected:<12> but was:<13>
        at junit.framework.Assert.fail(Assert.java:50)
        at junit.framework.Assert.failNotEquals(Assert.java:287)
        at junit.framework.Assert.assertEquals(Assert.java:67)
        at junit.framework.Assert.assertEquals(Assert.java:199)
        at junit.samples.SimpleTest.testEquals(SimpleTest.java:62)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
FAILURES!!!
Tests run: 3,  Failures: 3

大きな違いとしては、Errorsがなくなり、すべてFailuresに統一されている点でしょうか。
あとは、バージョン番号なんかも表示されるようになっていますね。

なお、4.x系では引数のテストクラスを複数指定することができるようになっています。
以下のように、引数にテストクラスを指定していけば、全て実行してくれます。

\junit4.10> java -cp junit-4.10.jar;. org.junit.runner.JUnitCore junit.samples.SimpleTest

2012年3月13日火曜日

JUnit入門―導入・実行編(Eclipse ver.)

まずは、JUnitを使うための環境作りについて見ていきます。
JUnitを利用するためには、IDEを利用する方法やビルドツールを利用する方法などがあります。
今回は、最も簡単な利用方法だと思われるEclipseを使った方法を試してみます。

使用している環境はPleiades All in One 3.7.2(Eclipse3.7.2をベースに日本語化したもの)です。

・JUnitの導入

Eclipseには最初からJUnitが含まれているため、インストールの必要はありません。
また、JUnitのテストクラスを実行して結果を確認するためのプラグインも含まれていて、至れり尽くせりです。
そのため、ビルドパスはJUnitのライブラリを追加して、テストクラスを作成すればすぐに実行して結果を確認することができます。

ということで、まずはプロジェクトにJUnitのライブラリを追加します。
(プロジェクトはすでにあるものとします。)
パッケージ・エクスプローラーのプロジェクトを右クリックして、「ビルド・パス→ライブラリの追加」を選択すると、以下のようなライブラリ選択画面になります。
そこで、JUnitを選択して次に進みます。

JUnitライブラリの追加(1)
次に進むと、ライブラリのバージョンを選択する画面になります。
ここではJUnit4を選択しています。
今回の環境ではJUnitのソースは含まれていないので、ソース・ロケーションが「見つかりません」となっているようです。
これで完了を押せばOKです。

JUnitライブラリの追加(2) バージョンの選択

・テストの実行

JUnitライブラリの準備ができたので、次にテストクラスを作って実行してみます。
テストクラスの作成も、IDEによるサポートがあるため、簡単に作ることができます。

ここではテスト対象のクラスとして、以下のCalcクラスがプロジェクトに含まれているとします。


パッケージ・エクスプローラー上のCalcクラスを右クリックして、「新規→JUnitテスト・ケース」と選択すると、以下のテスト・ケース作成画面になります。
この時点で、一通りのデフォルト値が入力された状態になっています。
名前はテスト対象のクラスに”Test”と付けたものになり、テスト元クラスが先程のCalcクラスになっています。
クラスを選択せずに新規作成すると、名前やテスト元クラスのデフォルト値は空になります。

また、メソッドのスタブを作成するかどうかもここで選ぶことができます。
以下の画面では、setUpメソッドとtearDownメソッドを選択しています。

JUnitテスト・ケース(テストクラス)の追加

次に進むと、テストの対象とするメソッドを選択する画面になります。
テスト対象クラスのメソッド一覧が表示されているので、どれをテストするかを選択します。
以下の画面では、Calcクラスのsumメソッドのみを選択しています。
これで完了を押すと、テストクラスがプロジェクトに追加されます。

JUnitテスト・ケースでの対象メソッド選択
追加されたテストクラスは以下のようなものになっているはずです。(画像右側のCalcTest.java)
setUp、tearDown、testSumの3つのメソッドがあります。
テストメソッドは、対象のメソッド名の前に”test”と付けた名前になります。
中身はまだ実装されていないので、必ず失敗するコードが書かれています。

このテストクラスを実行するためには、メニューから「実行→実行」を選択します。
もしくは「Ctrl+F11」でも実行できます。
実行すると、左側にJUnitの実行結果が現れます。
今回は1つのテストケース(メソッド)を実行し、そのテストが失敗していることを示しています。
失敗すると、バーが赤く表示されます。

テスト・ケースの実行(失敗)
では、次にテストケースの中身を以下のように書き換えてみます。


詳細は省略しますが、Calcクラスのsumメソッドを使って、「sum(1,2)」が正しく「3」になるかどうかを確認するように書き換えています。
これをもう一度実行すると、今度はバーの部分が緑色に変わります。
これで、「sum(1,2)=1+2=3」が確認できたことになります。

テスト・ケースの実行(成功)
以上のように、Ecpliseではかなりお手軽にJUnitの導入と実行ができるようになっています。

2012年3月3日土曜日

Flickrのテスト

Flickrの写真を表示するテスト。
自宅の側で撮った月。

P1140439
GF1  LUMIX G VARIO 45-200/F4.0-5.6 F5.6 1/200

JUnit入門―参考情報まとめ編


最近お勉強中のJUnitについて、ちびちびとまとめていきます。

JUnitとは

JUnitとはJava用のユニットテストフレームワークです。
3.x系までと4.x系でテストクラスの書き方や実行の方法が異なっていて、
最新版は4.10です。(2012/3/2現在)
ビルドツール(AntやMavenなど)やIDEなどを始め、様々なツールが連携していて、
Java界隈ではデファクトスタンダードのようです。

以下、参考情報まとめ。

ところで、最新の機能について知りたい場合には、リリースノートかソースコードを見るしかないんでしょうか…

公式系

本家。最新情報等はこちらから。

http://www.junit.org/

レポジトリ。Githubにあります。jarなどのダウンロードもこちらから。
https://github.com/KentBeck/junit

本家のスタートガイドなど。Junit Cookbookに一応簡単な例が載っています。
情報量はいまいちです。
http://junit.sourceforge.net/

JUnit4系

4.x系でのテストクラスの要素についてまとめられています。
最初に読むのがおすすめです。
http://d.hatena.ne.jp/oknknic/20111030/1319943307

上記の要素について、より詳細な解説があります。
http://www.ibm.com/developerworks/jp/java/library/j-junit4/

4.x系から導入されたアサーションメソッド(assertThatとMatcher)の例がたくさん載っています。
モダンな書き方ならこちらでしょうか。
http://d.hatena.ne.jp/daisuke-m/20090710/1247181113

JUnit3系

3.x系について、インストールからテストクラスの書き方までまとめられています。
初心者向けな感じです。
http://www.techscore.com/tech/Java/Others/JUnit/index/


3.x系でのJUnitの使い方から、JUnitを使ったTDDのサンプル、JUnitのTipsなどが書かれています。
3.x系がベースですが、今でもかなり参考になるんではないでしょうか。
長めなのでじっくり読む系です。
http://www.javainthebox.net/publication/200401JP34/junit.html

JUnit(3.x系)を使ったTDDの実況中継の記事「車窓からのTDD」です。(※pdf)
読み物系ですが、TDDのノウハウが詰まってます。
http://objectclub.jp/technicaldoc/testing/stack_tdd.pdf

参考文献

「現場で使えるソフトウェアテスト Java編」
JUnit以外にも、テストで使える様々なツールについて解説されています。
さらには、テスト設計の技法も解説されていて、
Java系以外のテストエンジニアにもおすすめです。
http://www.amazon.co.jp/gp/product/4798114634/

「テスト駆動開発入門」
JUnitの開発者Kent Beck氏によるTDDの入門書。
http://www.amazon.co.jp/gp/product/4894717115/