読者です 読者をやめる 読者になる 読者になる

JUnitチュートリアル

アジャイルソフトウェア開発の奥義 第2版

アジャイルソフトウェア開発の奥義 第2版

  • 作者: ロバート・C・マーチン,Robert C. Martin,瀬谷啓介
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2008/07/01
  • メディア: 単行本
  • 購入: 18人 クリック: 586回
  • この商品を含むブログ (71件) を見る

内容

JUnitとは何なのか、JUnitでユニットテストの実行をしてみる。

環境

JDK8
Eclipse(Neon)
macOS

プロジェクトの準備

ファイル
→新規
→Javaプロジェクト
→junit-tutorialを作成

通常はテストコードとプロダクションコードは別のソースフォルダに配置する。
このため、テストコードを作成するためのソースフォルダ「test」を作成する。

f:id:sattamassagana:20170225221829p:plain

プロジェクトのコンテキストメニューから
→ビルドパス
→新規ソースフォルダを選択
→フォルダ名を「test」にする

テスト対象クラスの作成

■テストクラス
テストプログラムを記述するクラス
■テスト対象クラス
テストされるクラス
下記のようなクラスを作成する。これがテスト対象クラス。
Calculator.java

package junit.tutorial;

public class Calculator {
public int multiply(int x, int y){
	return x * y;
}
public int divide(int x, int y){
	return x / y;
			}
}

テストクラスの作成

パッケージエクスプローラーで右クリック
→新規
→JUit
→JUnit Test Case
ソースフォルダをjunit-tutorial/testにする
テスト元クラスをjunit.tutorial.Calculatorにする

下記のようなクラスが作成される。これがテストクラス。
CalculatorTest.java

package junit.tutorial;

import static org.junit.Assert.*;

import org.junit.Test;

public class CalculatorTest {

	@Test
	public void test() {
		fail("Not yet implemented");
	}

}

テストの実行

この段階ではまだテストが実装されていないが、一旦実行してみる。
CalculatorTestのコンテキストメニューから実行-JUnitテストを選択する。
f:id:sattamassagana:20170226205003p:plain
1件のテストを実行し、1件が失敗したことを確認できる。

乗算メソッドのテストコードを書く

テストメソッドを作成するときは、はじめにそのテストで何を検証したいのかを検証する。
ここでは「テスト対象クラスのmultiplyメソッドで乗算結果が取得できる」ことを検証する。

  • JUnitのルールに注意する
    • テストクラスはpublicクラスとする
    • テストメソッドはorg.junit.Testアノテーションを付与したpublicメソッドとする
    • テストメソッドは戻り値がvoidであり、引数を持たない
    • テストメソッドのthrows句は自由に定義できる
    • テストクラスにはいくつでもテストメソッドを定義できる
    • テストメソッド名は、そのテストの概要がわかる名前にする

まずは「3と4を引数としてmultiplyメソッドを実行し、取得された値が12である」ことを検証する。

CalculatorTest.java

package junit.tutorial;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;

public class CalculatorTest {

//	@Test
//	public void test() {
//		fail("Not yet implemented");
//	}

	// テストコードの追加
	@Test
	public void multiplyTest() {
		Calculator calc = new Calculator();
		int expected = 12;
		int actual = calc.multiply(3, 4);
		//JUnitではorg.junit.AssertクラスのassertThatメソッドを使って
		//「あるテスト対象クラスのメソッドを実行したときに、戻り値などで取得した
		//実際の値と、期待される値が一致する/しないはずである」という宣言で構成される(アサーション)
               //assertThatはAssertクラスに定義sれたstaticメソッド。1つめの引数が実測値、2つめの引数が期待値。
		assertThat(actual, is(expected));
	}

}

実行する
f:id:sattamassagana:20170226212110p:plain
実行1、エラー0、失敗0となった。
また、グリーンバーになっている。
これで「3と4を引数としてmultiplyメソッドを実行し、取得された値が12である」ことが確認できた。

2つめのテストを追加する

テストが失敗した場合の動作を確認してみる。
CalculatorTest.java

package junit.tutorial;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;

public class CalculatorTest {
	@Test
	public void multiplyTest() {
		Calculator calc = new Calculator();
		int expected = 12;
		int actual = calc.multiply(3, 4);
		assertThat(actual, is(expected));
	}
  //テストコード追加その2
	@Test
	public void multiplyTest5x7equals35() {
		Calculator calc = new Calculator();
		int expected = 12;//35が正しい期待値
		int actual = calc.multiply(5, 7);
		assertThat(actual, is(expected));
	}

}

これを実行するとテストが失敗する。
AssertionErrorに「期待値が<12>なのに<35>でした。」とのメッセージ。
f:id:sattamassagana:20170304174806p:plain
Failure Traceにはテスト失敗時のスタックトレースが表示されており、行を
ダブルクリックすることでそのクラスのソース箇所に移動できる。
今回はテストコードの方に不具合があるため、これを修正して再度実行する。
CalculatorTest.java

