ラベル JUnit ユニットテスト の投稿を表示しています。 すべての投稿を表示
ラベル JUnit ユニットテスト の投稿を表示しています。 すべての投稿を表示

2011年8月9日火曜日

Goole App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発する(その13)

それでは、ここで今までの内容を反映した
サンプルコードを掲載します。



import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

/**
 * Google App Engine for Javaにおけるユニットテストのサンプルコード。
 */
public class LocalUnitTestSample {

	private static final String DATA_KIND = "sampleDataKind";

	private LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

	private String propertyName = "propertyName";

	private String[] propertyValues = {"pValue1","pValue2","pValue3","pValue4","pValue5"};

	private DatastoreService ds;

	private List keyList;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		helper.setUp();

		//サンプルデータをデータストアに保存する
		putSampleData();
	}

	/**
	 * サンプルデータをデータストアに保存するメソッド。
	 */
	private void putSampleData() {
		keyList = new ArrayList();
		ds = DatastoreServiceFactory.getDatastoreService();
		for (int i = 0; i < propertyValues.length; i++) {
			Entity entity = new Entity(DATA_KIND);
			entity.setProperty(propertyName, propertyValues[i]);
			Key key = ds.put(entity);
			keyList.add(key);
		}
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		//サンプルデータをデータストアから削除する
		deleteSampleData();

		helper.tearDown();
	}

	/**
	 * サンプルデータをデータストアから削除するメソッド。
	 */
	private void deleteSampleData() {
		Iterator iter = keyList.iterator();
		while (iter.hasNext()){
			ds.delete(iter.next());
		}
	}

	@Test
	public void doTest(){
		//サンプルデータをデータストアから検索する
		for (int i = 0;i < propertyValues.length;i++){
			EntitySearch search = new EntitySearch(ds,DATA_KIND,propertyName);
			List entitiesList = search.getEntity(propertyValues[i]);
			assertEquals(1,entitiesList.size());
			Iterator iter = entitiesList.iterator();
			while (iter.hasNext()){
				Entity entity = iter.next();
				assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
			}
		}
	}

	/**
	 * データストアから、設定された名前のプロパティが該当する
	 * エンティティを取得する機能を提供するクラス。
	 */
	public class EntitySearch {

		/**
		 * データストアサービス
		 */
		private DatastoreService ds;

		/**
		 * 探索するエンティティのカインド名を表す文字列フィールド
		 */
		private String kindName;

		/**
		 * 探索するプロパティの名前を表す文字列フィールド
		 */
		private String propertyName;

		/**
		 * データストアサービスと、探索するプロパティの名前を引数とするコンストラクタ。
		 * @param ds データストアサービスオブジェクト
		 * @param kindName 取得するエンティティのカインド名文字列
		 * @param propertyName 探索するプロパティ名を表す文字列
		 */
		public EntitySearch(DatastoreService ds, String kindName, String propertyName) {
			this.ds = ds;
			this.kindName = kindName;
			this.propertyName = propertyName;
		}

		/**
		 * データストアからエンティティを検索するメソッド。
		 * コンストラクタで設定したカインド、プロパティ名の値が
		 * 引数propertyValueと同一のエンティティを格納したリストを返します。
		 * @param propertyValue 検索条件となるプロパティの値オブジェクト
		 * @return コンストラクタで設定したプロパティが引数propertyValueと同一の値のエンティティのリスト
		 */
		public List getEntity(Object propertyValue) {
			Query query = new Query(kindName);
			query.addFilter(propertyName, FilterOperator.EQUAL, propertyValue);
			PreparedQuery prepare = ds.prepare(query);
			List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
			return entitiesList;
		}

	}

} 

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年8月7日日曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発する(その12)

前回に引き続き、EntitySearchクラスの修正を行います。


メソッドgetEntity()内で、
クエリを生成する部分に修正する点があります。

コンパイル時に警告が出るのですが、
フィールドkindNameが参照されていないのです。

getEntity()内では、
エンティティ探索のためにクエリを生成しています。
クエリを生成するためにはコンストラクタで
new Query(String kind)
とするのですが、
引数の部分が
DATA_KIND
となっていて、LocalUnitTestSampleクラスの定数を参照しています。
(もし、EntitySearchクラスを内部クラスとしていなければ、
コンパイルエラーになります)

