情シスは何度でも甦るさ。

OracleDB/Ruby好きの情シス部員がお送りします

Oracle Functional Testing OpenScriptで定常作業を自動化する

何気に4回目。
第一回OpenScriptとは
第二回OpenScriptでスクリプト作成
第三回OpenScriptをJenkinsから呼ぶ


皆さん仕事でシステムAの画面上のデータをシステムBに転記して入力するなんてことはありますか。
月次や年次のたまにしかやらない運用作業とか、はたまたグループウェアのスケジュールを別のプロジェクト管理のシステムに転記するとか。


うちの場合は、案件の工数を管理するシステムと、給与のための日毎の就業時間を管理するシステムがあり、その二つが見事に何の連携もされていない状況でした。一方がパッケージなのでDBのデータ連携なども難しい。
就業管理システムは、入退時にカードをかざすだけなのですが、案件管理システムは、手入力が必要。
でもって、基本的に二つの時間は、ニアイコールである必要があるため、毎日朝くると、就業管理システムで昨日の就業時間をチェックし、案件管理システムにどの案件で時間を使ったか割り振りをして、手入力する必要がありました。
で、毎日就業時間をチェックするのが地味に面倒臭い。
トータルの時間だけでもいいから、連携してくれないかしら。


そんなあなたの悩みも解決。そう、Oracle Functional Testing OpenScriptならね(長い)



本来は、回帰テストのためのツールですが、登録した操作を定常的に繰り返すという意味では合ってる。

というわけで、今回は、この就業管理システムの一日の就業時間を案件管理システムに自動で登録(連携)するスクリプトを作ります。
今回の要件は、以下の三点

  1. 毎日夜中の1:00に実行
  2. 前日分の就業システムの時間を案件管理システムに登録
  3. 就業システム上の、時間はHH:MI 形式。案件管理システム上は、時間は小数点で入力する


スクリプトの作成手順は、以下の通り。
1.新規スクリプトを作成する
2.転記する変数を初期化部で定義しておく
3.転記元のシステムの画面上のデータを変数化する
4.初期化部にJavaで関数を書く(version12から)
5.4で書いた関数を呼ぶ
6.5で変換した変数を使用して、違うシステムの画面に入力する
7.必要な場合はデータバンクの設定をする
8.JenkinsからコマンドラインでそのJobを呼ぶようにする


では、詳細。


1.新規スクリプトを作成する
普通にスクリプトを作成して下さい。


2.転記する変数を初期化部で定義しておく
最初に書いておきますが、値の加工自体は関数を作成し、そこにJavaで処理を書くのですが、なんとこの関数は引数は渡せるけど返り値を書けません。
なので、予めグローバルで変数を定義しておき、関数の中からグローバル変数に値をセットするというアプローチを取ります。
まじかよと思いましたが、それ以外の方法が見つかりませんでした。
なので、値は空でいいので、変数を作成します。
初期化部で右クリックメニューで[追加]-[変数の設定]で値は空でいいので作成します。


3.転記元のシステムの画面上のデータを変数化する
記録した際に、HTMLソースも一緒に記録されますが、そのHTMLから正規表現で該当の値を引っ掛けて変数化するということができます。

まず、該当の画面のWaitForPageというツリーをクリックすると、右側の詳細windowにその時のスクリーンショットが表示されます。
その下のタブをHTMLをクリックするとその時のHTMLが表示されるので、そこから変数化したい部分を範囲選択して右クリックして、[変数の作成]メニューを選択。


すると、選択した文字を検索するための正規表現を自動で記述してくれます。が、大概それでは足りません。
なので、選択範囲を複数行にして、かつ、タグのID属性とかを絡めて毎回必ずその値だけ抽出できる正規表現にします。

なお、正規表現上で (.+?) の部分が変数化される部分です。
最終的には、正規表現を手で修正して、画面項目を変数化しましょう。


4.初期化部にJavaで関数を書く
Javaで処理を書きます。引数は、3でセットした変数を引数として渡します。ただし、さっきも書いたとおり加工後の値はグローバル変数に関数内からセットします。

初期化部で右クリックメニューから、[追加]-[その他]-[スクリプト関数]-[ローカル・スクリプト]-[新規関数] を選択して、引数と名前を設定しましょう。





設定すると初期化部に関数が表示されます。

ここで、Javaコードタブに画面をスイッチすると、メソッドと、引数のみが定義されているので、ここにコードを書きます。

	/**
	 * mi:hh を 0.5単位の数に変換する
	 * @param time hh:mi の時間
	 */
public void convert(@Arg("time") String time) throws Exception {
    Integer h,m;
    Double convTime;

    //時と分に分ける
    String splitTime[] = time.split(":");
    h = Integer.parseInt(splitTime[0]);
    m = Integer.parseInt(splitTime[1]);

    //0.5単位にする
    if (m < 15){
      m = 0;
    }else if(m >= 15 && m < 45){
      m = 5;
    }else{
      m = 0;
      h += 1;
    }
    convTime = (m/10.0) + h;
    //グローバル変数にセット
    getVariables().set("time", convTime.toString());  
}

最後の部分で変数に値をセットしています。
よく見たら、グローバル変数と、引数の変数名一緒ですね。ミスってるだけなので、気にしないで下さい。


5.4で書いた関数を呼ぶ
忘れがちですが、実行部で関数を呼ぶという処理を追加する必要があります。
実行部の下のレベルのツリーで右クリックから、[追加]-[その他]-[スクリプト関数]-[ローカル・スクリプト]-作った関数 を選択しましょう。引数には、画面からキャプチャした変数をセット
注意は、この場合だと、実行部の2段階下のレベルに関数が作られますが、ドラッグ&ドロップで、実行部の1段階下のレベルのツリーにしましょう。
ここらへん、よくわからんけど、そうしたらちゃんと動きました。


6.5で変換した変数を使用して、別システムの画面に入力する
ここまでくれば無事入力した値は取得できているので、その変数を別システムの入力したい画面のテキストボックスとかに設定するようにしましょう。


7.必要な場合はデータバンクの設定をする
複数人のユーザー分転記するとかなら、データバンクが必要ですね。やっときましょう。


8.JenkinsからコマンドラインでそのJobを呼ぶようにする
やっぱりJenkinsから定期実行させて結果レポートも閲覧できるようにしましょう。詳細は、前回のブログを参考に。

なお、ここではまったのが、DataBankのスクリプトコマンドラインから呼び出すオプションの付け方。

マニュアルを見ると、以下で全件のデータバンクを実行できるとおもいきや、

runScript "C:/OracleATS/OFT/script1/script1.jwg"  -dbopts alias=DataBankName:whenOut=STOP_USER

これだとデータバンクの一件目しか実行されず。試行錯誤して、-iterations 件数 でデータバンクの件数を設定したら動きました。ここらへんもようわからん。

runScript "C:/OracleATS/OFT/script1/script1.jwg"  -dbopts alias=DataBankName:whenOut=STOP_USER -iterations 50

なお、-iterations オプションの数がデータバンクの件数より多くても、一周すると自動で止まりました。



他にも、はまった部分は
・データバンクの次のデータを取得する処理を初期化部に置いてしまい、処理がループしても、Databankの次のレコードが取れずにはまった
スクリプトの実行が二回に一回はポートが使われてるってエラーで動かなくなった⇒再起動したらなおった
・別システムでの入力のリンクの位置が変わるため、うまく動かなかったのでURLを直接指定して遷移した。なお、その際にURL内のパラメータも動的に変更する必要があったので、URLに変数を入れ込んだ。


ということもありましたが、なんとか動くところまでもっていけました。


なお、これによる効果は、
一日26秒(計測した)の削減で、対象メンバー約50人なので、全体で年間93時間ほどの削減になりましたとさ。チリと積もればヤマ!


ここらへんは英語のマニュアルにもほとんど記述がないので、触り触りやりましたので、本当はもっとイケてる使い方があるかもしれません。
製品としてはスゲーと思うけど、ほんとマニュアルが揃ってないよね・・・。


というわけで、レッツ自動化ライフ