あ〜、暇だから、Swing フォームを JavaScript で動かすやり方でも考えてみっかな。
====
例えば、打鍵+目視に基づいた手動画面テストが既に実施されていたり、チェックリストとかテスト仕様書が出来ている場合に、作業負荷を減らすために、後から部分的に自動化を導入して、半自動テストにしたい場合がある。
ところでfest という、Swing アプリを Javaコードから機能テストするための API セットがあり、Javaコード からUIイベントを発生させて画面上のコンポーネントを操作するAPIが一揃い入っている(AWT の Robot をベースにしたものらしい)。
また、JavaScript コードを Javaプログラムから動かす仕組みは、Java 1.6 から備わっていて、特に何か特別なライブラリを必要とせずに、簡単に使えるようになっている。
これらを利用すれば、テスト対象フォームの外で JavaScript を実行して、フォーム上の要素を制御することができるはず。
■ 実験台
実験台として、以下のフォームを考えてみる。
こんな仕様- テキストボックスの名前は "field1"
- チェックボックスの名前は "check1"
- ボタンの名前は "button1" で、押下すると "check1"がチェックされている場合は field1 を大文字化した文字列、チェックされていない場合は field1 そのままの文字列を、標準出力に書き出す。
実験台だから単純なフォームにしたけど、実際の現場での開発対象フォームは入力項目が何十個もあって、実行ボタンを押すまでに必要な打鍵動作が多く、1回なら問題ないけど、同じようなテストケースや回帰テストをしたりすると心身ともに疲れたりする。やはり、そういうのは、何とかして省力化したい。
■ 方針
まず、テスト対象フォームを開くと同時に、以下のような別ウィンドウを開く。で、ここで JavaScript を入力して Excecute ボタンを押下すると、手動の打鍵と同等の JavaScript が実行されるようにしたい。
■ 実装
JavaScript 入力用のウィンドウ ScriptInputWindow は、最初にテスト対象ウィンドウの FrameFixture を受け取る。
public static void main(String[] args) {
JFrame frame = showWindow(new TestTargetWindow("Test Target"), 0);
FrameFixture window = new FrameFixture(frame);
showWindow(new ScriptInputWindow(window), 3000);
}
public static JFrame showWindow(JFrame frame, int xpos) {
frame.setSize(250, 150);
frame.setLocation(xpos, 0);
frame.setVisible(true);
return frame;
}
ScriptInputWindow はまず最初に、テスト対象フォーム上のコントロールを、JavaScript 用の ScriptEngine に登録する。ScriptEngine も ScriptInputWindow が保持しておく。
public ScriptInputWindow(FrameFixture window) {
super("JavaScript input window");
initializeControlls();
this.jsEngine = new ScriptEngineManager().getEngineByName("JavaScript");
registerComponents(window, window.component(), 0);
}
@SuppressWarnings("restriction")
private void registerComponents(
FrameFixture window, Container container, int indent) {
for (Component component: container.getComponents()) {
String name = component.getName();
if (null != name) {
ComponentFixture comp = selectComponent(window, name);
if (null != comp) this.jsEngine.put(name, comp);
}
if (component instanceof JComponent)
listComponents(window, (Container)component, indent + 1);
}
}
ボタンを押すと書き込んだJavaScriptコードを実行する部分は以下のようなもの。
executeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ExecutorService e = Executors.newSingleThreadExecutor();
e.execute(new Runnable() {
public void run() {
try {
String text = ScriptInputWindow.this.textArea.getText();
ScriptInputWindow.this.jsEngine.eval(text);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
■ 試行
以下のコードを書き込んで実行すると、テキストボックスの内容が "123abcABC" に変わり、チェックボックスがチェックされ、ボタンが押され、標準出力に”123ABCABC”が出力される。field1.setText("123abcABC");
check1.check();
button1.click();
■ 応用
- フォーム上のコントロールの操作以前に、まずコントロールの名前を知ってなきゃならないんだけど、必要な時に階層状に表示してテスターに見せる機能もあった方が良いかもしれない。これは registerComponents でやってる事をそのままどっかに書き出すだけだから簡単。
- 自動打鍵の結果として得られた画面上の更新項目を、比較しやすい形式でどこか(TextArea とかクリップボードでもファイルでも)に書き出す仕組みもあると便利かもしれない。グリッドとかツリーとかあると、ちょっと手間がかかるかも。
- 自動打鍵後に、用意しておいた期待値と自動的に比較する仕組みがあると、かなり全自動に近づいてくる。
- 手動打鍵の記録なんかまでやるとなると、それは難しい。商用製品でも買った方がマシかもしれない(下記の参考記事をみるとFESTでも対応作業中みたいな書きっぷりだけど、どうなったのか不明)。
■ 参考サイト


0 件のコメント:
コメントを投稿