そこで、探索するエンティティのカインド名を
DATA_KINDから、kindNameに変更します。
そうすることで、EntitySearchクラスの内部から
LocalUnitTestSampleクラスのメンバを直接参照することは
なくなります。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年8月4日木曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発する(その11)

前回の投稿で、テスト駆動開発の利点として、
回帰テストが容易に出来る、ということを挙げました。

その実践・・・というわけでもないですが、
サンプルコードを修正してみましょう。
修正、といいますが、つまり、忘れていた点があったんです。

作成したEntitySearchクラスのコンストラクタが
実装されていませんでした。
引数が何も使われないままになっていたんですね。

引数が使われないまま放置されていたのに、
テストを実行してみると成功します。
この理由は、
EntitySearchクラスがLocalUnitTestSampleクラスの
内部クラスであることが原因です。

もし、EntitySearchクラスを内部クラスではなく、
別の独立したクラスとすると
コンパイルエラーとなります。

メソッドgetEntity()の内部で、
変数ds,kindName,propertyNameを解決できないはずです。

そこで、コンストラクタで渡された引数を
フィールドとして保持することにします。
private DatastoreService ds;

private String kindName;

private String propertyName;

public EntitySearch(DatastoreService ds, String kindName, String propertyName) {
 this.ds = ds;
 this.kindName = kindName;
 this.propertyName = propertyName;
}
フィールドds,kindName,propertyNameを宣言して、
コンストラクタで引数の値を代入します。

これで、メソッドgetEntity()でのコンパイルエラーが解消されます。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年8月2日火曜日

テスト駆動開発の利点(その3)

前にも書きましたが、
このブログで掲載しているサンプルコードのテスト駆動開発の
やり方は、あくまで私のやり方です。
ここで書いている「テスト駆動開発の利点」も
私なりに行ううえでのものです。

テスト駆動開発の方法や効果を書いた書籍やウェブページは
沢山あります。
それらを網羅してまとめる、ということをしているわけではありません。

それでも、回帰テストが容易に出来る、というのは間違いない利点です。
開発中はもちろん、一度クラスの実装が出来上がってからも、
簡単にテストが行えますから、コードの改修を積極的に行えます。
「少なくとも、テストコードのカバーしている範囲では」、
コードの修正を行っても、きちんと動作することを確かめられます。


インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月30日土曜日

テスト駆動開発の利点(その2)

前回では、サンプルコードのテスト駆動開発で
・コンパイルエラーまたはテストの失敗

・エラーの解消

・コンパイルエラーまたはテストの失敗
というサイクルが繰り返されることで、
コードの開発が促進されることを述べました。

これの特徴は、
「エラーがコーディングの区切りとなる」
ということです。

エラーが出たら解消しなければいけない、
と考えるのは普通ですが、
テスト駆動開発では
コーディングの進捗を表します。
ここまでは出来た、というわけです(後で手直しするハメになることも当然ありますけど)。

例えば、コーディングの途中で休憩したくなった時に、
エラーの出たところで休憩すれば、戻ってきても
どこから続ければいいのかすぐ分かります。
休憩しておしゃべりなんかしている間に
どこまで仕事が進んでいたのか忘れてしまって
再開地点を探すことから始めなければならなかった、
なんてことはありませんか?私はありますけど。それもよく。

忘れたって大丈夫なんです。
コンパイルエラーやテストの失敗は、
開発しているマシン(コンパイラやIDEなど)が教えてくれます。
これで、仕事の栞を頭の中から外して、
休憩に集中できますね(それも変)。

仕事と休憩のメリハリも大切ですね、ということにします。



インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月29日金曜日

テスト駆動開発の利点

前回まで、Google App Engine for Java のAPIを利用するクラスの
テスト駆動開発を試してみました。

あくまで、ここで行った方法は
私なりのやり方です。他の方法で行っている方は沢山いるでしょうし、
異論もあるでしょう。

先に動作確認済みのサンプルコードがある状態から
新しいクラスを作る、という例なので
そのままのやり方で応用できるというわけでもありません。
メソッドの中身をコピーしてくる部分などは、
先に機能の実装が出来ていなければなりませんし、
コンストラクタの引数を先に決めてから定義している部分も
かなり実装のイメージが出来上がっていなければ出来ません
(ここについては、コンストラクタの引数を定義しないでおいて、
必要になってから定義していくやり方もあるのですが、
つい、飛ばしてしまいました)。

しかし、既に定義されている仕様に従ってテストコードを
作成してから、そのテストに通るクラスを実装していくという方法は
有効なものです。

前々回に述べたように、テストコードが実装の指針を示していくので
コードの記述が楽になります。
実装の流れは、
・コンパイルエラーまたはテストの失敗

・エラーの解消

・コンパイルエラーまたはテストの失敗
という繰り返しになっています。
コンパイルエラーが何度も何度も繰り返されるので
まとめてエラーが出ないコードを書けばいい、というのとは違います(間違っているという意味ではありません)。
エラーが次に実装すべきコードを示している、ということです。
コードを頭の中からひねり出す苦労を減らせます。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月23日土曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その9)

前回で、EntitySearchクラスの実装が出来ました。

テストを実行してみます。

・・・成功しました。バーが緑になっています。

9回に渡ってテスト駆動開発を行ってきましたが、
とりあえず今回で終了です。
簡単な機能を持つクラスの作成でしたが、
 一応の完成をみました。

全体の流れをまとめてみると、
1.テストコードの作成
2.テスト対象のクラスを定義する
3.コンパイルエラーを修正しながら実装
4.テストの実行
5.エラーの修正
6.3~5を繰り返す
という順で開発を行っています。

1.テストコードの作成
ここでは、開発対象となるクラスの仕様に沿って、
テストを作成します。
メソッドのテストならば、特定の引数をメソッドに与えると、
結果が仕様通りに返ってくることを検証します。
条件と結果の組み合わせでテストするわけです。

今回は、動作するサンプルとして書いたテストコードを元に
開発を行ったので、開発対象のクラスに移したい機能を
コメントアウトする、というやり方で開発しています。
しかし、事前に機能するコードが実装されていなくても、
実装したい機能をテストするコードを書くことで、
開発の指針がコンパイルエラーやテストの失敗として
示されます。




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月16日土曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その7)

EntitySearch.getEntity(Object)メソッドが
単純にnullを返すだけになっているために、
テストを実行するとdoTest()メソッド内で
NullPointerExceptionがスローされる、
という所まで、前回は進みました。

getEntity()メソッドの中身を実装するのは簡単、
と前回の終わりに述べました。
同時に、既に大体出来ている、とも述べました。

テスト駆動開発を始めるときに、
doTest()メソッド内でコメントアウトした部分がありました。
開発するクラスの動作部分、テストする対象を
コメントアウトしたのですが、
まさにこの部分がgetEntity()メソッドの行いたい事を
表しています。
コメントアウトした部分の代わりに
EntitySearchオブジェクトを使った部分を記述しました。

それでは、コメントアウトした部分を
getEntity()メソッドにコピーします。

public List<entity> getEntity(Object propertyValue) {
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List<entity> entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   return null;
  }

またもや、コンパイルエラーが出ます。
ループカウンタを表していた
i
という変数が解決できないという内容です。
query.addFilter()メソッドの第3引数に与えるのは、
比較対象となるプロパティ値なので、
これはgetEntity()メソッドの引数propertyValueに変更します。
これで「i」という変数はメソッド内からなくなり、
コンパイルエラーは解消されます。




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月14日木曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その6)

前回で、コンパイルエラーは解決しました。
コード全体を見れば未完成なのは明らかですが、
とりあえず、テストを実行してみましょう。

テストの実行結果は、
java.lang.NullPointerExceptionがスローされて失敗します。

場所は、
doTest()メソッド内、
assertEquals(1,entitiesList.size());
です。
entitiesListがnullなので、size()メソッドを呼び出せないわけです。

その前の行でentitiesListにsearch.getEntity(propertyValues[i])
を代入しているわけですが、
そのsearch.getEntity()メソッドが
return null;

なのですから、当然の結果です。

そこで、getEntity()メソッドを実装します。
難しくはありません。
この記事は行き当たりばったりで書いていますが、
はっきり言えます。
難しくはありません。

なぜなら、既に大体出来ているからです。




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月4日月曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その3)

前回は、
doTest()メソッドの中から、
別クラスとして実装する部分をコメントアウトしました。
コメントアウトした部分の行っていたことは、
データストアから条件に沿って取得したエンティティを格納した
java.util.Listオブジェクトを取得することでした。