package junit.tutorial;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;

public class CalculatorTest {
	@Test
	public void multiplyTest() {
		Calculator calc = new Calculator();
		int expected = 12;
		int actual = calc.multiply(3, 4);
		assertThat(actual, is(expected));
	}

	@Test
	public void multiplyTest5x7equals35() {
		Calculator calc = new Calculator();
		int expected = 35;//テストコードを修正
		int actual = calc.multiply(5, 7);
		assertThat(actual, is(expected));
	}

}

f:id:sattamassagana:20170304173950p:plain
2つともグリーン。

windows10 + emacs + oracleでの文字化け

環境

emacsインストール済み
windows10インストール済み
oracle12cインストール済み

問題

emacsからM-x sql-oracleしてsql-plusをバッファに表示させると文字化けしている

対策

oracleのキャラクタセットを確認
sql-plusから
select * from NLS_DATABASE_PARAMETERS;
NLS_CHARACTERSET を確認するとJA16SJISTILDEとなっていた。これはoracleのインストール時に決めるもので後から変えられないらしい。
この場合は環境変数NLS_LANGにJAPANESE_JAPAN.JA16SJISTILDEを設定する必要がある。
システム環境変数の編集→詳細設定タブ→環境変数→システム環境変数で新規→変数名にNLS_LANG、変数値にJAPANESE_JAPAN.JA16SJISTILDE
を設定しOK→OK→OK→windows再起動

結果

emacsからM-x sql-oracle、文字化けしていない。しかし、今度はコマンドプロンプトの方が文字化けしている。

断念

・コマンドプロンプトからsqlplus使わない

JVMのソースコードを読むための準備

JDK/JRE/JVM

JVMとは

Javaバイトコードとして定義された命令セットを実行するスタック型の仮想マシン(Java Virtual Machine) 。JRE(Java Runtime Environment)に入っている。

JREとは

Java実行環境。JVMやAPIが入っている。

JDKとは

Java開発キット(Java Development Kit)。JREが入っている。

具体的に何が入っているのか確かめる

ソースコードを取得する

OpenJDKはMercurialというソースコード管理システムで管理されている。Mercurialをインストールする(ubuntu)

パッケージのダウンロード

sudo apt-get install mercurial

ソースコードを取得するにはターミナルから下記を実行(jdk8)

hg clone http://hg.openjdk.java.net/jdk8/jdk8

するとjdk8というフォルダがhome以下にできる

この時点でフォルダの中を見てみると、makefileや.cファイルの存在を確認できる。まだ.javaファイルはない。
ターミナルからjdk8の中に入り、get_source.shを実行するとソースコードを全て取得できる。

JavaScript スタイルシートを操作する②

<link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript">
 //className.html
 //外部スタイルシートで定義されたスタイル(スタイルクラス)にアクセスするには
 //classNameプロバティを使用する。
 function changeStyle(elem, clazz){
     //指定要素に対して、スタイルクラスclazzを適用する
     elem.className = clazz;
 }
</script>

<div onmouseover="changeStyle(this, 'highlight')"
     onmouseout="changeStyle(this, 'normal')">
    マウスを乗せると色が変わります。</div>
/*style.css*/
.Highlight{
    Background-color: Pink;
}
.normal{
    Background-color: White;
}

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript スタイルシートの操作①

<script type="text/javascript">
 //JavaScriptからスタイルシートを操作①
 
 //インラインスタイルにアクセスする。<div>タグにマウスポインタを載せたタイミングで背景色をピンクに、外したタイミングで下の白色に切り替える。
 function changeStyle(elem, color){
     elem.style.backgroundColor = color;
 }
</script>

<div onmouseover="changeStyle(this, 'Pink')"
     onmouseout="changeStyle(this, 'White')">
    マウスを乗せると色が変わります。</div>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 新規にノードを追加する

<script type="text/javascript">
 //新規にノードを追加する
 
 //フォームに入力した内容を下にページ下部に対応するリンクを追加する
 //追加ボタンをクリックしたタイミングで実行されるadd関数
 function add(f){
     //<a>タグを生成
     var anchor = document.createElement('a');
     //<a>タグのhref属性を設定
     anchor.href = f.url.value;
     //テキストノードを生成し、<a>タグの直下に追加
     var name = document.createTextNode(f.name.value);
     anchor.appendChild(name);
     //<br>タグを生成
     var br = document.createElement('br');
     //<div id="list">を取得
     var list = document.getElementById('list');
     //<div>タグ直下に<a>,<br>タグの順番で追加
     list.appendChild(anchor);
     list.appendChild(br);
 }
</script>

<form>
    <label>サイト名:<br />
        <input type="text" name="name" size="30"/></label><br />
        <label>URL:<br />
            <input type="text" name="url" size="50"/></label><br />
            <input type="button" value="追加" onclick="add(this.form)"/>
