ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

Apache Hadoop 2.1.0-beta・Windows

2013-08-31 09:27:54 | TRPG

Apache Hadoop 2.1.0-betaがWindowsに対応したらしいので、インストールしてみた

ちょっと前からHortonworksがHDP(Hortonworks Data Platform 1.1 for WindowsでWindows用Hadoopを出しているが、対象がWindows Serverだったり、スタンドアローンモードのインストール手順が無さそうだったりするので、開発環境としては(公式には)使えない感じだった。
で、Windows用のバッチファイル類だけApache Hadoopに入れてくれないかな~と思っていたんだけど、今回の2.1.0-betaはそういうようにしてくれた気がする。
hadoop.cmdとか、部分的に異なるけど、大部分は同じだし。

で、2.1.0-betaだけど、インストール作業はダウンロードしてきたアーカイブを解凍するだけですぐ済んだんで、インストール自体は簡単。
環境変数も、必要なのはJAVA_HOMEだけで、HADOOP_HOME等のHadoop用環境変数は一切不要。
ただし、JAVA_HOMEに空白入りのパスを指定できない(つまりWindowsの標準の場所(Program Files)にインストールしたJavaは使えない)。これはHDPもそうだったんで、対応する気は無いんだろうな^^;

で、単なるhadoopコマンドとか「hadoop version」「hadoop classpath」辺りは動いたんだけど、サンプルを実行したらこけたorz
少しだけ色々試してみたが、まだ解決できていない。
つーか、必要なexeファイルやDLLファイルがアーカイブに含まれていないのはおかしいでしょう^^;
まだベータ版だから仕方ないのかもしれないけどさぁ(苦笑)

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

Eclipseプラグイン更新サイトのUTF-8バグ

2013-08-29 23:15:39 | PG(Java)

Xtextで作ったエディターに対する更新サイトを作ったら、更新サイト経由でインストールしたプラグインで変なエラーが出た。
色々調べた結果、Windowsにおいて、UTF-8で書いたソースをビルドする際に文字化けしてエラーが発生することが分かった。
MS932で書くと通る。
Eclipse3.7(indigo)、4.2(juno)、4.3(kelper)でも発生したので、昔から発覚していないのかな??

不可解なのは、以前から作っているDMDL EditorではUTF-8にしているのに、特にエラー(文字化け)は起きてないんだよね。
他にも何か条件があるのかもしれない。

(2013/08/30追記)
という訳で、プラグインプロジェクトのbuild.propertiesにエンコーディングを指定できる(DMDL Editorでは指定していた)のを発見!
まぁ、デフォルトでワークスペースのエンコーディングを見てくれないのはバグだ、ということにしておきたい^^;
とほほーorz 

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

目指せ!カバレッジ100%

2013-08-20 22:22:22 | PG(Java)

Javaのprivateのテストについて書いていて思い出したので、カバレッジについて書いておく。

「カバレッジは100%でなくてもよい」という標語も、言葉が抜けているような気がするんだよね。


「カバレッジ」とひとことで言っても種類が色々あるらしいことは知っているのだが、自分はテストについて勉強しているわけではないので、種類まではよく知らない^^;
でも命令網羅・分岐網羅は100%になるべきだろう。

以前、HBase0.20のシェルでバグを踏んだことがあるけど、これなんかその部分を実行するテストをやっていれば(命令網羅100%ならば)、絶対発覚したはずのバグだし。
(もっと言えば、変数をちゃんと定義してコンパイルする言語で書かれていれば、(テストするまでもなく)コンパイルエラーになったはずなんだが)

プログラミング(コーディング)しているのに、その箇所を動かしていないというのは有り得ないよ(憤)

Javaの場合、テストできないのって、Cloneableに関するCloneNotSupportedExceptionをキャッチしている部分くらいのものだと思う。
switch文も、(コーディング規約によってdefaultを強制されている場合等は)実行されないケースがあるかもしれないけど。


もうひとつ、「カバレッジ」という語が指しているのが「自動テスト(JUnit)によるカバレッジ」ということなら、100%は難しいこともあるかもしれない。
例えば画面系のテストなんかは、自動テストは面倒だよね…。

「カバレッジは100%でなくてもよい」と言っている人は、どういう意図で言ってるだろうな??

コメント (2)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

続・privateのテストがしたいです

2013-08-19 12:37:58 | PG(Java)

先週privateメソッドのテストがしたい話を書いたけど、2点補足。


まず、テストを実際にやる方法について。

自分はprivate相当のメンバーの可視性は、なるべくpackage privateにする。settter/getterがあったり、テストに直接は関係無さそうだったらprivateにする。
(つまり、「privateにする=直接はテストしない」という意味でprivateを使っていることになる^^;) 

コーディング規約とかでどうしてもprivateのままにしてテストをしないといけないなら、リフレクションを使うしかない。
けど、リフレクションはちょっと手間がかかるし、メソッド名やフィールド名を文字列で指定すると、不一致だった場合にコンパイルエラーになってくれないので、あまり好きではない。

privateメソッドをクラスにするという方法もあり、メソッド分割だけでなくクラスに分割した方がいい場合もあるという事については大いに賛成。
ただ、その場合のクラスの可視性については、自分はprivateにしたいと思う。
前回の例(ID0001Logicクラス)で言えば、 値を算出するのはLogicクラス自身の責務なので、機能を分割して下請けクラスを作るにしても、その下請けクラスはLogicクラスからだけ参照できるようにするのが筋だと思う。
この下請けクラスがpublicやpackage privateでいい(Logicクラス以外からも呼び出せても構わない)のであれば、そもそも当初のLogicクラスのcalculateメソッド自身もpublicやpackage privateでいい(Logicクラスの外から呼び出せても構わない)はず。 

Javaの場合は、クラスの可視性をprivateにするにはインナークラス(厳密にはnested classらしい)にする必要がある。
で、privateなインナークラスは、やっぱりテストクラスからはアクセスできないという問題があり、「クラスにする」というだけでは解決にならない。 
(解決策として言われる「クラスにする」というのが「publicクラスにする」という意味だったら、やっぱりもやもやする…)

(とは言え、下請けクラスは自分しか使わない(はずの)ユーティリティーのようなものだとも思えるので、それならpublicでも構わないのか…?) 


もうひとつは、メソッド分割(クラス分割)を何の為に行うのか?ということ。

分割すると責務の範囲とかソースの見た目が分かりやすくなる・構造を理解しやすくなるというメリットはあるけど、自分はテストのしやすさの為に分割している気がしてきた。

例えば、

public void execute() {
  if(isTarget()) process1(); else process2();
}

private boolean isTarget() {
  return 複雑な判定;
}

private void process1() {
  複雑な処理
}

private void process2() {
  複雑な処理
}

このようなソースの場合、executeの中に全部を書くことが出来るけど、isTarget・process1・process2を別々にテストする方が効率がいいと思う。
executeの中に全部書いていたら、isTargetの中に相当する部分をテストするのにprocess1やprocess2も絡んできてしまう。


結論として、可視性とテスト実施有無は、本来は関係ないと思う。
Javaがprivateメンバーに外部からアクセスできないから問題になるのであって、「privateのテストがしたいというのは間違い」はやっぱり間違っていると思う。

テストクラスだけはフルアクセス可能にするような仕組みがあるといいんだけどなぁ。
C++のfriendみたいなものが欲しかった^^;
(下手にそういう構文を用意してしまうと、意図を理解していない人がテストコードだけでなくプロダクトコードに対しても使ってしまいそうで、微妙だけど(苦笑)) 

コメント (1)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

先生、privateメソッドのテストがしたいです

2013-08-13 23:45:04 | PG(Java)

Javaでprivateメソッドをどうやってテストするかについて、不定期に話題にあがるんだけど。
「publicメソッドだけテストすればいい、privateメソッドをテストしたいというのはおかしい(設計(実装方法?)が間違っている)」という意見を聞いたことがあるが、違和感を持っていた。

で、「publicメソッドのテスト=仕様に基づくテスト=ブラックボックステスト」「privateメソッドをテストしたい=ホワイトボックステストをしたい」という事なのかもしれない、と思い付いてブログを書こうと思ってたんだけどDQ10が忙しくてさぼっていたら、
kencobaさんが『どうしてもprivateメンバをテストしたい人に対する、Unit4での解決案』でホワイトボックステスト・ブラックボックステストについて触れていた。(いやぁ、ブログをさぼると他の人が書いてくれて、ラッキー(爆))
その中で、「JUnitはブラックボックステストを前提としている」とあって、びっくり!なんと、そうだったのか!それならホワイトボックステストが出来なくても仕方ないなぁ
と思ったんだけど、ちょっと待って。後工程の結合試験や総合試験は、どうしたってブラックボックステストになるよね。先頭の単体試験(JUnit)でホワイトボックステストをしなかったら、どこでやるんだ…??

というところにタイムリーな記事が、渡辺 修司さんの『ブラックボックステストとホワイトボックステスト』。
「ユニットテスト(単体試験)はホワイトボックステストとブラックボックステストを組み合わせて行います」とのこと。
そりゃそーだよなー、ホワイトボックスとブラックボックスはテストの観点の話だから、工程とかあまり関係無さそうだもの。JUnitでホワイトボックステストをしても別に問題は無いわけだ。


ちなみに、自分がprivateメソッドのテストをしたいと思うのは、複雑な機能をメソッド分割して分離し、それぞれをテストしていきたいと思うから。
例えば以下の様なクラスを想定している。(どこぞのSIerっぽい雰囲気^^;)

public class ID0001Logic extends BusinessLogic {
  @Override
  public void execute(String key) {
    DAO dao = super.getDatabaseAccessObject();
    Record record = dao.selectByKey(key);
    record.setValue3(calculate(record.getValue1(), record.getValue2());
    dao.update(record);
  }

  private int calculate(int value1, int value2) {
    // 副作用の無いメソッド
    return ~; // 複雑な計算
  }
}

publicなのはexecuteメソッドだけだが、ロジックを切り出して、副作用の無いcalculateメソッドを作っている。calculateメソッドは他から呼ばれないので、普通の感覚ならprivateにするのは当然だろう。
でも、どう見ても、calculateをテストしたいと思うんだが、違うだろうか?
(もちろんexecuteメソッドもテスト対象だけど、テストパターンを色々実装する事を考えると、calculateメソッドを直接テストする方が遥かに楽) 


個人的には、こういうケースではpackage privateにする(可視修飾子を付けない)。

というか、オブジェクト指向はクラスを継承しメソッドをオーバーライドして部分的な修正を加えることで利便性(生産性)を上げるものだと思う。
が、フレームワークを作る人は可視範囲を制限しようとする。(カプセル化の考えからすれば当然なんだけど(苦笑))
フレームワークを利用する側(自分)としては、ちょっとだけ違う機能を加えたくて、オーバーライドできれば綺麗に作れるのに…ということが時々ある。(AntのCopyTaskとか、再利用したかったのに、出来ないし!)
そういう訳で、個人的にはprivateとかfinalとか使うの反対!(暴論w)
拡張する人の自己責任は当然なので、メソッドもフィールドも全部final無しのprotectedにしといてよ~(笑)

(先の例で言えば、calculateメソッドをprotectedにしておく(実際には、calculateメソッドが複雑であればさらにメソッド分割するはずなので、それらも全てprotectedにしておく)。すると、ID0001Logicを継承したサブクラスで一部のメソッドだけ変更して使える。これがprivateだと、コピペするしかなくなる(苦)(まぁ、どちらも自分の管理下にある場合は、オーバーライドしたくなった時にprotectedに変えればいいんだけどさ)) 


最後にもうひとつ、設計とテストの関係について。
テストは、設計書に書かれた内容が実現されているかを確認する為に行うものだと思う。
「要件定義書に書かれていることを確認する→総合試験」
「基本設計書に書かれていることを確認する→結合試験」
「詳細設計書に書かれていることを確認する→単体試験」といった感じ。
つまり、テストは本質的にブラックボックステストになる。

ここにもうひとつ、「プログラム設計書の確認→単体試験」という関係があると思っている。
プログラム設計書は、メソッドからロジックまで全部書かれている想定。しかし現在のプログラミング技法では、プログラム設計書は書かず、プログラムを直接記述する。
だから、この単体試験は、本来は「プログラム設計書を元とするブラックボックステスト」なのだが、実際は「プログラム設計書=プログラム」なので、プログラムを見て試験項目を抽出したテスト、すなわちホワイトボックステストになる。
言い直すと、「ホワイトボックステストは、プログラム設計書を元とするブラックボックステストである」。 

とも考えられると思うんだけど、どうかなぁ?

そしたら、privateメソッドも(本来はプログラム設計書に書かれているのでブラックボックステストの)テスト対象であり、「privateメソッドをテストしたいというのはおかしい」という話にはならないと思う。

コメント (4)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする