あ〜、暇だから、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 件のコメント:
コメントを投稿