Pluginのテストを自動化するには(その5-2:Eclipseのビルドをしてみた)

やっとこさビルドができましたよ。こんな感じでコマンドを打ちました。

java -jar ../org.eclipse.releng.basebuilder/plugins/org.eclipse.equinox.launcher.jar -application org.eclipse.ant.core.antRunner -DbuildDirectory=/home/kompiro/eclipse-builder/builds -Dconfigs="linux,gtk,x86" -DmapCvsRoot=":pserver:anonymous@dev.eclipse.org:/cvsroot/eclipse" -buildfile build.xml

途中CVSからうまく落とせないプラグイン(fragments:org.eclipse.swt.linux.motif.x86)を無理やり手で落としてみたりしながらやってみました。なお、ドキュメントにかかれているように-Dcomponentを使うと、まだうまく動かないので、指定しないといけないオプションが他にもあるのかもしれません。-DmapCvsRootを指定しないと、CVSのパスが間違ってるので、動きません。気をつけてください。
で、ビルドが出来上がったんですが、ビルドのスクリプトは最新版から落としてくるので、Ganymede(3.4)なんですよね。スプラッシュがさらに格好良くなってて惚れ込みました。

Pluginのテストを自動化するには(その5-2:ビルドの自動化で泣いちゃうよ編)

まぁ、仕事あるのに調べながらやるのは大変だよ。えー、前回はEclipseの自動ビルド用のプロジェクトをCVSから落としてきました。で、ここ2,3日はreadme.htmlを眺めては泣かされているのです。まぁ、ドキュメントの更新は大変だよねー。で、readme.htmlを読んで気づいたんですが、このorg.eclipse.releng.basebuilderは様々なプロジェクトのビルドをするあくまでも「ベース」であって、ビルドのプロジェクトは別途用意されていました。
でも現在まともに存在するビルドのプロジェクトはorg.eclipse.releng.eclipsebuilderだけのようです。昔はgefとか、veとかも自動ビルドプロジェクトがあったらしいですが、現在は見当たりません。ECFやMylynもCruiseControlを使ってたり、Bittenを使ってたりするんで、そいつらがどうやっているか興味津々だったりするんですが、とりあえず基本からやっちゃうんです。
org.eclipse.releng.eclipsebuilderの落し方ですが、CVSのコマンドだとこんな感じです。

cvs -d :pserver:anonymous@dev.eclipse.org:/cvsroot/eclipse export -r v20070614 org.eclipse.releng.eclipsebuilder

要するに同じタグのeclipsebuilderプロジェクトを落としただけなんデスが。
はい。落としてきたeclipsebuilderの中のreadme.htmlを見てみるとご丁寧に*OBSOLETE - contents need to be changed to reflect reorganization in structure of the scripts.*なんてかかれている訳です。確かにコマンドを叩いても動きません。Eclipse3.3のインストールフォルダからはlauncher.jarはない訳ですから。で、今日はeclipseのビルドをやってみよう!という話をして終わろうと思ったんですが、さらにお茶を濁す結果となってます。えぇ。今日はここまでですとも。実際にビルドができたらこのコンテンツは更新しようか。

Pluginのテストを自動化するには(その5-1:ということで、ビルドの自動化にも突っ込んじゃうよ)

まぁ、冬休みも終えたんで、のんびりとやらせてください。
プラグインのビルド自動化についての話はhttp://www.eclipse.org/articles/Article-PDE-Automation/automation.html:Titleが有名です。ちょっと前にはPluginbuilder - Build automation for Eclipse plug-insなんてのも出てきましたが、今回は自分の環境にビルド環境を作成するということで、割愛します。
プラグインのビルド自動化にはorg.eclipse.releng.basebuilderというツールを使いマス。このツールはダウンロードサイトでは配布していません。CVSから落とすのみとなっています。例えばEclipse3.3環境で動くプラグインのビルドをしたい場合は下記のようにCVSのコマンドを打ちます。*1

cvs -d :pserver:anonymous@dev.eclipse.org:/cvsroot/eclipse export -r v20070614 org.eclipse.releng.basebuilder

タグの番号は対象とするEclipseのバージョンごとに違うので、次のサイトで確認してください。Platform-releng-basebuilder - Eclipsepedia

CVSから落としてくるとサンプルのスクリプトがついてきています。今日は落とすところまでということでご勘弁くださいませ。

*1:Eclipseを使って落とすことももちろんできます。が、Eclipseを立ち上げるのが面倒なので、今回はコマンドで書きました。

Pluginのテストを自動化するには(その4-2:eclipse-Automated-Testsのtest.xmlを見てみる)

今日はeclipse-Automated-Testsのtest.xmlを見てみます。
runtestsスクリプトでテストするターゲットを指定します。例として『ui』を指定した場合のスクリプトを見てみると
423行目から425行目にかかれ手います。

	<target name="ui">
		<runTests testPlugin="org.eclipse.ui.tests" />
	</target>

はい。runTestsってタスクは何?って思いますよね。test.xmlの中でを使って宣言されています。って何って思った方はリンク先をどーぞ。要するにもタスクの宣言の一種でで引数を、タグでかこわれている部分を順次実行するというものですね。
runTestsマクロで何をやっているかというと、ざっといっちゃえばこのマクロ直下のjunitターゲットやperformanceターゲットへ処理を振ってます。この辺を見てみるとperformanceのテストをするためには、runtestsに-Dtest.target=performanceを設定すればいいって言eclipse-junit-tests-M20071023-1652うのもこのあたりで分かります。(readme.htmlにも書かれていますが。)Antスクリプト内で定義されているプロパティはJVMのシステムプロパティに設定された場合は上書きされます。
Cloudscapeがあると何がうれしいのかまでは追っかけません。
さて、junitターゲットとperformanceターゲットで何が違うかというとほとんど何も違いません。setupターゲットの後、ターゲットのテストプラグイン内のtest.xmlへ処理を移譲し、結果を収集しているだけです。要するに、テストプラグインの中のtest.xmlを見なきゃ実際のテストがどう動いているかわからんとです。(ちなみにsetupターゲットではSDKを解凍し、テスト用のプラグイン*1を解凍したSDKのEclipseへコピーし、CVS用の設定をするターゲットを呼び出しています。)
と言う訳で、テストプラグインの中のtest.xmlを見てみましょう。
uiのテストプラグインの中を見てみようかと思ったんですが、やっぱり説明しずらいので、osgiでご勘弁。

osgiのテストプラグインをのぞいてみる

osgiのテストプラグインですが、『eclipse-junit-tests-M20071023-1652.zip』の中の『/eclipse/plugins/org.eclipse.osgi.test_3.3.0』がそれになります。なので、この中のtest.xmlを見てみましょう。
ざっと眺めてみるとlibrary-fileというプロパティに設定されている『${eclipse-home}/plugins/org.eclipse.test/library.xml』のcore-testターゲットに処理が移譲されているというのがなんとなく見えるかと。ぉぃ*2そうなんす。このtest.xmlをコピって自分のプロジェクト用にちょちょっといじると自分のプロジェクトでも使えたりします。
後は本体プラグインとテストプラグインのビルドが自動化できていればきっとテストまで自動化できる雰囲気を感じていただけたんじゃないかと思いマス。
ということで、明日はビルドの自動化についてちょちょっと触れてみますよ。

*1:Eclipse-test-frameworkのプラグイン含む

*2:ここで指定されているcore-testターゲットはUI(ワークベンチ)を使わない場合のターゲットで、uiを使う場合はui-testターゲットを使います。

Pluginのテストを自動化するには(その4-1:eclipse-Automated-Testsの中を見てみる)

さて、今日はeclipse-Automated-Testsを動かしてみるところをやってみました。

必要なもの

ちょっと前に触れましたが、R-3.3.1.1のダウンロードサイトはこちらになります。また、直後でEclipse-SDKも必要になりますので、一緒に落としてください。

テストを実行してみる

中身を解凍してみました。以下がファイルの一覧です。

eclipse-testing/
eclipse-testing/label.properties
eclipse-testing/test.properties
eclipse-testing/org.eclipse.platform.doc.isv.javadoc.txt
eclipse-testing/org.eclipse.jdt.doc.isv.javadoc.txt
eclipse-testing/org.eclipse.jdt.apt.javadoc.txt
eclipse-testing/org.eclipse.pde.doc.user.javadoc.txt
eclipse-testing/testframework.html
eclipse-testing/runtests
eclipse-testing/test.xml
eclipse-testing/readme.html
eclipse-testing/runtests.bat
eclipse-testing/eclipse-junit-tests-M20071023-1652.zip

runtestsというファイルがテストを実行するためのスクリプトですが、このスクリプトの中ではテスト対象のEclipse-SDKを解凍するように書かれています。解凍するファイル名の対象がEclipse3.3.1.1の場合は『eclipse-SDK-M20071023-1652-*.zip』でなければなりません。先ほど落としてきたEclipse-SDKを解凍後のeclipse-testingの中へコピーし、eclipse-SDK-M20071023-1652-*.zipへ名前を変更した後にruntests(Windows環境の場合はruntests.bat)を実行してみると下記のusageが表示されます。

usage: ./runtests -os <osType> -ws <windowingSystemType> -arch <architecture> [-noclean] [<test target>][-properties <path>]

それじゃ試しに動かしてみましょうか。僕の環境は現在X86Ubuntu Linux 7.10上で動かしているので下記のようにコンソールに入力してみました。

./runtests -os linux -ws gtk -arch x86 ui 

するとものすごい勢いでEclipseのワークベンチがいくつか立ち上がり、画面が描画されていきます。最後に指定した「ui」がテストターゲットですが、EclipseのUIプラグインに対するテストを指定しました。なのでViewやPerspectiveがどんどん書き換えるテストが実行されます。パフォーマンスも同時に計測されているのです。
ここで指定した-osや-ws,-archはOS,WindowSystem,CPUのアーキテクチャを指定します。上記の例はx86系CPUで動作させているUbuntu Linux 7.10だから

-os linux -ws gtk -arch x86

と指定していました。
Windows XPの場合はバッチファイルの中でデフォルトが指定されているので不要です。-nocleanオプションや-propertiesオプション、そしてその他のテストターゲットについてはeclipse-testing/readme.htmlに書かれているので見てみてください。

runtestsの中身を見てみる

このスクリプトを見てみましょう。runtestsもruntests.batも環境が違うのですが、結局同じ事をしています。ダウンロードしてきたEclipse-SDKを解凍し、その中にあるランチャーを使ってtest.xmlにかかれたAntスクリプトを実行しているのです。Antスクリプトの実行をしている行は下記の行です。

非Windowsの場合(runtests)
$vmcmd -Dosgi.os=$os -Dosgi.ws=$ws -Dosgi.arch=$arch -jar $launcher -data workspace -application org.eclipse.ant.core.antRunner -file `pwd`/test.xml $tests -Dws=$ws -Dos=$os -Darch=$arch -D$installmode=true $properties -logger org.apache.tools.ant.DefaultLogger
Windowsの場合(runtests.bat)
%vmcmd% -Dosgi.os=%os% -Dosgi.ws=%ws% -Dosgi.arch=%arch% -jar eclipse\plugins\%launcher-jar% -data workspace -application org.eclipse.ant.core.antRunner -file test.xml %tests% -Dws=%ws% -Dos=%os% -Darch=%arch% -D%installmode%=true %properties% -logger org.apache.tools.ant.DefaultLogger

この中の『-application org.eclipse.ant.core.antRunner』がEclipse上に配置されているAntの実行をするためのアプリケーションになります。おや?普通のAntではダメなのでしょうか。えぇ、通常のAntではテストの自動化やビルドの自動化はできません。そもそもプラグイン同士のクラスローダーの解決をするためにはOSGiフレームワーク上で稼働している必要があります。また、Eclipse上のAntでは独自のタスクが登録されているのです。test.xmlが実行されているのがお分かりいただけたのではないかとおもいます。

eclipse-Automated-Testsの中のtest.xmlを見てみる

すいません。明日test.xmlを見てみます。

Pluginのテストを自動化するには(その3のあとがき)

えぇと、前回ちょっとズルをしてみたんですが、気づかれましたかね。とりあえずコンソールから実行するために『-configurationや-devなどの指定はEclipseから実行したときのものをコピーしてきました』が、開発中のワークスペースをそのまま使って自動化する事はほぼ「ありえません」。なぜなら、テストの自動化の目的は、CI、「Continuous Integration」ですよね。継続的に結合テストを行うことが目的です。なのである開発中のワークスペースを定期的にアップデートして、ビルドして…。という訳にはたぶんいかないでしょう。テストの自動化をするためには、自動的にプラグインをエクスポートをする環境、ビルドの自動化が出来ていて、かつ本体プラグインとテストプラグインを稼働対象のターゲットEclipseに自動的に配置できるっていうのが前提条件になります。要するに「ビルドの自動化」ができなければお話にならなさそうだというのが分かりました。
なお、期待させてくれた『eclipse-Automated-Tests-*.zip』の中を調査してみましたが、これはEclipse IDEのテストを自動化するためのフレームワークとして配布されているもので、自作プラグインのテスト自動化をしてくれるものではありませんでした。ですが、Eclipse IDEのテストがどうやって自動化されているかを見てみるのはおもしろいでしょう。今日はもう遅いので、明日ここのあたりから解説していきます。

Pluginのテストを自動化するには(その3-2:テストクラスをHeadlessで動かす:後編)