ここでコンパイルエラーとなった部分は、
entitiesList
です。
ローカル変数entitiesListは宣言された部分が
コメントアウトされたのですから、当然です。

コンパイルエラーを解決するために、
変数entitiesListを宣言します。
コメントアウトの直後、
assertEquals(1,entitiesList.size());
の前に

List entitiesList;


を加えます。

すると、またもやエラーになります。
「変数entitiesListが初期化されていない可能性があります。」
というメッセージです。

変数entitiesListは、データストアから取得したエンティティを格納した
java.util.Listオブジェクトとしたいのですから、
目的の機能を持ったメソッドを宣言します。

List entitiesList = getEntity(propertyValues[i]);


とします。
すると、メソッドgetEntity(String)は未定義なので、
コンパイルエラーになります。


ここまでのコードは、以下の通りです。


@Test
public void doTest(){
//サンプルデータをデータストアから検索する
for (int i = 0;i < propertyValues.length;i++){ /*   Query query = new Query(DATA_KIND);    query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);    PreparedQuery prepare = ds.prepare(query);    List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
*/   List entitiesList = getEntity(propertyValues[i]);
assertEquals(1,entitiesList.size());
Iterator iter = entitiesList.iterator();
while (iter.hasNext()){
Entity entity = iter.next();
assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
}
}
}


インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月3日日曜日

Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その2)

前回、テストメソッドの中身を別クラスに移す
と書きました。

そのテストメソッドは以下の通りでした。


@Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyValues.length;i++){
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   assertEquals(1,entitiesList.size());
   Iterator iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
   }
  }
 }
まず、別クラスに移す部分をコメントアウトしてしまいましょう。
コメントアウトする部分、つまり別クラスの機能とする部分は、
Queryを生成して、データストアからプロパティの値が該当するエンティティの
リストを取得する部分です。

@Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyValues.length;i++){
/*   Query query = new Query(DATA_KIND);
   query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
*/   assertEquals(1,entitiesList.size());
   Iterator iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
   }
  }
 }

すると、
assertEquals(1,entitiesList.size());
Iterator iter = entitiesList.iterator();
の行でコンパイルエラーとなります。




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年7月1日金曜日

データストアAPIを利用するテスト駆動開発をおこなってみる

前回まで、サンプルコードの修正を行いました。
データストアに保存するサンプルデータを変更した後の
コードは前回掲載したとおりです。

今後は、修正後のサンプルコードを

サンプルコード2

と記述することにします。

サンプルコード2でJUnitテストを行うと、
きちんとテストは成功します(確認しました)。

しかし、サンプルコード2のテストは
テストコードではあるものの、具体的に何かのJavaクラスを
テストしたわけではありません。
単に、データストアにデータを保存して、
保存したデータを取り出してみた、というだけです。

一連の動作を行うだけならば、
わざわざJUnitテストクラスを作るのではなく、
普通のJavaクラスにmainメソッドを宣言して
実装すればいいことです。

JUnitテストで動作するコードを書いた理由は、
きちんと動作するということが視覚的に確認できる、
という意味があります。
要するに、バーが緑になる(テストが全て成功する)ということです。

それだけではありません。
成功するテストがあるならば、テストメソッドの内部で行っている処理を
別のクラスの機能として実装することができます。
新しく実装するクラスのテストが既にできていることになります。

次回から、
実際にテストメソッドの内部の処理を別クラスに移す、
ということを行ってみます。




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年6月28日火曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その16)

前回までに修正した、サンプルコードを掲載します。

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

/**
 * Google App Engine for Javaにおけるユニットテストのサンプルコード。
 */
public class LocalUnitTestSample {

 private static final String DATA_KIND = "sampleDataKind";

 private LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

 //private String[] propertyNames = {"pName1","pName2","pName3","pName4","pName5"};
 private String propertyName = "propertyName";

 private String[] propertyValues = {"pValue1","pValue2","pValue3","pValue4","pValue5"};

 private DatastoreService ds;

 private List keyList;

 /**
  * @throws java.lang.Exception
  */
 @Before
 public void setUp() throws Exception {
  helper.setUp();

  //サンプルデータをデータストアに保存する
  putSampleData();
 }

 /**
  * サンプルデータをデータストアに保存するメソッド。
  */
 private void putSampleData() {
  keyList = new ArrayList();
  ds = DatastoreServiceFactory.getDatastoreService();
  for (int i = 0; i < propertyValues.length; i++) {
   Entity entity = new Entity(DATA_KIND);
   entity.setProperty(propertyName, propertyValues[i]);
   Key key = ds.put(entity);
   keyList.add(key);
  }
 }

 /**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
  //サンプルデータをデータストアから削除する
  deleteSampleData();

  helper.tearDown();
 }

 /**
  * サンプルデータをデータストアから削除するメソッド。
  */
 private void deleteSampleData() {
  Iterator iter = keyList.iterator();
  while (iter.hasNext()){
   ds.delete(iter.next());
  }
 }

 @Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyValues.length;i++){
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   assertEquals(1,entitiesList.size());
   Iterator iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
   }
  }
 }

}




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年6月27日月曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その15)

サンプルコードの変更の続きです。


前回の変更で、
putSampleData()メソッドを修正しました。

今回は、
doTest()メソッドの修正です。

まず最初、for文です。
for (int i = 0;i < propertyNames.length;i++){
この行のpropertyNamesの部分がコンパイルエラーになりますので、
propertyValues


と変更します。
ループ条件を構成する配列を、propertyNamesからpropertyValuesにすることで、
プロパティの「値」の数だけ繰り返します。

その次は、
query.addFilter(propertyNames[i], FilterOperator.EQUAL, propertyValues[i]);
の行のうち、propertyNames[i]の部分がコンパイルエラーになるので、
ここに正しいプロパティ名にあたる文字列を入れます。
propertyName
です。
変更後のコードは、
query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i])
です。

もう一つは、
whileループ内部のassertTrue()の引数です。
assertTrue(propertyValues[i].equals(entity.getProperty(propertyNames[i])));
この行のpropertyNames[i]を、propertyNameにします。
assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
となります。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月23日木曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その14)

サンプルコードの変更の続きです。

前回の変更で、
フィールドpropertyNamesを削除して、
新たにフィールドpropertyNameを作成しました。

すると、コンパイルエラーとなりますので、
エラー部分を修正します。

まず、
putSampleData()メソッドです。

for (int i = 0;i < propertyNames.length;i++){

の行を、
for (int i = 0;i < propertyValues.length;i++){

と変更します。
propertyNamesをpropertyValuesとするわけです。

次に、
entity.setProperty(propertyNames[i],propertyValues[i]);


の行を
entity.setProperty(propertyName,propertyValues[i]);

とします。
propertyNames[i]をpropertyNameに変更しています。

次回は、doTest()メソッドを変更します。


インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月21日火曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その13)

サンプルコードの改造を進める前に、
テスト用のサンプルデータを変更します。

と言っても、プロパティ名を変更するだけです。

フィールドpropertyNamesはjava.lang.String配列になっていますが、
String型に変更します。

private String[] propertyNames = 
{"pName1","pName2","pName3","pName4","pName5"};
の行を、
private String propertyName = "propertyName";
と変更します。

次に、
メソッドputSampleData()の実装を変更します。


インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月18日土曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その12)

今回は、サンプルコードの改変はお休みです。
その代わり、サンプルコード全体の流れを
書いてみます。


このサンプルコードは、
setUp()
putSampleData()
doTest()
tearDown()
deleteSampleData()
の5つのメソッドを実装しています。
この中で、putSampleData()、deleteSampleData()の2つは
それぞれsetUp()、tearDown()の内部で呼び出されるだけなので、
テストを実行する上で、メソッド呼び出しの流れとしては
serUp()
doTest()
tearDown()
という順になります。JUnit4で使用されるアノテーションが付いた
メソッドだけです。

・テストの前準備(サンプルデータの保存)
・テストの実行(サンプルデータの検索)
・テストの後処理(サンプルデータの削除)
単純な流れですね。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年5月23日月曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる

前回前々回
データストアAPIのテストを実装する上での
気が付いた事について書きました。

今回からは、テストクラスを実装して、
具体的にどういうことなのか?
ということを述べようと思います。

まずは、サンプルコードです。
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

/**
 * Google App Engine for Javaにおけるユニットテストのサンプルコード。
 */
