Transcript
Page 1: Unit testing JavaScript with JUnit/JavaFX

JUnitでJavaScript

テスト

Fx-Js-JUnitの紹介

Page 2: Unit testing JavaScript with JUnit/JavaFX

おことわり

● この発表ではJavaFXの話はほとんど出てきません。

● JavaScriptの話を延々とします。

● あらかじめご了承下さい。

Page 3: Unit testing JavaScript with JUnit/JavaFX

誰?

● 名前 : @mike_neck● 所属 : 無職

○ 1日9時間勤務で18時定時で昼1時間の休憩に加えて3時間昼寝できる会社探しています。

● 職業 : プログラマー○ Groovy / JavaScript / Java

● ブログ○ mike、mikeなるままに…

Page 4: Unit testing JavaScript with JUnit/JavaFX

本日のテーマ

● JavaでJavaScriptをテストする○ Fx-Js-JUnitの紹介○ 技術接近遭遇、的な○ 名状しがたい…

Page 5: Unit testing JavaScript with JUnit/JavaFX

ところで…

Page 6: Unit testing JavaScript with JUnit/JavaFX

JavaScriptのテストどう

していますか?

Page 7: Unit testing JavaScript with JUnit/JavaFX

QUnitjQueryのテストでも使われているシンプルかつ強力なテストフレームワーク。Phantom.jsでCUIから操作可能。JavaScriptでテストを記述。

Page 8: Unit testing JavaScript with JUnit/JavaFX

Seleniumブラウザーの自動操作ツール。Selenium Web Driverを用いてUI系のテストが記述できる。画面がボコボコ立ち上がるのがうざい。

Page 9: Unit testing JavaScript with JUnit/JavaFX

JavaでJavaScriptのテス

トが書けて、かつうざくな

い奴が欲しいと思いませ

ん?

Page 10: Unit testing JavaScript with JUnit/JavaFX

そこでFx-Js-JUnitで

すよ!

Page 11: Unit testing JavaScript with JUnit/JavaFX

Fx-Js-JUnitを三行で

説明せよ!

Page 12: Unit testing JavaScript with JUnit/JavaFX

Fx-Js-JUnitを三行で説明せよ!

● JavaFX2.0のWebEngineを用いたテストツール。

● JUnitで型安全にJavaScriptのテストができる。

● ブラウザーが立ち上がらないのでうざくない!

…ニャル子、あかちゃんつくろ

Page 13: Unit testing JavaScript with JUnit/JavaFX

そうそう、JUnitの説明は

省きますよ

Page 14: Unit testing JavaScript with JUnit/JavaFX

詳しくはWeb + DB プレス

#69のJUnit特集で

Page 15: Unit testing JavaScript with JUnit/JavaFX

JUnit

Server JavaFX

Test

Page 16: Unit testing JavaScript with JUnit/JavaFX

サンプルテストコード

@ClassRuleprivate static UseFxJsJUnit fxJsJUnit = UseFxJsJUnit .address('http://www.google.com') .identifiedBy('TestClass').get();

private JsJUnit jsJUnit;

@Beforepublic void setUp () { jsJUnit = fxJsJUnit.getTester();}

@ClassRuleでテスト前にJavaFXアプリケーションを起動

JavaScriptのインターフェースを取得

Page 17: Unit testing JavaScript with JUnit/JavaFX

サンプルテストコード

@Testpublic void longTest () { assertThat(jsJUnit.callLong(Integer.MAX_VALUE + " + 1"), is (Integer.MAX_VALUE + 1L));}@Testpublic void personTest () { Person person = new Person(); person.setName("mike"); person.setAge(35); assertThat(jsJUnit.callAs("{name : 'mike', age : '35'}", Person.class), is (person));}

型Longを期待するテスト実行

型Personを期待するテスト実行

Page 18: Unit testing JavaScript with JUnit/JavaFX

Fx-Js-JUnitJavaScriptのテストが

Page 19: Unit testing JavaScript with JUnit/JavaFX

カターンゼン

型安全

Page 20: Unit testing JavaScript with JUnit/JavaFX

Fx-Js-JUnit< `・ω・´ > ヨロシク

Page 21: Unit testing JavaScript with JUnit/JavaFX

The End

Page 22: Unit testing JavaScript with JUnit/JavaFX

Page 23: Unit testing JavaScript with JUnit/JavaFX

……

Page 24: Unit testing JavaScript with JUnit/JavaFX

………

Page 25: Unit testing JavaScript with JUnit/JavaFX

すんません

調子こきました

Page 26: Unit testing JavaScript with JUnit/JavaFX
Page 27: Unit testing JavaScript with JUnit/JavaFX

技術

Page 28: Unit testing JavaScript with JUnit/JavaFX

JavaScriptを型安全に取り扱うために

● JavaFXスレッドの理解● 並列処理を構成する部材の

理解● JavaScriptオブジェクトから

Javaオブジェクトへのマッピング

Page 29: Unit testing JavaScript with JUnit/JavaFX

JavaFXスレッドの理解-1

● アプリケーションを起動した後の部分のコードはアプリケーション終了後に実行される

↑Platform.exit(); の後に実行される。

Application.launch(App.class);doSomething();

Page 30: Unit testing JavaScript with JUnit/JavaFX

JavaFXスレッドの理解-2

● UIを構成するオブジェクトへの操作、結果の取得はJavaFXスレッドを介する必要がある。

WebEngine engine;

engine.executeScript("1 + 1");

Platform.runLater( { engine.executeScript("1 + 1");});

Page 31: Unit testing JavaScript with JUnit/JavaFX

JavaFXスレッドの理解-3

● UIを構成するオブジェクトはJavaFXスレッド上で生成しなければならない

JavaFX Threadengine = new WebEngine();

Main ThreadWebEngine engine;

WebEngine

Page 32: Unit testing JavaScript with JUnit/JavaFX

JavaFXスレッドの理解-まとめ

● JUnitからWebViewを操作するために

○ JUnitとは別のスレッドからJavaFXアプリケー

ションを起動

○ 別のスレッドに演算させた結果を待機して、

取得

○ JUnitはJavaFXスレッドでインスタンス化され

たオブジェクトへの参照を取得

Page 33: Unit testing JavaScript with JUnit/JavaFX

並列処理を構成する部材の理解

● java.util.concurrent.ExecutorService○ 別スレッドの処理を簡易に記述○ JavaFXアプリケーションの起動にも

ちいる● java.util.concurrent.BlockingQueue<T>

○ JavaFXスレッドからのメッセージング(値のやり取り)に使用する

● javafx.application.Platform○ JavaFXへの操作を提供

Page 34: Unit testing JavaScript with JUnit/JavaFX

並列処理を構成する部材の理解

詳しい話は下記の書籍を参照。

Java並行処理プログラミング

3,990JPYくらい。

http://goo.gl/UUzc1

Page 35: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

WebEngineのAPIよりhttp://docs.oracle.com/javafx/2/api/javafx/scene/web/WebEngine.html

JavaScript values are represented using the obvious Java classes: null becomes Java null; a boolean becomes a java.lang.Boolean; and a string becomes a java.lang.String. A number can be java.lang.Double or a java.lang.Integer, depending...If the result is a JavaScript object, it is wrapped as an instance of the netscape.javascript.JSObject

Page 36: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

JavaScript Object

typeof value

Java Object

null object null

false boolean java.lang.Boolean

23 number java.lang.Integer

1.10 number java.lang.Double

"script" string java.lang.String

Page 37: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

WebEngineのAPIよりhttp://docs.oracle.com/javafx/2/api/javafx/scene/web/WebEngine.html

JavaScript values are represented using the obvious Java classes: null becomes Java null; a boolean becomes a java.lang.Boolean; and a string becomes a java.lang.String. A number can be java.lang.Double or a java.lang.Integer, depending...If the result is a JavaScript object, it is wrapped as an instance of the netscape.javascript.JSObject

Page 38: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

┌(┌ ^o^)┐ JSObject...

Page 39: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

Plain Old JavaScript Object (POJSO)なら

JSObject#getMember()でマッピングが可能

{name : "cthuga", str : 80, con : 120, siz : 140, pow : 42}

JSObject cthuga = ...;assertThat( (String)cthuga.getMember("name"), is ("cthuga") );

Page 40: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

SAN値を減少させるオブジェクト…

Page 41: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

JSObject date = ...;date.getMember("year");

JSExceptionが発生する

Dateオブジェクト…

Page 42: Unit testing JavaScript with JUnit/JavaFX

JS→Javaオブジェクト

JavaScriptのDateオブジェクトにはメソッドはあるが、メンバーは存在しない。

←Dateオブジェクトにはメンバーがない

←POJSO

Page 43: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

ちなみにJavaScriptでちゃんとメンバーの隠蔽化がなされたオブジェクト…var Encapsulation = function() {

var count = 0;this.addAndGet = function () {

count ++;return count;

}};var counter = new Encapsulation();return counter;

Page 44: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

そういったオブジェクトもメンバーを持ちません。

Page 45: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

メンバーのないJSObjectをPOJOにマッピングするいい方法はないか

Page 46: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

メソッドと戻り値の型情報がわかれば大丈夫だ、問題ない

Page 47: Unit testing JavaScript with JUnit/JavaFX

テストしたい関数

JS→Javaマッピング

Page 48: Unit testing JavaScript with JUnit/JavaFX

関数を実行する関数を作成

JS→Javaマッピング

Page 49: Unit testing JavaScript with JUnit/JavaFX

関数を実行する関数を実行

JS→Javaマッピング

Page 50: Unit testing JavaScript with JUnit/JavaFX

関数を実行する関数を実行する関数を作る

JS→Javaマッピング

Page 51: Unit testing JavaScript with JUnit/JavaFX

{…}を無名関数化

JS→Javaマッピング

Page 52: Unit testing JavaScript with JUnit/JavaFX

戻り値を既知のメソッドでPOJSO化

JS→Javaマッピング

Page 53: Unit testing JavaScript with JUnit/JavaFX

テスト実行

JS→Javaマッピング

Page 54: Unit testing JavaScript with JUnit/JavaFX

既知の型、メンバーを持つPOJSOを取得

JS→Javaマッピング

(int) jsObject.getMember("addAndGet");

Page 55: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

DateはPOJSOにマッピング

Page 56: Unit testing JavaScript with JUnit/JavaFX

既知の型とメソッドはアノテーションに記述

JS→Javaマッピング

Page 57: Unit testing JavaScript with JUnit/JavaFX

型安全に実行してassertionできる!

JS→Javaマッピング

Page 58: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

equals(java.lang.Object)とhashCode()メソッドの実装は自己責任でね★

Page 59: Unit testing JavaScript with JUnit/JavaFX

JS→Javaマッピング

● プリミティブ型は直接取得してassert● POJSOはgetMemberメソッド経由で

POJOにマッピングしてassert● 特殊なオブジェクトはアノテーションのメ

タ情報からPOJSOを経由してマッピングしてassert

Page 60: Unit testing JavaScript with JUnit/JavaFX

Fx-Js-JUnitJavaScriptのテストが

Page 61: Unit testing JavaScript with JUnit/JavaFX

カターンゼン

型安全

Page 62: Unit testing JavaScript with JUnit/JavaFX

Enjoy JavaScript!

Page 63: Unit testing JavaScript with JUnit/JavaFX

ご静聴ありがとぉ…

Page 64: Unit testing JavaScript with JUnit/JavaFX

…ぉ?

Page 65: Unit testing JavaScript with JUnit/JavaFX

テストは複数同時に実行

したいですよねぇ

Page 66: Unit testing JavaScript with JUnit/JavaFX

お望みであれば

やってみせますが…

Page 67: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

SAN値が下がりますよdef service = Executors.newThreadPool(2)service.execute {

Application.launch(App) }service.execute {

Application.launch(App) }

Page 68: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

Page 69: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

Page 70: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

複数 + JavaFX で検索

Page 71: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

Page 72: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

JavaFXは二度起動させることはできぬ!

Page 73: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

● 複数のテストへの対応○ WebEngineを複数立ち上げる○ 定期的にポーリングを行なって、

WebEngineが利用されなくなったら終了する

Page 74: Unit testing JavaScript with JUnit/JavaFX

名状しがたい…

● TODOs○ 複数のテストへの対応○ ServletコンテナまたはJavaEEコン

テナの搭載○ GitHubへの公開

○ Maven/Ivyレポジトリーへの登録○ 他ご要望がありましたら

@mike_neckまで

Page 75: Unit testing JavaScript with JUnit/JavaFX

Thank youfor your attention


Recommended