さて、今日はeclipse-test-frameworkを使ってPluginのテストを実行してみましょう。eclipse-test-frameworkはEclipseのダウンロードサイトにあります。Eclipse Project Downloadsからテストを実行する環境のEclipseのバージョンを選びましょう。例えば2008/01/03現在のStableは3.3.1.1なので、Latest Releaseの3.3.1.1を選びます。画面真ん中に『JUnit Plugin Tests and Automated Testing Framework』という項目が
あります。ここにあるeclipse-test-framework-3.3.1.1.zipをダウンロードしましょう。(その直下にeclipse-Automated-Tests-3.3.1.1.zipなんて気になるもんもありますが、今日はそこは触れないよ!たぶん明日か明後日か?)ちなみに3.3.1.1はリリースバージョンですので、他のバージョンを選んだ人は他のバージョンに適宜読み替えてください。

Eclipse Test Frameworkのセットアップ

さて、ダウンロードしてきたeclipse-test-framework-3.3.1.1.zipですが、Eclipseのプラグイン開発環境ではないEclipseを別途用意して、そちらに解凍してください。いつも使っている開発環境としなかったのは、自分が作成しているプラグインの古いバージョンがいつも使っている開発環境に入ってたりしないですか?この状態ですと古いバージョンを先に見つけてテスト対象になってしまいます。またPlug-inのエクスポートがうまく動かない事もあるので、別のEclipse環境を作成してそれをTarget Platformに指定しておきましょう。Target Platformの指定方法ですが、『Window - Preferences』を選んだ後、『Plug-in Development - Target Platform』を選び、Locationに作成したEclipse環境を指定してください。

Eclipse Test Frameworkを覗いてみる

次に用意されているプラグインの中をちょっと覗いてみましょう。Package Explorerで『右クリック->Import』を選び『Plug-in Development->Plug-ins and Fragments』を選んでNextを押下ください。すると下記の画面が表示されます。

『Import From』の部分はTarget Platformのまま、『Import As』の部分だけ『Projects with Soruce Folder』に選択し直して、Nextを押下してください。
最後に『Plug-ins and Fragments Found』から『org.eclipse.test』を選び、Finishをします。『Plug-ins and Fragments Found』から探すのは骨が折れるので、『Locate Plug-ins and Fragments』で『org.eclipse.test』を選んでAddするといいです。
インポートが終わるとlibrary.xmlというAntスクリプトやtestframework.htmlというドキュメントが入っています。testframework.htmlは英語でかかれていますがいいドキュメントなので一度目を通すことをお勧めします。この記事はこのドキュメントを見て、『もしかしていらないかも』と思いました。
library.xmlEclipse Test Frameworkを実行するためのAntスクリプトです。このスクリプトファイルを使って定期実行すれば自動テストが出来ていると言えます。とりあえずコマンドラインでどう実行するかをまず見てみましょう。
試しに書いてみました。

java -jar plugins/org.eclipse.equinox.launcher_1.0.1.R33x_v20070828.jar
 -application org.eclipse.test.uitestapplication -consolelog
 -data /home/kompiro/code/workspaces/rss-reader/../junit-workspace formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,result.xml 
 -configuration file:/home/kompiro/code/workspaces/rss-reader/.metadata/.plugins/org.eclipse.pde.core/pde-junit/ 
 -dev file:/home/kompiro/code/workspaces/rss-reader/.metadata/.plugins/org.eclipse.pde.core/pde-junit/dev.properties 
 -os linux -ws gtk -arch x86 
 -testPluginName org.kompiro.percs.rss.test 
 -className org.kompiro.readviewer.rss.TestRssService 

-dataは開発中のコードが含まれたワークスペースです。formatterはXML形式で出力するために指定しています。「,」区切りでファイルの指定が出来ます。-configurationや-devなどの指定はEclipseから実行したときのものをコピーしてきました。これらの指定がないとテストプラグインが発見されません。-osや-ws、-archもEclipseから実行したときのものをコピーしました。OSとウィンドウシステム、CPUアーキテクチャですね。-testPluginNameはテスト対象のプラグインの名前、-classNameはテスト対象のクラスです。
ここまで来てみてまた壁にぶつかりました。実はJUnit4にこのフレームワークは対応していないようなのです。正確に言うとJUnit4にantが対応しておらず、JUnit4側が動作するようにアダプタを提供しているんですが、OSGiの機能で同一クラスローダーで動作出来ません。たぶんちょこっと環境をいじってあげる必要があるでしょう。
試しにJUnit3形式に書き直したところ、動作しました。これにはまって2時間とかつぶれて疲れたので、残りはまた明日。たぶんlibrary.xmlを使ってAntスクリプトを書くあたりに触れていく予定です。