</form>
<div id="list"></div>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript ウィンドウサイズやスクロール位置を操作する

<html>
    <head>
        <body>
<!-- moveByメソッド、resizeByメソッドはChromeでは未対応 -->
 <input type="button" value="scrollTo" onclick="window.scrollTo(0,200)"/>
 <input type="button" value="moveBy" onclick="moveBy(100,100)"/>
 <input type="button" value="resizeBy" onclick="window.resizeBy(50,50)"/>
 1<br>
 1<br>
 1<br>
 1<br>
 1<br>
 1<br>
 1<br>
 1 <br>
 1<br>
 1<br>
 
        </body>
    </head>
</html>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript タイマー機能の実装

<script>
 //タイマー機能の実装
 //タイマーIDを格納するためのグローバル変数
 var timer;
 //ページロード時にタイマー処理を登録
 window.onload = function(){
     timer = window.setInterval(
         //現在の時刻を<div id='result'>タグに表示(1000ミリ秒ごとに更新)
         function(){
             var dat = new Date();
             document.getElementById('result').innerHTML = dat.toLocaleTimeString();
         },1000
     );
 };
</script>

<!-- ボタンクリック時にタイマー処理を中止 -->
<input type="button" value="タイマー停止" onclick="clearInterval(timer)"/>
<div id="result"></div>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript サブウィンドウを生成する

<script type="text/javascript">
 //サブウインドウを表すWindowオブジェクトを格納する変数
 var subwin;
 //サブウィンドウを開くボタンクリック時に実行
 function win_open(){
     subwin = window.open('http://www.wings.msn.to/', 'Sample',
     'width=600,height=300,scrollbars=yes,location=yes');
 }
 //サブウィンドウを閉じるボタンクリック時に実行
 function win_close(){
     //変数subwinが空でなく、サブウィンドウが閉じられていない時にのみクローズ
     if(subwin && !subwin.closed){
         subwin.close();
     }
 }
</script>

<input type="button" value="サブウィンドウを開く" onclick="win_open()"/>
<input type="button" value="サブウィンドウを閉じる" onclick="win_close()"/>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript ハンドラー3

<script type="text/javascript">
    //ページロード時に実行されるイベントハンドラを登録
    window.onload = function(){
    //ボタンクリック時に実行されるイベントハンドラを登録
    document.getElementById('btn').onclick = function(){
    window.alert('ボタンがクリックされました');
    };
    };
</script>
<input id="btn" type="button" value="ダイアログ表示"/>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript ハンドラー1

<script type="text/JavaScript">

 function btn_onclick(){
     window.alert('ボタンがクリックされました');
 };
 //-->
</script>

<input type="button" value="ダイアログ表示" onclick="btn_onclick()" />

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 継承

<script>
//クラスベースなオブジェクト指向によく似た継承を実現する方法
 //予め用意したMemberクラスを継承してSpecialMemberクラスを定義する
 function initializeBase(derive, base, baseArgs){
     base.apply(derive, baseArgs);
     for(prop in base.prototype){
         var proto = derive.constructor.prototype;
         if(!proto[prop]){
             proto[prop] = base.prototype[prop];
         }
     }
 }

 //Memberクラスを定義
 var Member = function(firstName, lastName){
     this.firstName = firstName;
     this.lastName = lastName;
 };

 Member.prototype.getName = function(){
     return this.lastName + ' ' + this.firstName;
 };

 //Memberクラスを継承したSpecialMemberクラスを定義
 var SpecialMember = function(firstName, lastName, role){
     initializeBase(this, Member, [firstName, lastName]);
     this.role = role;
 }

 SpecialMember.prototype.isAdministrator = function(){
     return (this.role == 'Administrator');
 };

 var mem = new SpecialMember('Jhon', 'Paul', 'Administrator');
 document.writeln('名前:' + mem.getName());
 document.writeln('管理者:' + mem.isAdministrator());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript コンストラクタ

<script>
 var Member = function(firstName, lastName){
//thisはコンストラクタによって生成されるインスタンスを表す。
     this.firstName = firstName;
     this.lastName = lastName;
     this.getName = function(){
         return this.lastName + ' ' + this.firstName;
     }
 };

 var mem = new Member(' Jhon', 'Paul');
 document.writeln(mem.getName());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript クラス

<script>
 //JavaScriptのオブジェクト指向はプロトタイプベースのオブジェクト指向であり
 //クラスベースのオブジェクト指向ではない

 // 「クラス」を定義
 var Member = function(){};

 //インスタンス化
 var mem = new Member();//JavaScriptでは関数にクラスとしての役割を与えている
 //new演算子によってオブジェクトを生成することを想定した関数オブジェクトのことを
 //コンストラクタと言っている。
 //Member関数がコンストラクタにあたる。
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで