ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

iアプリ版「Googleマップ」が登場

2007-08-21 22:21:57 | Weblog

ここのニュース
iアプリ版「Googleマップ」が登場
http://headlines.yahoo.co.jp/hl?a=20070821-00000011-imp-sci

衛星からの航空写真版のほうも見れるみたい。。

たのしそう(^^)


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

開発の初めから順番に書いていってみる その79:単体テスト(4)ドライバとしてのJunit

2007-08-21 19:46:10 | 開発ネタ

シリーズ「開発の初めから順番に書いていってみる」の続きです。

 設計手順には、要求分析、外部設計、内部詳細設計・プログラミング、単体テスト、結合テスト、総合テスト、運用テスト及び運用とあります。
 (バックナンバーは、ここ http://www.geocities.jp/xmldtp/index_kaihatsu.htm)。
 今回は、前回次回は、上記に挙げた、テストドライバとJunitの関係についてみてみたいと思います。どこが、形式化されているのかなどについてですと書いたことについてです。




■JUnitと、普通のテストのドライバの違い

 JUnitと普通のテストのドライバでは、
・JUnitのjarをパスに通さないといけない
・実行するとき、JUnitから、テストドライバを実行する形になる
  →Eclipseの場合、Jarを通すだけではない

などの、操作上の違いは、もちろんあります。
 もちろん、その結果として、見え方も違います。緑(青?)や赤の線が出たり。

 しかし、ドライバという点で見ると、ドライバの書き方が、フレームワーク化した、形式化したということのほうが、大切です。
 具体的に、どう形式化したのかをみてみます。




■JUnitでのドライバのソース

 JUnitでも、テスト対象となるプログラムには、手を加えません。
 テストをするドライバのほうを、形式化します。

 では、前回の5,1,0,-1の階乗を求めるプログラムは、どうなるかというと、
 こんなかんじ。

import junit.framework.TestCase;

public class KaijyoTest extends TestCase {

	/*
	 * コンストラクタが必要になります
	 */
	public KaijyoTest(String arg0)
	{
		super(arg0);
	}
	
	/*
	 * メソッド名のはじめを大文字にして、testをつけたメソッドがテストメソッドです
	 * つまりkaijyoのテスト
	 */
	 public void testKaijyo()
	 {
	 	//	assertでたしかめます。
		assertEquals(120,Kaijyo.kaijyo(5));
		assertEquals(1,Kaijyo.kaijyo(1));
		assertEquals(-1,Kaijyo.kaijyo(0));
		assertEquals(-1,Kaijyo.kaijyo(-1));
	 }
}



 junit.framework.TestCase;をインポートするのは、まあ、JUnitをやっているのでいいとして、クラス名と、メソッドのテスト方法が、以下のように決まっています。

・クラスは、テスト対象にTestを付けて、TestCase等から(ほかもある)extendsする
・コンストラクタ(引数String arg0)をつくる
・メソッドのテストは、「testメソッド名の初めは大文字」とする
・そこに、assertEquals等を使って、「こうなるはず」というのを書く。

このように書き方が決まっています。




■ということは・・・

JUnitは、書き方が決まっているというだけで、これを使ったから、テストの品質があがるというものではないです。テストの品質は、あざやかなテストケースを作ることですが、JUnitがテストケースを考えてくれるわけではないので、JUnitを使えばテストが網羅されるというわけではないです。

 現に、境界値である
assertEquals(-1,Kaijyo.kaijyo(0));
 というテストケースを除いても、別に怒られないです。
 でも、この境界値をテストするかどうかが、テストの品質にかかわってくるわけです。




ということで、JUnitによる、テストの形式化の話はおしまい。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

在庫テーブルの存在意義というか、DBの現在データと履歴データの違いというか。。

2007-08-21 13:57:30 | Weblog

 あるところで、こういう話を聞いたことがある。

「在庫テーブルは不要である。入庫データと出庫データの総和にすぎないから」

 これは、極論だけど、(創業時からの入庫データの総和ー出庫データの総和など、求められるわけではないので)仮に、求められたとしても(つまり、創業時データから保持できる巨大なDBと、総和を求められる超高速計算機があったとして)、果たして、そうなのか?




 入庫データと出庫データから、在庫を求めた場合、在庫を求めた瞬間は、現在値(現在の在庫数)です。でも、求めた瞬間に、過去の値になります。

 そのあとに、出庫されたり、入庫されたりするかもしれないので・・

 たとえば、在庫が2個あったら、出庫して、商品を発送する。
 なかったら、注文自体をキャンセルするということを考える。

このとき、在庫を入出庫からもとめるとすると、

・はじめに、在庫を検索、表示
  →入出庫の総和からもとめる
  →この時点で、3個の在庫があったとする

・この直後、2個出庫。
  →在庫3-2=1個になるので、キャンセルしないといけない

・でも、表示上では、3個の在庫があることになっているので、
 出庫しようとする
  →たりなくなる。

 これを、防ぐためには、実際の出庫をする直前に、再度総和をもとめるか
といっても、求めた瞬間にまた・・・
 とか、そもそも、そんなに総和をみんなで求められたらたまったもん
じゃあありません。
 
 あと、引き当てデータを作るという手もあるのですが、これは
処理が複雑になります。




 このように、過去の履歴から、現在値をもとめると、その瞬間は現在値なのですが、その直後から、過去の値になってしまうため、それを現在値と信じて処理すると、おかしなことになります。現在値は、現在値を保証するところが必要になってきます。

 現在値の保証は、

・テーブルに値とタイムスタンプがある
・更新するとき、そのタイムスタンプ値が、検索したときのものと同じかどうか
  →おなじなら現在値、違えば誰かが更新したのでキャンセル

ということでできます。タイムスタンプでなく、更新カウンタでもOKです。




ということで、現在値を持っているテーブルとして、在庫テーブルがあったほうが望ましいわけです。
これなら、

・在庫テーブルを検索する
  →3個あった。この時点でタイムスタンプも取得
・他で、2個出庫した
  →2個出庫した時点で、タイムスタンプが変わる
・もとの人が2個出庫しようとする
  →2個在庫を引く=>ただし、タイムスタンプが同じとき
  →でも、実際には、タイムスタンプが違うので、更新されるのは0件
  →更新件数0なら、他で更新されたものとしてエラーにする

というふうにすれば、話はかんたん。




というわけで、現在値を保証するテーブルと、過去の履歴を見るテーブルは分けたほうが良く、現在値を保証するテーブルとして、在庫テーブルがあると思う。




  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする