前にも書きましたが、
このブログで掲載しているサンプルコードのテスト駆動開発の
やり方は、あくまで私のやり方です。
ここで書いている「テスト駆動開発の利点」も
私なりに行ううえでのものです。
テスト駆動開発の方法や効果を書いた書籍やウェブページは
沢山あります。
それらを網羅してまとめる、ということをしているわけではありません。
それでも、回帰テストが容易に出来る、というのは間違いない利点です。
開発中はもちろん、一度クラスの実装が出来上がってからも、
簡単にテストが行えますから、コードの改修を積極的に行えます。
「少なくとも、テストコードのカバーしている範囲では」、
コードの修正を行っても、きちんと動作することを確かめられます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
インストール不要・無料の自製翻訳ツール、Kaede翻訳ツール(Translation Tool)の使い方・変更点などをつづるブログ。
2011年8月2日火曜日
2011年7月30日土曜日
テスト駆動開発の利点(その2)
前回では、サンプルコードのテスト駆動開発で
・コンパイルエラーまたはテストの失敗
↓
・エラーの解消
↓
・コンパイルエラーまたはテストの失敗
というサイクルが繰り返されることで、
コードの開発が促進されることを述べました。
これの特徴は、
「エラーがコーディングの区切りとなる」
ということです。
エラーが出たら解消しなければいけない、
と考えるのは普通ですが、
テスト駆動開発では
コーディングの進捗を表します。
ここまでは出来た、というわけです(後で手直しするハメになることも当然ありますけど)。
例えば、コーディングの途中で休憩したくなった時に、
エラーの出たところで休憩すれば、戻ってきても
どこから続ければいいのかすぐ分かります。
休憩しておしゃべりなんかしている間に
どこまで仕事が進んでいたのか忘れてしまって
再開地点を探すことから始めなければならなかった、
なんてことはありませんか?私はありますけど。それもよく。
忘れたって大丈夫なんです。
コンパイルエラーやテストの失敗は、
開発しているマシン(コンパイラやIDEなど)が教えてくれます。
これで、仕事の栞を頭の中から外して、
休憩に集中できますね(それも変)。
仕事と休憩のメリハリも大切ですね、ということにします。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
・コンパイルエラーまたはテストの失敗
↓
・エラーの解消
↓
・コンパイルエラーまたはテストの失敗
というサイクルが繰り返されることで、
コードの開発が促進されることを述べました。
これの特徴は、
「エラーがコーディングの区切りとなる」
ということです。
エラーが出たら解消しなければいけない、
と考えるのは普通ですが、
テスト駆動開発では
コーディングの進捗を表します。
ここまでは出来た、というわけです(後で手直しするハメになることも当然ありますけど)。
例えば、コーディングの途中で休憩したくなった時に、
エラーの出たところで休憩すれば、戻ってきても
どこから続ければいいのかすぐ分かります。
休憩しておしゃべりなんかしている間に
どこまで仕事が進んでいたのか忘れてしまって
再開地点を探すことから始めなければならなかった、
なんてことはありませんか?私はありますけど。それもよく。
忘れたって大丈夫なんです。
コンパイルエラーやテストの失敗は、
開発しているマシン(コンパイラやIDEなど)が教えてくれます。
これで、仕事の栞を頭の中から外して、
休憩に集中できますね(それも変)。
仕事と休憩のメリハリも大切ですね、ということにします。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
2011年7月29日金曜日
テスト駆動開発の利点
前回まで、Google App Engine for Java のAPIを利用するクラスの
テスト駆動開発を試してみました。
あくまで、ここで行った方法は
私なりのやり方です。他の方法で行っている方は沢山いるでしょうし、
異論もあるでしょう。
先に動作確認済みのサンプルコードがある状態から
新しいクラスを作る、という例なので
そのままのやり方で応用できるというわけでもありません。
メソッドの中身をコピーしてくる部分などは、
先に機能の実装が出来ていなければなりませんし、
コンストラクタの引数を先に決めてから定義している部分も
かなり実装のイメージが出来上がっていなければ出来ません
(ここについては、コンストラクタの引数を定義しないでおいて、
必要になってから定義していくやり方もあるのですが、
つい、飛ばしてしまいました)。
しかし、既に定義されている仕様に従ってテストコードを
作成してから、そのテストに通るクラスを実装していくという方法は
有効なものです。
前々回に述べたように、テストコードが実装の指針を示していくので
コードの記述が楽になります。
実装の流れは、
・コンパイルエラーまたはテストの失敗
↓
・エラーの解消
↓
・コンパイルエラーまたはテストの失敗
という繰り返しになっています。
コンパイルエラーが何度も何度も繰り返されるので
まとめてエラーが出ないコードを書けばいい、というのとは違います(間違っているという意味ではありません)。
エラーが次に実装すべきコードを示している、ということです。
コードを頭の中からひねり出す苦労を減らせます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
テスト駆動開発を試してみました。
あくまで、ここで行った方法は
私なりのやり方です。他の方法で行っている方は沢山いるでしょうし、
異論もあるでしょう。
先に動作確認済みのサンプルコードがある状態から
新しいクラスを作る、という例なので
そのままのやり方で応用できるというわけでもありません。
メソッドの中身をコピーしてくる部分などは、
先に機能の実装が出来ていなければなりませんし、
コンストラクタの引数を先に決めてから定義している部分も
かなり実装のイメージが出来上がっていなければ出来ません
(ここについては、コンストラクタの引数を定義しないでおいて、
必要になってから定義していくやり方もあるのですが、
つい、飛ばしてしまいました)。
しかし、既に定義されている仕様に従ってテストコードを
作成してから、そのテストに通るクラスを実装していくという方法は
有効なものです。
前々回に述べたように、テストコードが実装の指針を示していくので
コードの記述が楽になります。
実装の流れは、
・コンパイルエラーまたはテストの失敗
↓
・エラーの解消
↓
・コンパイルエラーまたはテストの失敗
という繰り返しになっています。
コンパイルエラーが何度も何度も繰り返されるので
まとめてエラーが出ないコードを書けばいい、というのとは違います(間違っているという意味ではありません)。
エラーが次に実装すべきコードを示している、ということです。
コードを頭の中からひねり出す苦労を減らせます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
2011年7月25日月曜日
Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その10)
先に進む前に、ソースコードを掲載します。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
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<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 < 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<key> 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<entity> entitiesList = search.getEntity(propertyValues[i]);
assertEquals(1,entitiesList.size());
Iterator<entity> iter = entitiesList.iterator();
while (iter.hasNext()){
Entity entity = iter.next();
assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
}
}
}
/**
* データストアから、設定された名前のプロパティが該当する
* エンティティを取得する機能を提供するクラス。
*/
public class EntitySearch {
/**
* データストアサービスと、探索するプロパティの名前を引数とするコンストラクタ。
* @param ds データストアサービスオブジェクト
* @param kindName 取得するエンティティのカインド名文字列
* @param propertyName 探索するプロパティ名を表す文字列
*/
public EntitySearch(DatastoreService ds, String kindName, String propertyName) {
}
/**
* データストアからエンティティを検索するメソッド。
* コンストラクタで設定したカインド、プロパティ名の値が
* 引数propertyValueと同一のエンティティを格納したリストを返します。
* @param propertyValue 検索条件となるプロパティの値オブジェクト
* @return コンストラクタで設定したプロパティが引数propertyValueと同一の値のエンティティのリスト
*/
public List<entity> getEntity(Object propertyValue) {
Query query = new Query(DATA_KIND);
query.addFilter(propertyName, FilterOperator.EQUAL, propertyValue);
PreparedQuery prepare = ds.prepare(query);
List<entity> entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
return entitiesList;
}
}
}
インストール不要・無料の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を繰り返す
という順で開発を行っています。
テストを作成します。
メソッドのテストならば、特定の引数をメソッドに与えると、
結果が仕様通りに返ってくることを検証します。
条件と結果の組み合わせでテストするわけです。
今回は、動作するサンプルとして書いたテストコードを元に
開発を行ったので、開発対象のクラスに移したい機能を
コメントアウトする、というやり方で開発しています。
しかし、事前に機能するコードが実装されていなくても、
実装したい機能をテストするコードを書くことで、
開発の指針がコンパイルエラーやテストの失敗として
示されます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
テストを実行してみます。
・・・成功しました。バーが緑になっています。
9回に渡ってテスト駆動開発を行ってきましたが、
とりあえず今回で終了です。
簡単な機能を持つクラスの作成でしたが、
一応の完成をみました。
全体の流れをまとめてみると、
1.テストコードの作成
2.テスト対象のクラスを定義する
3.コンパイルエラーを修正しながら実装
4.テストの実行
5.エラーの修正
6.3~5を繰り返す
という順で開発を行っています。
1.テストコードの作成
ここでは、開発対象となるクラスの仕様に沿って、テストを作成します。
メソッドのテストならば、特定の引数をメソッドに与えると、
結果が仕様通りに返ってくることを検証します。
条件と結果の組み合わせでテストするわけです。
今回は、動作するサンプルとして書いたテストコードを元に
開発を行ったので、開発対象のクラスに移したい機能を
コメントアウトする、というやり方で開発しています。
しかし、事前に機能するコードが実装されていなくても、
実装したい機能をテストするコードを書くことで、
開発の指針がコンパイルエラーやテストの失敗として
示されます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
2011年7月21日木曜日
Google App Engine for Java のデータストアAPIを利用するクラスをテスト駆動開発してみる(その8)
コンパイルエラーが解消されたところで、
テストを実行してみます。
結果は、
EntitySearch.getEntity()メソッドのreturn文が、
せっかくgetEntity()メソッドにコメントアウトしていた
機能をコピーしてきたのですから、
先ほどのreturn文を、
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
テストを実行してみます。
結果は、
NullPointerException
が返ってきます。EntitySearch.getEntity()メソッドのreturn文が、
return null;となっているのだから、当然です。
せっかくgetEntity()メソッドにコメントアウトしていた
機能をコピーしてきたのですから、
その結果を返しましょう。
先ほどのreturn文を、
return entitiesList;と変更します。
インストール不要・無料の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()メソッドにコピーします。
またもや、コンパイルエラーが出ます。
ループカウンタを表していた
query.addFilter()メソッドの第3引数に与えるのは、
比較対象となるプロパティ値なので、
これはgetEntity()メソッドの引数propertyValueに変更します。
これで「i」という変数はメソッド内からなくなり、
コンパイルエラーは解消されます。
インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/
単純に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/
登録:
投稿 (Atom)