public class LocalUnitTestSample {

 private static final String DATA_KIND = "sampleDataKind";

 private LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

 private String[] propertyNames = {"pName1","pName2","pName3","pName4","pName5"};

 private String[] propertyValues = {"pValue1","pValue2","pValue3","pValue4","pValue5"};

 private DatastoreService ds;

 private List<key> keyList;

 /**
  * @throws java.lang.Exception
  */
 @Before
 public void setUp() throws Exception {
  helper.setUp();

  //サンプルデータをデータストアに保存する
  putSampleData();
 }

 /**
  * サンプルデータをデータストアに保存するメソッド。
  */
 private void putSampleData() {
  keyList = new ArrayList<key>();
  ds = DatastoreServiceFactory.getDatastoreService();
  for (int i = 0; i < propertyNames.length; i++) {
   Entity entity = new Entity(DATA_KIND);
   entity.setProperty(propertyNames[i], propertyValues[i]);
   Key key = ds.put(entity);
   keyList.add(key);
  }
 }

 /**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
  //サンプルデータをデータストアから削除する
  deleteSampleData();

  helper.tearDown();
 }

 /**
  * サンプルデータをデータストアから削除するメソッド。
  */
 private void deleteSampleData() {
  Iterator<key> iter = keyList.iterator();
  while (iter.hasNext()){
   ds.delete(iter.next());
  }
 }

 @Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyNames.length;i++){
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyNames[i], FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List<entity> entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   assertEquals(1,entitiesList.size());
   Iterator<entity> iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyNames[i])));
   }
  }
 }

}

このコードは動作確認済みです。
次回から、このコードの内容の説明と、
前回までの内容を示すコードの変更を行います。


インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月23日土曜日

Google App Engineのユニットテストのドキュメント(その1)

前回、Google App Engine for Javaのテストについて
少しだけ述べました。

今回は、その問題のドキュメントの翻訳を
してみようと思います。
ちなみに、翻訳にはKaede翻訳ツールを使っています。
もともと、こういう用途に使うために作ったものですからね。

翻訳元のドキュメントは
http://code.google.com/intl/en/appengine/docs/java/tools/localunittesting.html
です。

Local Unit Testing for Java (Javaにおけるローカルユニットテスト)
ユニットテストは、記述されたコードの質をチェックすることを可能にしますが、継続中の開発プロセスを改善するためにユニットテストを使用することも可能です。アプリケーションの開発が終わった後にテストを記述する代わりに、行うべきテストを記述することを検討してみてください。それが小さく、保守しやすく、再利用できるコードのユニットをデザインする助けとなります。そしてまた、コードを徹底的に、素早くテストすることを容易にします。

ローカル環境でユニットテストを行う場合、アプリケーションに含まれるリモートコンポーネントを除いた上での開発環境の内部に限定されたテストを実行するでしょう。App Engineは、ローカルで実装されたデータストアと、その他のApp Engineのサービスを利用するテスト用ユーティリティを提供しています。これは、App Engineにデプロイすることなく、サービスのスタブを使うことで、これらのサービスをローカルで利用したコードを実行することを可能にします。

サービスのスタブは、サービスの振る舞いをシミュレートするメソッドとなっています。例として、データストアサービスのスタブは、実際のデータストアに対するリクエストを作成すること無しにデータストアを利用するコードのテストを可能とするWriting Datastore and Memcache Tests(データストアとMemcacheのテストの記述)で示されています。データストアのユニットテストの間に保存されるエンティティはメモリ上に保持され、データストアには保存されず、テストの実行の後に削除されます。これにより、データストア自身に依存することなく、小規模に素早くテストを実行することができます。

このドキュメントはテストを行うフレームワークをセットアップするための情報を提供して、ローカルApp Engineサービスについてのユニットテストの記述方法を説明します。

・Setting Up a Testing Framework (テストを行うフレームワークのセットアップ)
・Intorduceing the Java Testing Utilities (Javaにおけるテストユーティリティの紹介)
・Writing Datastore and Memcahe Tests (データストアとMemcacheのテストの記述)
・Writing Task Queue Tests (タスクキューのテストの記述)
・Writing Tests for Other Services (その他のサービスのテストの記述)
・Writing Tests with Authentication Expectations (認証を前提としたテストの記述)


続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/