FlashDevelop で flexcover を動かしてカバる
テストには flexunit4を、そのテストケースがコードを網羅しているかの確認に、 flexcover が使えます。今回は flexcover の環境を整えて、実際に使ってみます。
環境構築
flexcover ダウンロード、展開
Google Code Archive - Long-term storage for Google Code Project Hosting.
↑の「Downloads」から「flexcover-0.81.zip」をダウンロードし、適当な場所に展開します。展開して出来たフォルダ名は「flexcover-0.81」とします。
flexcover 用 Flex 3 SDK 構築
既存の Flex 3 SDK のフォルダをコピーし、フォルダ名を「flexcover_sdk_3」に変更します。(何でもいいです。)
展開してできたフォルダ「flexcover-0.81」中の「sdk-modifications-3_2」フォルダの中身(frameworks、lib)を「flexcover_sdk_3」へ上書きコピーします。
FlashDevelop グローバル設定
コンパイルに使う Flex SDK を切り替え。「Tools>Program Settings...>AS3Context>Language>Flex SDK Location」に上記「flexcover_sdk_3」のパスを設定。
FlashDevelop プロジェクト毎の設定
「Project>Properties>Compiler Options>Advanced>Additional Compiler Options」へ「-coverage-metadata=<任意のファイルパス>.cvm」を設定。
flexcover を使ってみる
CoverageViewer のインストール
「flexcover-0.81」フォルダ内の「CoverageViewer.air」を実行します。
CoverageViewer でカバレッジを見る
インストールした CoverageViewer を実行します。
「Load Files...」ボタンを押して環境構築確認で見た cvm ファイルを選択します。
この段階では未実行ということで、全実行回数は 0 件、カバレッジは 0% です。問題ありません。
続いて環境構築確認のコンパイルで出来た swf ファイルを実行します。適当にいじり倒します。
実行後、 CoverageViewer 画面を確認すると、実行結果が反映されます。今回は MyGameLib のテストを実行しました。テストスイート以外、全コードが 100% 実行できていることが分かります。今のところ、テストでコードの全経路は実行できているようです。よかったよかった。
後はコード修正、コンパイル、swf 実行でカバレッジは見ていけるようです。ソースファイルが増えたら、cvm ファイルを読み直して swf 実行...という流れでいけるようです。
後書き
これでケース漏れを視覚で確認できますね!!!!!!!!!!!!!!!!!!!!1
TDDのケース漏れ対策
テスト駆動型開発(TDD)というのが面白くて、今後この方向でコーディングしていこうと思ってます。しかしテストケース漏れの有無ってのをある程度客観的に判定できなければ、結構キケンに思いました。自分のさじ加減でケースを挙げているようで...。
なんかこういうケース漏れの判定に、カバレッジの測定ツールってものがあるみたいですね。flexunit4ではFlexcoverとのこと。これは興味深い。これで上記の不安がふっしょくできればいいのですが!
参照があいまい
このコードって、「参照があいまい」と怒られます。
インターフェースがインターフェースを多重継承して、同じメソッドを実装した場合、どこかしらあいまいな様子...。
よく分からんなぁ。
package { import flash.display.Sprite; public class FlashTest extends Sprite { public function FlashTest() { // write as3 code here.. var test:ITest0 = new TestClass(); test.x = 0; } } } class TestClass implements ITest0 { public function get x():Number { return 0; } public function set x(value:Number):void { } } interface ITest0 extends ITest1, ITest2 { } interface ITest1 { function get x():Number; function set x(value:Number):void; } interface ITest2 { function get x():Number; }