Quantcast
Channel: hifive開発者ブログ
Viewing all 274 articles
Browse latest View live

業務システムで使えるグリッドライブラリ×8選

$
0
0

Webベースの業務システムを作っている際に必要になるのがデータの一覧画面です。多くのデータを一覧でき、かつスクロールした際にもデータの確認が容易であることなどが求められます。

今回はそんなデータを表示するのに最適なOSSのグリッドライブラリを紹介します。一部のライブラリは編集機能も備えており、さながら表計算ソフトウェアのようになっています。

Sensei Grid


シンプルかつ軽量なデータグリッドライブラリです。矢印キーやタブを使ったセルの移動、エンターキーで編集ができます。とてもシンプルなライブラリなので、マスタメンテナンスなどに向いています。(注:2015/06現在「Currently not intended for production use」とのことです。)

Sensei Grid

kawasima/jagrid


Excel方眼紙を再現できるライブラリです。こだわればかなり精密な帳票デザインも行えます。

kawasima/jagrid

mleibman/SlickGrid


表の中にグラフやチェックボックスを埋め込み表示することもできます。そのため、ガントチャート風の表示を行うこともできます。1万行以上のデータを表示しても軽快に動作します。

mleibman/SlickGrid

mmurph211/Grid


上下左右の行/カラムを固定表示したり、行を選択してハイライト表示できるライブラリです。データのソートもサポートしています。シンプルですが多くの業務要件をカバーしているでしょう。

mmurph211/Grid

SitePen/dgrid


カラムの動的な追加、ソート、並び替え、セル単位の選択、ページネーション、グルーピングなどの機能があります。ページネーション処理なども動的に変更できるので、利用者によってカスタマイズするといったこともできそうです。

SitePen/dgrid

Knockout-Contrib/KoGrid


ソート、グルーピングなどの機能に加えてサーバサイドと連携したページネーションもサポートしています。

Knockout-Contrib/KoGrid

jqGrid


jQueryプラグインとして開発されているグリッドライブラリです。ツリーグリッド、検索、サブグリッドなどの高度なグリッド表示もサポートしています。

jqGrid

Sigma Ajax Grid – Ajax editable data grid – DHTML grid control with flexibility and user API.


二つのグリッドを連携させるマスター/詳細グリッドがあります。さらにや矢印キーでの移動、PDFやExcelでのエクスポート、印刷など多彩な機能が揃っています。このライブラリはライセンスがLGPLですが、別途商用ライセンスも設定されているようです(テクニカルサポートなども受けられるようです)。

Sigma Ajax Grid – Ajax editable data grid – DHTML grid control with flexibility and user API.


これらのグリッドライブラリを使えば自社システムはもちろん、クライアント向けWebアプリケーションにおいてもユーザビリティの高い高度な機能が提供できることでしょう。グリッド表示におけるユーザの不満もその殆どが解消するのではないでしょうか。

hifiveでもヘッダーが複雑なグリッドページンググリッドスクロールグリッドといったグリッドをデモしています。ぜひご覧ください。

皆さんのWebシステム開発に活かしてください!

hifive – HTML5企業Webシステムのための開発プラットフォーム – hifive



UIを気にしないで済むデータバインドの使い方

$
0
0

最近Reactが盛り上がっています。特に大きな要因として、UIの描画を気にせず、Virtual DOM側に実際の描画は任せられるというのが挙げられます。

Virtual DOMの方式ではありませんが、hifiveでもデータを変更すると描画が変わる、データバインドという機能が提供されています。今回はそんなデータバインドの使い方をステップを踏みつつ紹介します。

基本のHTML

今回はJavaScript/スタイルシートともにダウンロードせず、CDN版を使います。一緒に使うjQueryもGoogleのCDN版を使います。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1">
    <link href="//code.htmlhifive.com/h5.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//code.htmlhifive.com/ejs-h5mod.js"></script>
    <script src="//code.htmlhifive.com/h5.js"></script>
    <title>TODO管理</title>
</head>
<body>
  <div id="container">
  </div>
</body>
</html>

モデルを作る

データバインドを行う際にはまず、モデルを定義する必要があります。最も簡単な例としては次のようになります。

var manager = h5.core.data.createManager('TodoManager');
var model = manager.createModel({
  name: 'TodoModel',
  schema: {
    id: {id: true},
    text: {
      type: 'string'
    }
  }
});

モデル名とスキーマは必須です。また、ユニークなキーを設定する必要があります(今回はidです)。そして他のフィールドについても型を指定します。

オブジェクトを作る

定義したモデルに従ってオブジェクトを作ります。

var item = model.create({
  id: '1',
  text: 'Hello World'
});

そしてこれをビューにバインドします。

h5.core.view.bind($('#container'), item);

このようにバインドすると、

<div id="container">
  <span data-h5-bind="text"></span>
</div>

といった形で Hello World が表示されます。


データを変更してみる

では次にデータを変更してみます。例えばボタンを設置して、その押した時のアクションでラベルを変更します。

<div id="container">
  <input type="button" name="add" id="add" value="追加" />
  <span data-h5-bind="text"></span>
</div>

そしてJavaScriptは次のように書きます。

$("#add").on("click", function(e) {
  item.set('text', 'changed');
});

こうするとボタンを押した時にラベルが変わります。


全体のソースコードは以下になります。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1">
    <link href="//code.htmlhifive.com/h5.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//code.htmlhifive.com/ejs-h5mod.js"></script>
    <script src="//code.htmlhifive.com/h5.js"></script>
    <title>TODO管理</title>
</head>
<body>
  <div id="container">
    <input type="button" name="add" id="add" value="追加" />
    <span data-h5-bind="text"></span>
  </div>
  <script>
    $(function() {
      var manager = h5.core.data.createManager('TodoManager');
      var model = manager.createModel({
        name: 'TodoModel',
        schema: {
          id: {id: true},
          text: {
            type: 'string'
          }
        }
      });
      var item = model.create({
        id: '1',
        text: 'Hello World'
      });
      h5.core.view.bind($('#container'), item);
      $("#add").on("click", function(e) {
        item.set('text', 'changed');
      });
    });
  </script>
</body>
</html>


データさえ変更すれば、UI側は自動で変更してくれるのはとても便利です。DOMを変更する場合、変更し忘れであったり、別な場所からもデータを変更してしまう(それを補足できない)といった問題があります。hifiveのデータバインドを使えば、UIとデータの一貫性は保たれますのでコードの品質が保たれるはずです。

データバインドについての詳細はチュートリアル(データバインド編) – hifiveでご覧いただけます。

hifive – HTML5企業Webシステムのための開発プラットフォーム – hifive


UIを気にしないで済むデータバインドの使い方(リアルタイム反映編)

$
0
0

前回のデータバインドを使ったHello World表示に続いて、今回はさらにデータの入力との連携も行ってみたいと思います。なお前回終了時のコードは以下になります。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1">
    <link href="//code.htmlhifive.com/h5.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//code.htmlhifive.com/ejs-h5mod.js"></script>
    <script src="//code.htmlhifive.com/h5.js"></script>
    <title>TODO管理</title>
</head>
<body>
  <div id="container">
    <input type="button" name="add" id="add" value="追加" />
    <span data-h5-bind="text"></span>
  </div>
  <script>
    $(function() {
      var manager = h5.core.data.createManager('TodoManager');
      var model = manager.createModel({
        name: 'TodoModel',
        schema: {
          id: {id: true},
          text: {
            type: 'string'
          }
        }
      });
      var item = model.create({
        id: '1',
        text: 'Hello World'
      });
      h5.core.view.bind($('#container'), item);
      $("#add").on("click", function(e) {
        item.set('text', 'changed');
      });
    });
  </script>
</body>
</html>

ここで、入力欄を追加します。

<div id="container">
  <input type="button" name="add" id="add" value="追加" />
  <span data-h5-bind="text"></span><br />
  <!-- 以下を追加 -->
  <input type="text" name="edit" id="edit" data-h5-bind="attr(value):text" />
</div>

data-h5-bindを使ってvalueに値を表示する場合は、 data-h5-bind="attr(value):text" といった方法を使います。attr(value)で入力欄のvalue要素を指定します。そしてその時に表示する値を :text という指定で表示します。

次に入力欄を編集した時のイベントをkeyupで受け取ります。そしてその値をitemにセットします。

$("#edit").on("keyup", function(e) {
  item.set('text', e.currentTarget.value);
});

これで完了です。HTML全体は次のようになります。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1">
    <link href="//code.htmlhifive.com/h5.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//code.htmlhifive.com/ejs-h5mod.js"></script>
    <script src="//code.htmlhifive.com/h5.js"></script>
    <title>TODO管理</title>
</head>
<body>
  <div id="container">
    <input type="button" name="add" id="add" value="追加" />
    <span data-h5-bind="text"></span><br />
    <input type="text" name="edit" id="edit" data-h5-bind="attr(value):text" />
  </div>
  <script>
    $(function() {
      var manager = h5.core.data.createManager('TodoManager');
      var model = manager.createModel({
        name: 'TodoModel',
        schema: {
          id: {id: true},
          text: {
            type: 'string'
          }
        }
      });
      var item = model.create({
        id: '1',
        text: 'Hello World'
      });
      h5.core.view.bind($('#container'), item);

      // 値を変更
      $("#add").on("click", function(e) {
        item.set('text', 'changed');
      });
      
      // 値を変更した時の処理
      $("#edit").on("keyup", function(e) {
        item.set('text', e.currentTarget.value);
      });
    });
  </script>
</body>
</html>

実際に動かすと次のようになります。



このようにデータの修正と表示の反映がリアルタイム化できると、データ編集後のAjaxを使ったサーバへの保存処理もそのまま使えるようになります。次回はもう少し複雑な表示を行ってみたいと思います。

データバインドについての詳細はチュートリアル(データバインド編) – hifiveでご覧いただけます。

hifive – HTML5企業Webシステムのための開発プラットフォーム – hifive


UIを気にしないで済むデータバインドの使い方(独自メソッド編)

$
0
0

全体のデータ修正とそのリアルタイム反映に加えて、今回はモデルのメソッドを使ってみたいと思います。

例えばTwitterなどでは入力している文字数が分かるようになっています。同じように文字数を出してみましょう。

前回までのHTMLは次のようになっています。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1">
    <link href="//code.htmlhifive.com/h5.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//code.htmlhifive.com/ejs-h5mod.js"></script>
    <script src="//code.htmlhifive.com/h5.js"></script>
    <title>TODO管理</title>
</head>
<body>
  <div id="container">
    <input type="button" name="add" id="add" value="追加" />
    <span data-h5-bind="text"></span><br />
    <input type="text" name="edit" id="edit" data-h5-bind="attr(value):text" />
  </div>
  <script>
    $(function() {
      var manager = h5.core.data.createManager('TodoManager');
      var model = manager.createModel({
        name: 'TodoModel',
        schema: {
          id: {id: true},
          text: {
            type: 'string'
          }
        }
      });
      var item = model.create({
        id: '1',
        text: 'Hello World'
      });
      h5.core.view.bind($('#container'), item);

      // 値を変更
      $("#add").on("click", function(e) {
        item.set('text', 'changed');
      });
      
      // 値を変更した時の処理
      $("#edit").on("keyup", function(e) {
        item.set('text', e.currentTarget.value);
      });
    });
  </script>
</body>
</html>

入力文字数を出す部分を作る

HTML上で現在の入力文字数を出すようにします。

<input type="text" name="edit" id="edit" data-h5-bind="attr(value):text" />
<!-- 追加 -->
(<span data-h5-bind="text_length"></span>)

モデルにメソッドを追加

次にモデルに text_length メソッドを追加します。

var model = manager.createModel({
  name: 'TodoModel',
  schema: {
    id: {id: true},
    text: {
      type: 'string'
    },
    //
    // text_lengthの追加(ここから)
    //
    text_length: {
      type: 'integer',
      depend: {
        on: 'text',
        calc: function () {
          return this.get("text").length
        }
      }
    }
    //
    // text_lengthの追加(ここまで)
    //
  }
});

text_lengthは元々のデータフォーマットには存在しない項目ですが、schemaの中に定義します。型の種類と、関連するデータを指定します(今回はtextです)。そしてcalcオプションで実際の処理内容を指定します。textデータはgetメソッドを使ってデータを取り出します。そしてその文字数をlengthで取得、返却しています。


ここまでできあがると、次のように文字を入力する度に文字数が変わるようにします。



新しいメソッドを自分で追加できるのでリアルタイムバリデーションなどで利用が可能です。次回は項目を増やして配列を管理してみましょう。


Pitaliumを使ってスクリーンショットベースのユニットテストを書こう(準備編)

$
0
0

Webブラウザを操作する系統のユニットテストは作るのがとても大変で、その後のメンテナンスコストも大きいのが問題です。SeleniumIDEを使ってブラウザの操作をスクリプト化し、テストに組み込むのが一般的に行われていますが、画面やシステムの変更が発生するとテストはすべて破棄しなければならないくらい再利用性が低いです。

そこでhifive開発チームがリリースしたのがPitalium(ピタリウム)になります。Pitaliumは、マルチデバイスを対象としたWebアプリ開発におけるリグレッションテストを自動化・省力化するためのライブラリです。hifiveのテスト支援ツールの一つとして、Apache2.0ライセンスにて無償で利用できます。

PitaliumはSeleniumの中で使うことが出来ます。DOMや画面上の文字を比較するのではなく、スクリーンショットを使って見た目上の比較を行うのがポイントになっています。

今回はまずPitaliumを使うための環境作りについて紹介します。

必要なソフトウェアのダウンロード

PitaliumはSeleniumと組み合わせて使います。そのため、以下のソフトウェアが必須になります。

  • Java
    Javaソフトウェアをダウンロードよりダウンロードしてください。
  • Selenium Server
    Selenium Downloads より selenium-server-standalone–2.xx.x.jar をダウンロードしてください。
  • InternetExplorerDriver(IE Driver)
    スクリーンショット時に幅と高さが変わる問題を修正したバージョンを用意しています。これらはPitaliumに同梱されていますので、Pitaliumダウンロードページからpitalium-x.x.x.zipをダウンロードし、zipを展開したフォルダの下記の場所から取得して下さい。
    32bit版:pitalium_x.x.x/IE/x86/IEDriverServer_h5mod_2.xx.x.exe
    64bit版:pitalium_x.x.x/IE/x64/IEDriverServer_h5mod_2.xx.x.exe
  • Chrome driver
    Downloads – ChromeDriver – WebDriver for Chromeより ChromeDriver をダウンロードしてください。

その他、今回は下記ソフトウェアも利用します。

  • Eclipse
    テストを実行する際に使っています。Eclipse DownloadsよりEclipse IDE for Java Developersをダウンロードしてください。

ファイルの配置について

今回は、

  • Selenium Server
  • InternetExplorerDriver(IE Driver)
  • Chrome driver

が Cドライブ直下のtestlibディレクトリの中に配置されていることとします。下の画像のようになります。

(ただし、修正版IE Driverのファイル名はIEDriverServer_h5mod_x.xx.x.exeのようになります。)

Selenium Gridの起動

PitaliumはSeleniumの平行実行版であるSelenium Grid上で実行するようになっています。そこでまずはSelenium Serverを起動します。

java -jar C:/testlib/selenium-server-standalone-2.46.0.jar -role hub

設定ファイルの記述

次にSelenium Serverに接続するノードに関する設定ファイルを記述します。ファイルは C:\testlib\NodeConfigBrowser.json にあるものとし、内容は以下のように記述します。

{
  "capabilities": [
    {
      "browserName": "firefox",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "chrome",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "configuration": {
    "hub": "http://localhost:4444/grid/register"
  }
}

ローカルのSelenium Serverに接続するノードおよびそのブラウザについて記述します。そしてファイルを記述したらノードを起動します。

java -jar C:/testlib/selenium-server-standalone-2.46.0.jar ^
    -role node ^
    -nodeConfig C:/testlib/NodeConfigBrowser.json ^
    -Dwebdriver.ie.driver=C:/testlib/IEDriverServer_h5mod_2.46.0.exe ^
    -Dwebdriver.chrome.driver=C:/testlib/chromedriver.exe

IEに対応するドライバ、Chromeに対するドライバをそれぞれ指定しているのが分かるかと思います。IEを使う場合は初期設定として、IE上の設定変更が必要になります。こちらの内容を参考して、設定を変更してください。

Eclipseでの作業

続いてEcpliseでテストを実行してみます。まず新規でJavaプロジェクトを作成します。今回はWebDriverTestとしています。作成したらsrc/testというパッケージフォルダを作成します。そしてさらにその中に com.htmlhifive.sample という名前のパッケージを作成します。

さらにlibsディレクトリを作成し、その中にSeleniumのjarファイルおよびlibsフォルダの内容をコピーします。

次にプロジェクトのプロパティを開いて、Javaのビルドパス > ライブラリと開きます。そして jar追加ボタンを押し、先ほどコピーしたlibsフォルダ以下のjarファイルをすべて選択し、OKボタンを押します。

テストの記述

では com.htmlhifive.sample パッケージの中に SeleniumGridTestSample.java というファイルを作成し、以下のように記述してみましょう。

package com.htmlhifive.sample;
 
import org.junit.Test;
import org.openqa.selenium.remote.*;
import org.openqa.selenium.Platform;
import java.net.*;

public class SeleniumGridTestSample {
    @Test
    public void test() throws Exception {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setPlatform(Platform.WINDOWS);
        capabilities.setBrowserName("internet explorer");

        RemoteWebDriver driver =
                new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilities);
        driver.get("https://www.htmlhifive.com/");
    }
}

このファイルを実行すると、 IEが立ち上がってhifiveのWebサイトが表示されるはずです。これはSeleniumのノードからGridを経由してIEが立ち上がっている状態ということです。


今回は以上になります。これでSelenium Gridが使えるようになりましたので、次回から実際にPitaliumを使ってみましょう。

Pitalium(hifiveリグレッションテストライブラリ) – hifive


Pitaliumを使ってスクリーンショットベースのユニットテストを書こう(デモ編)

$
0
0

Seleniumを使ったWebブラウザを自動操作するタイプのテストでは、画面遷移が正しく行われた結果、必要なテキストやDOMが存在することは確認できます。しかしデザインを変更した結果、DOM構造が崩れてしまっているかどうかについては分かりません。

プロジェクトの最初ではちゃんと多数のブラウザでテストを行うと思いますが、更新の度に確認するのは大きなコストです。そうしたデザインの状態においても確認できるのがPitaliumになります。前回の準備編に引き続き、今回は実際にPitaliumを動かすところを紹介したいと思います。

サンプルプロジェクトをダウンロード

まずGitHubにあるサンプルプロジェクトをチェックアウト、またはZipファイルをダウンロードします。

$ git clone git@github.com:hifive/hifive-pitalium.git
$ cd hifive-pitalium

そしてさらに pitalium-sample フォルダに入り、antを実行します。Eclipseからも実行できますが、今回はコマンドプロンプトで実行しています。

$ cd pitalium-sample
$ ant -buildfile ivy_build.xml

しばらく待つと必要なファイルのダウンロード、ビルドが完了します。

Selenium Hubサーバの起動

前回の記事にあった手順でSelelnium Hubサーバを起動しておきます。

$ java -jar selenium-server-standalone-2.46.0.jar -role hub

Eclipseを起動

Eclipseを起動して pitalium-sample プロジェクトを開きます。そして pitalium-sample/src/main/resources/capabilities.json を編集します。デフォルトは次のようになっていますので、必要なものだけを残して後は削除します。WindowsのFirefox/Google Chrome/IE11/IE10/IE9/IE8/IE7に加えてMac OSXのSafari、Android 4.4/5.1/2.3.6/4.0.4、iOS 8.1/8.3などが定義されています。

[
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "firefox"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "chrome"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "internet explorer",
        "version": "11"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "internet explorer",
        "version": "10"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "internet explorer",
        "version": "9"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "internet explorer",
        "version": "8"
    },
    {
        "platform": "WINDOWS",
        "os": "WINDOWS",
        "browserName": "internet explorer",
        "version": "7"
    },
    {
        "platform": "MAC",
        "os": "OS X",
        "browserName": "safari"
    },
    {
        "platform": "ANDROID",
        "platformName": "Android",
        "platformVersion": "4.4.4",
        "version": "4.4.4 Xperia Z3",
        "deviceName": "Xperia Z3",
        "os": "Android",
        "browserName": "chrome"
    },
    {
        "platform": "ANDROID",
        "platformName": "Android",
        "platformVersion": "5.1",
        "version": "5.1 Nexus5",
        "deviceName": "Nexus 5",
        "os": "Android",
        "browserName": "chrome"
    },
    {
        "platform": "ANDROID",
        "platformName": "Android",
        "platformVersion": "4.4.4",
        "version": "4.4 Nexus7",
        "deviceName": "Nexus 7",
        "os": "Android",
        "browserName": "chrome"
    },
    {
        "platform": "ANDROID",
        "browserName": "android",
        "version": "2.3.6 Galaxy S2",
        "platformName": "Android",
        "platformVersion": "2.3.6",
        "deviceName": "Galaxy S2",
        "automationName": "selendroid",
        "autoWebview": true
    },
    {
        "platform": "ANDROID",
        "browserName": "android",
        "version": "4.0.4 ASUS Pad",
        "platformName": "Android",
        "platformVersion": "4.0.4",
        "deviceName": "ASUS Pad",
        "automationName": "selendroid",
        "autoWebview": true
    },
    {
        "platformName": "iOS",
        "os": "iOS",
        "platformVersion": "8.1",
        "deviceName": "iPad Air",
        "browserName": "safari"
    },
    {
        "browserName": "safari",
        "deviceName": "iPhone6",
        "os": "iOS",
        "platformName": "iOS",
        "platformVersion": "8.3",
        "version": "8.3"
    }
]

テストの実行

テストファイルは pitalium-sample/src/main/java/com/htmlhifive/pitalium/sample/PtlSampleTest.java  になります。実際に画面キャプチャを行うのは次の処理になります。

assertionView.assertView("sampleCapture", targets, HIDE_ELEMENTS);

UnitTestとして実行すれば、しばらく待つとブラウザが立ち上がり、テストが実行されます。

テストが終わるとresultsフォルダ内にテスト実行日時とその時に撮影したスクリーンショットが保存されます。これで画面が変わっている場合は差分画像も保存されます。


Pitaliumを使えばテストの実行と同時にそのスクリーンショットを残してくれるようになります。デザインの崩れをすべてのブラウザに対して常に確認するというのはとても大変です。Pitaliumを使えば大幅に工数が減るはずです。

次回はさらに踏み込んだ使い方を紹介します。

Pitalium(hifiveリグレッションテストライブラリ) – hifive


Pitaliumを使ってスクリーンショットベースのユニットテストを書こう(実用編)

$
0
0

Pitaliumを使うとSeleniumのテストが画面の表示結果ベースでの確認になるので、DOMやテキストのように一つ一つ指定して確認する必要がありません。さらにスクリーンショットを保存しますので、画面のデザイン崩れについても確認ができます。

今回はそんなPitaliumをさらに活用できるテクニックについて紹介します。

IDを指定してDOM比較

これは画面の一部について確認を行いたい時に使えるコードになります。ヘッダー、フッターは変化せず、メインコンテンツだけを比較したいといった使い方が考えられます。

コードは例えば以下のようになります。

import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.htmlhifive.pitalium.core.PtlTestBase;
import com.htmlhifive.pitalium.core.model.CompareTarget;
import com.htmlhifive.pitalium.core.model.ScreenArea;
import com.htmlhifive.pitalium.core.model.SelectorType;

public class SampleTest extends PtlTestBase {
    @Test
    public void testCompareTarget_ID() throws Exception {
        // 1. hifiveサイトのトップページを開きます。
        driver.get("https://www.htmlhifive.com/");

        // 2. ID: about の比較対象を作成します。
        List<CompareTarget> targets = new ArrayList<CompareTarget>();
        targets.add(new CompareTarget(ScreenArea.of(SelectorType.ID, "about")));

        // 3. 比較対象を使用して検証を実行します。
        assertionView.assertView("TopPageAbout", targets);
    }
}

CSSセレクタを使ってDOMを指定

さらにCSSセレクタによるDOMの指定もできます。この場合、コンテンツが複数あるケースも考えられます。その時にはスクリーンショットも複数に分かれて比較されます。サンプルコードは次のようになります。

import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.htmlhifive.pitalium.core.PtlTestBase;
import com.htmlhifive.pitalium.core.model.CompareTarget;
import com.htmlhifive.pitalium.core.model.ScreenArea;
import com.htmlhifive.pitalium.core.model.SelectorType;

public class SampleTest extends PtlTestBase {
    @Test
    public void testCompareTarget_cssSelector() throws Exception {
        // 1. hifiveサイトのトップページを開きます。
        driver.get("https://www.htmlhifive.com/");

        // 2. "#about > div" 比較対象を作成します。
        List<CompareTarget> targets = new ArrayList<CompareTarget>();
        targets.add(new CompareTarget(ScreenArea.of(SelectorType.CSS_SELECTOR, "#about > div")));

        // 3. 比較対象使用して検証を実行します。
        assertionView.assertView("TopPageAboutContents", targets);
    }
}

比較から除外する

例えばバナーであったり、ログイン名、Facebookのいいねなど状態によって表示内容が変わってしまう場合があります。そうした時にPitaliumは二つの方法を用意しています。

要素を除外

指定したID、CSSセレクタを使って除外設定を行います。

import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import com.htmlhifive.pitalium.core.PtlTestBase;
import com.htmlhifive.pitalium.core.model.CompareTarget;
import com.htmlhifive.pitalium.core.model.ScreenArea;
import com.htmlhifive.pitalium.core.model.SelectorType;

public class SampleTest extends PtlTestBase {
    @Test
    public void testExclude() throws Exception {
        // 1. hifiveサイトのトップページを開きます。
        driver.get("https://www.htmlhifive.com/");

        // 2. 画面全体のスクリーンショットを撮影する設定を作成します。
        //    ただし、画面上部の「Facebook いいね」ウィジェットを除外します。
        ScreenArea[] excludes = {ScreenArea.of(SelectorType.ID, "fb_share")};
        CompareTarget target = new CompareTarget(ScreenArea.of(SelectorType.TAG_NAME, "body"), excludes, true);
        List<CompareTarget> targets = Arrays.asList(target);

        // 3. スクリーンショットを撮影します(比較を実行します)
        assertionView.assertView("TopPageExcludeFBLike", targets);
    }
}

このように除外設定を行うと、専用のJSONファイルが生成されます。

[
  {
    "target": {
      ...
    },
    "excludes": [
      {
        "selector": {
          "type": "ID",
          "value": "fb_share",
          "index": null
        },
        "rectangle": {
          "x": 985.0,
          "y": 10.0,
          "width": 90.0,
          "height": 29.0
        },
        "screenArea": {
          "selector": {
            "type": "ID",
            "value": "fb_share"
          }
        }
      }
    ],
    ...
  }
]

スクリーンショット自体は特に加工を行わず、このJSONファイルを使って指定部分を比較対象外にするという仕組みになっています。

要素を非表示にする

非表示にするのは例えばポップアップのフローティングであったり、チュートリアルのツアーなどスクリーンショットで比較する際に邪魔になってしまう要素を除外する指定になります。

この場合は上記の除外とは異なり、予め要素を非表示にした上でスクリーンショットを撮影します。

import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import com.htmlhifive.pitalium.core.PtlTestBase;
import com.htmlhifive.pitalium.core.model.DomSelector;
import com.htmlhifive.pitalium.core.model.SelectorType;

public class SampleTest extends PtlTestBase {

    @Test
    public void testHidden() throws Exception {
        // 1. hifiveサイトのトップページを開きます。
        driver.get("https://www.htmlhifive.com/");

        // 2. 画面全体のスクリーンショットを撮影します。
        //    ただし「トップへ戻る」を非表示とします。
        List<DomSelector> hiddenSelectors = Arrays.asList(new DomSelector(SelectorType.CLASS_NAME, "gototop"));

        // 3. スクリーンショットを撮影します(比較を実行します)
        assertionView.assertView("TopPageHidden", null, hiddenSelectors);
    }

}

テストの再定義

運用を重ねていく内に、テストが失敗する時がきます。この時に行うべき対応としては2種類あります。

  1. 見た目が変化しただけでテストケースに影響がない場合
  2. 表示ロジックが変わったなど、テストケースが影響を受ける場合

それぞれ対応が異なってきます。

テストケースに影響がない場合

一旦RUN_TESTモードで実行した後、差分結果が問題ないか確認します。そして SET_EXPECTED モードで実行すると期待値となるスクリーンショットを更新してくれます。

テストケースに影響がある場合

テストケースの修正後、TAKE_SCREENSHOTモードで修正したテストコードや取得されるスクリーンショットが正しいことを確認してください。その後、SET_EXPECTED モードで実行すると期待値となるスクリーンショットを更新してくれます。


Pitaliumを使うとWebアプリケーションのテスト時における検証の面倒さから解放され、スクリーンショット単位での確認になります。さらにIEやChromeなど多くのブラウザにおけるデザイン崩れの発生が素早く行えるようになります。ぜひPitaliumを使って快適なテスト環境を構築してください!

Pitalium(hifiveリグレッションテストライブラリ) – hifive


Webサーバの負荷・ロードテストツール(1)「 ab(Apache Bench)」

$
0
0

今回から何回かに分けて、Webサーバ用の負荷テストツールを紹介していきたいと思います。今回は有名どころのabです。

Apache標準搭載の ab(Apache Bench)とはapacheをインストールすると標準で利用できる性能測定ツールで、コマンドラインから利用します。

はじめに(ご注意ください!)

今回紹介するテストツールは、DOS攻撃にも利用出来てしまいます。テストを行う時は、サーバのURLが正しいか注意し、他人のサーバに間違ってもアクセスしないようにくれぐれもご注意願います。

実行方法

実行は大変簡単です。以下をコマンドラインで実行します。

$ ab -n 100 -c 10 http://localhost/

利用したオプションパラメータは以下の通りです。
-n: リクエスト回数
-c:同時に発行するリクエスト数

上記例の場合、合計で100リクエストを、同時発行数が10リクエストでアクセスを行います。 正確にはちょっと違いますが、上記は10クライアントが同時アクセスしてきた場合をイメージすると良いでしょう。

オプションパラメータについて

他にも、abにはオプションパラメータが存在します。結果をHTMLで表示することも可能です。 代表的なオプションを以下にリストします。

オプション 説明
-n リクエスト回数 総リクエスト数
-c リクエスト数 同時発行のリクエスト数
-w 結果をHTML出力
-p ファイル名 サーバに送信するファイルがある場合に指定
-T コンテンツタイプ HTMLコンテンツヘッダを指定
-C ‘Cookie名称=値’ Cookieを指定
-A ユーザ名:パスワード Basic認証を行う場合に指定
-P ユーザ名:パスワード プロキシ接続の場合で、パスワード設定がある場合に指定
-X プロキシサーバ名:ポート番号 プロキシ接続のポート番号

実行結果

コマンドラインで実行すると、次のようにコンソールに出力されます。

$ ab -n 100 -c 10 http://localhost/

Server Software:        Apache/2.4.6
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        44076 bytes

Concurrency Level:      10
Time taken for tests:   10.247 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      4453200 bytes
HTML transferred:       4407600 bytes
Requests per second:    9.76 [#/sec] (mean)
Time per request:       1024.692 [ms] (mean)
Time per request:       102.469 [ms] (mean, across all concurrent requests)
Transfer rate:          424.40 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       43   65  16.7     65     180
Processing:   309  931 383.8    829    3127
Waiting:      149  654 218.3    623    1197
Total:        367  996 384.8    880    3193

Percentage of the requests served within a certain time (ms)
  50%    880
  66%   1149
  75%   1206
  80%   1215
  90%   1441
  95%   1483
  98%   2152
  99%   3193
 100%   3193 (longest request)

注目するべき項目リスト

次の項目は、パフォーマンスに大きく影響がある注目すべき値です。

name 説明
Complete requests 総リクエスト数
Failed requests 失敗したリクエスト数
Requests per second 1秒あたりのリクエスト数
Time per request 1リクエストの平均処理時間
Transfer rate 1秒あたりのバイト数
Connection Times (ms) 最小値(min)、平均値(mean[+/-sd])、中央値(median)、最大値(max)を、接続時間(Connect)、処理時間(Processing)、待ち時間(Waiting)で表記
Percentage of the requests served within a certain time (ms) 時間内に処理されたリクエストの割合。「50% 880」は0.880秒以内でリクエスト処理された件数が全体の50%という意味。

まとめ

これほど簡単にサーバ負荷を確認出来るツールはあまりありません。コマンドを暗記しているユーザも多いでしょう。

簡易なだけに機能は限定的ですが、初期構築時やサイトが調子悪いときなど、診断的に確認をするのにちょうど良いと思います。

また、パフォーマンスに影響がありそうな改修を行った際に、すぐに確認する癖を付けておけば、それだけでも品質確保に役立つと思います。

参考



オープンソースカンファレンス北海道に出展しました

$
0
0

6月13日(土)、東札幌の札幌コンベンションセンターにて開催されたオープンソースカンファレンス北海道にhifiveとして出展しました!


数多くの方にご来場いただき、hifiveを知っていただくきっかけになりました。ぜひhifiveを使ってHTML5アプリケーションを開発して貰えればと思います。


こちらは準備中の様子。


懇親会も大いに盛り上がりました!


今後もオープンソースカンファレンスに参加していく予定です。全国の皆さま、ぜひhifiveブースに遊びに来てください!

OSPN – We Are Open!!


Webサーバの負荷・ロードテストツール(2)「Locust」

$
0
0

LocustはPythonで制作されたWebサーバの負荷テストツールの一つで、MasterとSlaveによる分散テストも可能なツールとなっています。

はじめに(ご注意ください!)

今回紹介するテストツールは、DOS攻撃にも利用出来てしまいます。テストを行う時は、サーバのURLが正しいか注意し、他人のサーバに間違ってもアクセスしないようにくれぐれもご注意願います。

インストール

インストールはPythonが実行出来る環境が必要です。またここでは、パッケージ管理の「pip」を利用していますが、ここでは割愛しますので予め用意して下さい。

pipを使ってlocust本体とpyzmqをインストールします。

$ pip install locustio
$ pip install pyzmq

テストシナリオの設定

Locustはテストシナリオの設定ファイルが必要になります。設定ファイルは「locustfile.py」として保存すると、実行時に設定ファイルを読み込んでくれます。

以下は単純にサイトを読み込むだけの、極簡単なスクリプトです。

from locust import HttpLocust, TaskSet, task

class WebsiteTasks(TaskSet):

    @task(1)
    def index(self):
        self.client.get("/")

    @task(2)
    def search(self):
        self.client.get("/search.html")

class WebsiteUser(HttpLocust):
    task_set = WebsiteTasks
    min_wait = 5000
    max_wait = 15000

設定ファイルの説明

  • WebsiteTasksクラスは、各タスクを設定するクラスです。TaskSetクラスを継承しています。@taskの括弧内の数値は、重み付けです。@task(2)は、@task(1)に対して、約倍の実行比率となります。

    self.client.get()には、テストサイトのGETメソッド・パラメータを記述します。

  • WebsiteUserクラスが実行時のクラスです。HttpLocustクラスを継承しています。task_setに、上記WebsiteTasksクラスを設定します。

    min_wait、max_waitについては、それぞれタスクの待ち時間をミリ秒で設定します。

これ以外にも、Basic認証などの設定などや、CSVなどで記述したテストデータを外部から取込み、その情報を元に繰り返しテストすることもできます。テストはスクリプトで記述できるので、柔軟にテスト設計ができると思います。

実行方法

基本の実行コマンドは、以下の通りです。実行時のカレントディレクトリにあるテストシナリオファイルの「locustfile.py」を読み込みます。

$ locust -H http://test-site.xxx

別のシナリオファイルを読み込む場合は、-f オプションを設定します。

$ locust -f test.py -H http://test-site.xxx

その他のオプションパラメータ

locustの代表的なオプションを例に挙げます。

オプション 説明
-H HOST テストサイトのURL
-P PORT テストサイトのポート番号
-f LOCUSTFILE Locustの設定ファイル
–no-web CLIとして稼働させる場合に設定(-c、-rが必要です)
-c NUM_CLIENTS クライアント数を設定
-r HATCH_RATE Hatch rate(1秒間に作成するユーザ数)を設定
–web-port=PORT WEBコンソール画面のポート番号(デフォルトは8089)

実行画面

スタンドアローンでのWEB実行画面です。デフォルトでは、「http://localhost:8089」で接続出来ます。

locust first
locust first
  • Number of users to simulate(シミュレートするユーザ数)
  • Hatch rate(1秒間に作成するユーザ数)

それぞれ、値を設定してから、「Start swarming」をクリックします。

実行中の画面です

locust start
locust start
  • 随時、結果は更新されていきます。
  • Stopボタンを押すことで、テストを停止します。

実行後の画面です。

locust finish
locust finish
  • 結果はメニューの「Download Data」から、CSVなどでダウンロードも可能です。

分散環境テスト

疑似高負荷環境を作成する時は、さすがに端末が1台だけでは無理があります。 実際、高負荷設定でLocustを動かすと、端末にかなりの負荷が掛かります。Locustでは、複数台の端末を利用しアクセスすることで、アクセスを分散する事が可能です。

実行方法は、1台の端末(Master)に対して、複数の端末(Slave)を用意するだけです。

Masterの端末

マスターとしてlocustを起動します。

$ locust -H http://test-site.xxx --master

Slave側の端末

Slaveとしてlocustを起動します。–master-hostパラメータでMasterのURLかIPを指定します。

$ locust -H http://test-site.xxx --slave --master-host=xxx.xxx.xxx.xxx

まとめ

テストシナリオファイルはPythonスクリプトで記述していますが、簡単に動かすだけであれば、Pythonになれていない方でも、すぐに理解出来るでしょう。

テストはスクリプトでコントロールしますので、柔軟にテスト設計ができることが、このツールの強みだと思います。

また、高負荷のテストを行う場合にも、分散環境が用意されていますので、他の負荷テストツールと比較しても十分な性能をもったツールと言えるでしょう。

参考


PitaliumをGradleからつかってみよう!

$
0
0

Pitalium(ピタリウム)とは、hifiveのテスト支援ツールとして開発されているWebアプリ開発における画面系のリグレッションテストに対応するライブラリです。JUnitから利用できるライブラリですので、Javaにおけるユニットテストに慣れていれば、すぐに扱うことができるでしょうライセンスはオープンソース(Apache License 2.0)になります。今回は簡単にその動作を見ていきましょう。

Pitalium(hifiveリグレッションテストライブラリ)

Pitaliumを利用するにあたり、Seleniumの環境依存の設定があります。今回はGradleで環境を構築していきましょう。

主な手順は以下の通りです。

  1. ライブラリのダウンロード
  2. Selenium Standalone Server の設定と起動
  3. Gradleでの環境構築
  4. Pitalium テストコード作成
  5. テスト実行

本記載にあたって、各ディレクトリを以下の通りとします。 適宜環境に合わせて読み替えて下さい。

Seleniumサーバーパス: /pitalium
ソースコード: /pitalium-test

1. 各ライブラリのダウンロード

Pitalium本体とSeleniumサーバ、Seleniumの各ブラウザ用Driverをダウンロードします。

1–1. Pitalium リグレッションテストライブラリ

Pitalium ダウンロードサイトよりダウンロードして下さい。

執筆時点では、1.0.1が最新バージョンです。解凍後、pitalium–1.x.x.jar を後述するテストコードのlibsディレクトリに配備します。

/pitalium-test/libs/pitalium-1.0.1.jar

なお、IE DriverはPitalium用に用意されたものを利用します。同じく解凍後のフォルダから、Windowsのビット数に合ったドライバを取得し、Seleniumサーバパスに配備します。

Windows用 IEDriver
32bit版Windowsの場合:pitalium_x.x.x/IE/x86/IEDriverServer_h5mod_2.xx.x.exe
64bit版Windowsの場合:pitalium_x.x.x/IE/x64/IEDriverServer_h5mod_2.xx.x.exe

pitaliumパスにコピーします
/pitalium/IEDriverServer_h5mod_2.xx.x.exe

1–2. Selenium Standalone Server

Selenium Standalone Server ダウンロードサイトよりダウンロードして下さい。執筆時点では、2.48.2が最新バージョンです。ダウンロードしたファイルは、pitaliumディレクトリに配備します。

/pitalium/selenium-server-standalone-2.48.2.jar

1–3. ChromeDriver

Chromeでテストするには、ChromeDriverが必要になります。ChromeDriver – WebDriver for Chrome ダウンロードサイトよりダウンロードして下さい。執筆時点では、2.20が最新バージョンです。ダウンロードしたファイルは、seleniumディレクトリに配備します。

Winの場合

/pitalium/chromedriver.exe

Macの場合

/pitalium/chromedriver

2. Selenium Standalone Server の設定と起動

Pitaliumには、Seleniumサーバが必要になります。今回はローカルで起動することを前提とします。

2–1. Seleniumサーバの起動

サーバ構成はこのような形になります。

Selenium サーバ構成
Selenium サーバ構成

まずは、各テストのHubとなるSelenium Hubサーバを立ち上げます。今回はローカル環境かつPCブラウザだけのテストですので、あまりHubを立ち上げる意味はありませんが、後々ローカルPCでAndroidやiOSなどのテストを行う時に便利になってきます。例えば、ノード1にPCブラウザの設定、ノード2にAndroid、ノード3にiOSの設定といった具合です。また、大規模になればなるほどテストに時間とCPUリソースなどがかかりますので、テストサーバを分散させることが必要になってくるでしょう。ここで確認も含めて設定しておきましょう。

Selenium Hubサーバ

Selenium Hubサーバの起動は次のコマンドを起動して下さい。

$ cd c:\pitalium
$ java -jar selenium-server-standalone-2.48.2.jar -role hub 

Selenium Nodeサーバ

ノードサーバの起動には、NodeConfigファイルが必要になりますので、次の通り用意して下さい。なお、各設定値はこちらを参照して下さい。

Selenium Gridの設定(Capability) – hifive

/pitalium/NodeConfigBrowser.json

{
  "capabilities": [
    {
      "browserName": "firefox",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "chrome",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "internet explorer",
      "version": "11",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "configuration": {
    "hub": "http://localhost:4444/grid/register"
  }
}

Selenium Nodeサーバを起動するため、以下のコマンドを起動します。毎回起動するには長くなりますので、バッチファイルやshellを作成しておくと良いでしょう。

Windowsの場合

$ cd c:\pitalium
$ java -jar selenium-server-standalone-2.48.2.jar ^
    -role webdriver ^
    -nodeConfig NodeConfigBrowser.json
    -Dwebdriver.ie.driver=IEDriverServer_h5mod_2.46.0.exe ^
    -Dwebdriver.chrome.driver=chromedriver.exe

Macの場合

$ cd /pitalium
$ java -jar selenium-server-standalone-2.48.2.jar \
    -role webdriver \
    -nodeConfig NodeConfigBrowser.json
    -Dwebdriver.chrome.driver=chromedriver

2–2. Seleniumサーバの確認

起動後は、以下に接続してサイトが開けばOKです。

http://localhost:4444/grid/console/
selenium-grid-console_new
selenium-grid-console

3. Gradleでの環境構築

Javaを利用しますので、JDKは必須です。予めインストールして下さい。前述の通り、今回はGradleで環境を構築します。また、Seleniumサーバは上記「2. Selenium Standalone Server の設定と起動」を参考に、予め立ち上げておいて下さい。

3–1. gradleのインストール(Windows版)

Gradle公式サイト から最新版を入手します。入手したファイルを解凍してファイルを適当な場所に配備します。配備したフォルダを環境変数GRADLE_HOMEに設定します。パスは、GRADLE_HOME/binに通しておいて下さい。

3–2. gradleのインストール(Mac版)

Homebrewでインストールできます。

$ brew install gradle

3–3. gradleインストール確認

Gradleのバージョン確認をしておきましょう。

$ gradle -v

------------------------------------------------------------
Gradle 2.8
------------------------------------------------------------

Build time: 2015-10-20 03:46:36 UTC
Build number: none
Revision: b463d7980c40d44c4657dc80025275b84a29e31f

Groovy: 2.4.4
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_60 (Oracle Corporation 25.60-b23)
OS: Windows 7 6.1 amd64

上記の様にバージョンが表示されればOKです。

4. Pitaliumでスクリーンショットを取ってみる

4–1. ディレクトリ構成

今回は簡単に動作確認を行うだけですので、下記の通り必要最低限の設定となります。

.pitalium-test
├── build.gradle
├── libs
│   └── pitalium-1.0.1.jar
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        │   └── com
        │       └── htmlhifive
        │           └── pitalium
        │               └── HifivePitaliumTest.java
        └── resources
            └── capabilities.json

4–2. Pitalium ライブラリ

「1–1. Pitalium リグレッションテストライブラリ」でダウンロードしたPitalium本体のJarファイルを、libsディレクトリに配備しておいて下さい。

4–3. Gradle buildファイル

Gradleのbuildファイルbuild.gradleの設定です。特に依存クラスの設定は必須項目ですので、記述漏れやミスにご注意下さい。Log関連については、log4j2を利用していますが好きなlogライブラリを設定して下さい。

/pitalium-test/build.gradle

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

// 依存クラスの設定
dependencies {
    // logging log4j2
    compile group: 'org.slf4j', name: 'slf4j-api', version: '+'
    compile group: 'org.slf4j', name: 'slf4j-nop', version: '+'
    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '+'

    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '+'
    compile fileTree(dir: 'libs', include: '*.jar')

    // junit & selenium
    testCompile group: 'junit', name: 'junit', version: '+'
    testCompile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '+'
    testCompile group: 'org.seleniumhq.selenium', name: 'selenium-server', version: '+'
    testCompile group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version: '+'
}

// タスクの同時実行数
test.maxParallelForks = 6

// Javaコンパイル時の文字コード指定(特にWin環境で必須)
tasks.withType(JavaCompile){
    options.encoding = 'UTF-8'
}

4–4. capabilitiesファイル

capabilities.jsonはどのブラウザでテストするかを記述します。記述されるブラウザは全てテスト対象となり、テスト時に各ブラウザで実行されます。特に必要なければ、ブラウザの記述ブロックを削除するだけです。

/pitalium-test/src/test/resources/capabilities.json

Windows用

[
  {
    "platform": "WINDOWS",
    "browserName": "chrome"
  },
  {
    "platform": "WINDOWS",
    "browserName": "firefox"
  },
  {
    "platform": "WINDOWS",
    "browserName": "internet explorer",
    "version": "11"
  }
]

Mac用

[
  {
    "platform": "MAC",
    "browserName": "chrome"
  },
  {
    "platform": "MAC",
    "browserName": "firefox"
  }
]

4–5. テストコードを記述する

最後にスクリーンショットを取るテストコードを記述します。PtlTestBaseを継承して、JUnitのテストクラスを記述します。

/pitalium-test/src/test/java/com/htmlhifive/pitalium/HifivePitaliumTest.java

package com.htmlhifive.pitalium;

import com.htmlhifive.pitalium.core.PtlTestBase;
import org.junit.Test;

/**
 * Pitaliumでスクリーンショット
 */
public class HifivePitaliumTest extends PtlTestBase {

    @Test
    public void test1() throws Exception {
        // 1. hifiveサイトのトップページを開きます
        driver.get("https://www.htmlhifive.com/");

        // 2. hifiveサイトのトップページのスクリーンショットを撮影します
        assertionView.assertView("OpenhifiveTopPage");
    }

}

5. Pitalium テスト実行

テストコードのルートディレクトリに移動して、コマンドラインからGradleを実行します。

$ cd /pitalium-test
$ gradle build

Gradleインストール後の最初のビルドでは、ライブラリのダウンロードなどで数分程度かかります。無事にビルドが出来れば、自動でテストも実行されます。一度ビルドできれば、次回からは次のGradleコマンドで実行すればOKです。

$ gradle clean test

実行すると、ブラウザが自動で立ち上がり、スクリーンショットが以下のディレクトリに保存されます。

/pitalium-test/results/yyyy_MM_dd_hh_mm_ss/HifivePitaliumTest

また、直近のGradleのテスト結果は、以下のディレクトリにHTMLで保存されます。こちらも合わせて確認すると良いでしょう。

/pitalium-test/build/reports/tests

gradle test result
gradle test result

まとめ

SeleniumとPitaliumの設定から起動までを、Gradleで実行する方法を見ていきましたが、いかがでしたでしょうか? Pitaliumは、Seleniumの操作に加え、画面のスクリーンショットを利用して差分を比較することもできるライブラリです。Seleniumだけで行うよりも簡易にリグレッションテストが出来ますので、ぜひ試してみて下さい。

ご興味のある方はチュートリアル(Pitalium:hifiveリグレッションテストライブラリ) – hifiveを参考にして下さい。

過去のPitaliumに関するブログはこちら


Pitaliumを使ってAndroidのリグレッションテスト

$
0
0

今回は、前回の「PitaliumをGradleからつかってみよう!」を利用して、Androidでのテストを行ってみようと思います。

今まで、スマートフォンでのテストを躊躇していたエンジニアの方にチャレンジして頂きたい内容となっています。是非、ご覧下さい。

AndroidのPitaliumテストにはAppiumを利用します。
AppiumとはSeleniumとAndroidデバイスを繋ぐためのNodeサーバです。

Appium: モバイルアプリのテスト自動化ツール

起動構成はこのようになります。
selenium-appium

注意事項

対象のAndorid OSは、Android4.2以降をターゲットとしています。
それより前のAndroid端末についてはAndroid端末上でテストを行う(コマンドライン)をご確認下さい。

1. 事前準備

本記載にあたって、各ディレクトリを以下の通りとします。
適宜環境に合わせて読み替えて下さい。

Seleniumサーバーパス: /pitalium  
ソースコード: /pitalium-test

1–1. Java SDKのインストール

Java SE – Downloads | Oracle Technology Network | Oracleから、テスト環境に合った最新バージョンを入手して下さい。

1–2. Android SDKのインストール

Android SDKのダウンロード

Download Android Studio and SDK Tools | Android Developersより、Android SDKをダウンロードして任意の場所に解凍します。

ダウンロードする箇所が解りにくくなっていますが、セクション「Other Download Options」にある「SDK Tools Only」のプラットフォーム別のファイルです。

Android 環境設定

環境変数のPathに以下の場所をANDROID_HOMEとして追加します。

Macの場合

(Android SDKのインストールフォルダ)\android-sdk-macosx

Windowsの場合

(Android SDKのインストールフォルダ)\android-sdk-windows

以下のパスもWindowsであればシステム環境設定で追加しておきましょう。 Macユーザの場合は.zshrcや.bashrcなどに設定しておいて下さい。

ANDROID_HOME/platform-tools
ANDROID_HOME/tools

Android パッケージのインストール

コマンドラインからAndroid managerを起動します。

$ android

以下のパッケージをインストールします。

  • Tools
  • Android SDK Tools
  • Android SDK Platform-tools
  • Android SDK Build-tools
  • Android 4.4.2(API 19)(17以上ならどれでも良い)
  • SDK Platform
  • Extras
  • Google USB Driver

Android端末の接続

  1. Android端末をテスト実行するPCに接続します。
  2. Android端末の設定で、USBデバッグを有効にします。
  3. 接続した端末が認識されているか確認します。端末IDが表示されればOKです。
$ adb devices
List of devices attached
[端末ID]  device

SeleniumサーバのHubを起動

Selenium Standalone ServerはSelenium Standalone Server ダウンロードサイトよりダウンロードして下さい。

ダウンロードしたファイルは、次のディレクトリに配備します。

/pitalium/selenium-server-standalone-2.48.2.jar

Selenium Hubサーバの起動は次のコマンドで起動して下さい。

$ java -jar /pitalium/selenium-server-standalone-2.48.2.jar -role hub

2. Appiumのインストールと起動

インストールにはNodeJSを利用しますので、予めインストールしておいて下さい。

2–1. Appiumのインストール

以下のコマンドを実行して、インストールします。

$ npm install -g appium

インストール後は、チェックコマンドがありますので、次を実行して下さい。

$ appium-doctor

全てのチェックが通ると、最後に次のメッセージが出力されます。

✔ All Checks were successful

2–2. Appiumのcapabilitiesの設定

AppiumのNodeConfigの設定を記述します。
nodeConfigAndroid.jsonとして配備します。

/pitalium/nodeConfigAndroid.json

{
  "capabilities": [
    {
      "platform": "ANDROID",
      "browserName": "chrome",
      "version": "4.4.2 SH307",
      "maxInstances": 1,
      "seleniumProtocol": "WebDriver"
  }
  ],
  "configuration": {
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
    "url": "http://127.0.0.1:4723/wd/hub",
    "host": "127.0.0.1",
    "port": "4723",
    "maxSession": 1,
    "register": true,
    "registerCycle": 5000,
    "hubPort": 4444,
    "hubHost": "localhost"
  }
}

上記は、ローカル環境で動かす最低限の設定です。

capabilitiesの説明

項目 説明
platform Android端末の場合 “ANDROID”
browserName “chrome” 固定
version 任意の値。AndroidのOSバージョン+デバイス名とする事を本記事では推奨。
maxInstances テストを行う最大インスタンス数
seleniumProtocol “WebDriver” 固定

configurationの説明
注目すべき項目のみを説明しています。他はデフォルトではサンプルの通りとして下さい。

項目 説明
url Appiumが稼働するサーバアドレス
host urlのHost部分
port urlのport部分
hubHost Selenium HubサーバのHostアドレス
hubPort Selenium Hubサーバのport

設定値の詳しくはAppium API Referenceを参照して下さい。

2–3. Appiumの起動

事前に起動した、Selenium Hubサーバに接続します。

–nodeconfig オプションに渡すファイルは、フルパスで記述する必要がありますので注意して下さい。

$ appium --nodeconfig /pitalium/nodeConfigAndroid.json

以下のように、待ち受けが始まればOKです。

info: Welcome to Appium v1.4.13 (REV c75d8adcb66a75818a542fe1891a34260c21f76a)
info: Appium REST http interface listener started on 0.0.0.0:4723
info: [debug] Non-default server args: {"nodeconfig":"/pitalium/nodeConfigAndroid.json"}
info: Console LogLevel: debug
info: [debug] starting auto register thread for grid. Will try to register every 5000 ms.
info: --> GET /wd/hub/status {}
info: [debug] Responding to client with success: {"status":0,"value":{"build":{"version":"1.4.13","revision":"c75d8adcb66a75818a542fe1891a34260c21f76a"}}}
info: <-- GET /wd/hub/status 200 11.569 ms - 105 {"status":0,"value":{"build":{"version":"1.4.13","revision":"c75d8adcb66a75818a542fe1891a34260c21f76a"}}}
info: [debug] Appium successfully registered with the grid on localhost:4444

これでサーバの準備は整いました。

3. Pitaliumでスマートフォンのテスト

3–1. ディレクトリ構造

.pitalium-test
├── build.gradle
├── libs
│   └── pitalium-1.0.1.jar
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        │   └── com
        │       └── htmlhifive
        │           └── pitalium
        │               └── HifivePitaliumTest.java
        └── resources
            └── capabilities.json

以下のファイルは、前回記事と同じ物を利用します。

  • Gradleのbuildファイル
  • gradle.build
  • pitalium本体のjarファイル
  • /pitalium-test/libs/pitalium-1.0.1.jar
  • テストコード本体
  • /pitalium-test/src/test/java/com/htmlhifive/pitalium/HifivePitaliumTest.java

3–2. capabilitiesファイル

ここでポイントとなる項目は、“platform”、“browserName”、“version” です。 これらの項目は、Appiumを起動するときに設定したnodeConfigAndroid.jsonと同一の値を指定します

/pitalium-test/src/test/resources/capabilities.json

[
  {
    "platform": "ANDROID",
    "browserName": "chrome",
    "version": "4.4.2 SH307",
    "platformVersion": "19",
    "platformName": "Android",
    "deviceName": "SH307"
  }
]

capabilitiesの説明

項目 説明
platform Appinumサーバで指定した同項目値を設定
browserName Appinumサーバで指定した同項目値を設定
version Appinumサーバで指定した同項目値を設定
platformVersion 実行する端末のAPIバージョン
platformName “Android”固定 Android端末の場合
deviceName 対象のデバイス名(任意の名称)

※いずれも必須項目です。

3–3. テスト実行

テストコードのルートディレクトリに移動して、コマンドラインからGradleを実行します。

$ cd /pitalium-test
$ gradle build

実行すると、接続されたAndroid端末のブラウザが立ち上がり、PCと同様スクリーンショットが保存されます。

/pitalium-test/results/yyyy_MM_dd_hh_mm_ss/HifivePitaliumTest

次回からは次のGradleコマンドを実行すればOKです。

$ gradle clean test

最後に

Pitaliumを利用した、Androidの設定から起動までを行いました。
こちらもサーバ設定さえクリアしてしまえば、特に問題になることはないでしょう。

フロントエンドは、スマフォの開発がほぼ必須となっている状況かと思います。
Pitalium+Appliumを利用することで、スマフォのリグレッションテストも可能になります。
品質向上のために、導入をご検討してはいかがでしょうか。
今回は、Android端末の紹介でしたが、iOSなどの対応も次回以降に見ていきたいと思います。

Pitaliumにご興味のある方はチュートリアル(Pitalium:hifiveリグレッションテストライブラリ) – hifiveも参考にして下さい。

 

過去のPitaliumのブログはこちら


Pitaliumを使ってSafariでリグレッションテストを実行

$
0
0

Windows環境しかないのですが、Safariでのデバッグは可能でしょうか。いえ、現状ではMac OSXが必要です。残念なことに、すでにApple社はWindows版のSafariを提供していません。

過去のSafariバイナリをインストールして稼働することもできるようですが、Appleがサポートを終了していること、さらにHTML5の実装も変わっていることからWindowsでSafariを対応することは現実的ではないでしょう。今回は、MacOS Xによる、Safariでのデバッグ方法を確認していきましょう。

尚、本記事の環境については、以下の通りです。

  • MacOS X 10.10.5
  • Safari バージョン 8.0.8 (10600.8.9)

前回から利用している、Selenium HubサーバとNodeサーバを引き続き利用していきましょう。環境についても、各ディレクトリを以下の通り利用します。適宜環境に合わせて読み替えて下さい。

Seleniumサーバーパス: /pitlaium  
ソースコード: /pitalium-test

Mac OSX Safariを利用したデバッグ方法

以前まで、Safari拡張としてSeleniumのSafariDriverをMacで作成しなければならず、そのために、証明書を取得したりするなど、難易度が高めの設定でした。しかし最近はSeleniumサイドが、Safari拡張用の実行ファイルを用意しているので、インストールはクリックだけで済むようになりました。証明書取得など、全く必要ありませんし、AppleIDも必要ありません(Mac使ってる人は持ってると思いますが…)。

SafariDriverのインストール

SafariDriver Downloadsのダウンロードサイトの、SafariDriverのセクションよりSafariDriver.safariextz をダウンロードして下さい。

safaridriver
SafariDriver Downloads

あとは、ダウンロードSafariDriver.safariextz をクリックするとSafari拡張インストールが始まります。無事インストールが終わったら、Safariの環境設定を開き、「機能拡張」をクリックして下さい。

次の画面の通り、WebDriverが無事インストールされていればOKです。
この時、機能拡張のスイッチが「入」側になっているか確認しておいて下さい。

SafariDriver Downloads
SafariDriver Downloads

Nodeサーバの設定

Nodeサーバには次のNodeConfigファイルをSafari向けに更新します。Safariの定義を追加して保存しておきましょう。

/pitalium/NodeConfigBrowser.json

{
  "capabilities": [
    {
      "browserName": "firefox",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "chrome",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "safari",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "configuration": {
    "hub": "http://localhost:4444/grid/register"
  }
}

Selenium Hubサーバを立ち上げます。

$ cd /pitalium
$ java -jar /pitalium/selenium-server-standalone-2.48.2.jar -role hub

次に、Nodeサーバを起動します。

$ cd /pitalium
$ java -jar selenium-server-standalone-2.48.2.jar \
    -role webdriver \
    -nodeConfig NodeConfigBrowser.json \
    -Dwebdriver.chrome.driver=chromedriver

Seleniumコンソールをブラウザで確認して、Safariが設定されていればOKです。

http://localhost:4444/grid/console

gridconsole

Selenium Console

テストコード側の設定

テストコード側で利用するブラウザを設定します。Safariの設定を記述して保存します。

/pitalium-test/src/test/resources/capabilities.json

[
  {
    "platform": "MAC",
    "browserName": "safari"
  }
]

Safariでテスト実行

後はこれまでと同様にテストを実行するだけです。

$ gradle build

もしくは、こちらで可能です。

$ gradle clean test

実行後には、テスト結果がHTMLで作成されますので、以下にあるテスト結果を確認しましょう。

/pitanium-test/build/reports/tests/index.html

最後に

Mac OSXのSafariでもPitaliumを利用してテストが可能です。以前までは、Safari開発者の証明書取得とWebDriverのコンパイルもしなければならず、
WebDriverの作成自体が困難だったのではないでしょうか。

現在ではWebDriverの提供があるため、インストールは非常に簡単です。こちらもサーバ設定さえクリアしてしまえば、他のブラウザ同様、特に問題になることはないでしょう。

これを機会にぜひMacOSX Safariでのテストも検討して下さい。

Pitaliumにご興味のある方は、チュートリアル(Pitalium:hifiveリグレッションテストライブラリ) – hifiveも参考にして下さい。


Pitaliumを使った実際のワークフローについて

$
0
0

Pitaliumはスクリーンショットを利用して画面の差分比較ができるのがPitaliumの最大の特徴です。そのためにはまず基準となるスクリーンショットが必要になり、それをテスト実行モードで切り替えることで実現しています。今回は実際に差分比較を行うためのワークフローを見ていきましょう。

なお、利用しているのはTODO管理になります。

実行モードについて

画面比較を行うにあたって基準となる画面をキャプチャするのですが、Pitaliumには幾つかの実行モードがあります。それぞれ次のようになっています。

モード 内容
TAKE_SCREENSHOT スクリーンショットの取得のみ(Assertionは無視)
SET_EXPECTED 比較基準値となる画面を作成するモード(デフォルト)
RUN_TEST 基準画面との比較を行うモード

このモードは以下のファイルに記載するか、JUnitの実行時パラメータに含めることで変更できます。

src/main/resources/environmentConfig.json

{
  "execMode": "RUN_TEST"
}

JUnit VM実行パラメータに含める場合

-Dcom.htmlhifive.pitalium.execMode=RUN_TEST

モードの詳しい仕様はライブラリ仕様 – hifiveでも確認できます。

現在の状態を保存してみる

それではテストを行うための比較基準となる画面を取得してみましょう。先に説明したとおり、モードをSET_EXPECTEDとして実行するだけです。

なお、デフォルトで指定がない限りモードはSET_EXPECTEDとなります。この場合、当然ですが画面比較は行われませんので注意して下さい。

public class PitaliumTodoTest extends PtlTestBase {
  @Test
  public void test1() throws Exception {

      // TODOサイトのトップページを開きます
      driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");

      // 比較対象を使用して検証を実行します。
      assertionView.assertView("ToDoTOP");
  }
}

上記をテスト実行すると、デフォルト設定では次のディレクトリに各画像や基準値のデータが設定されます。

実行日付のディレクトリ以下、テストクラス名とその画像が保存されます。以下は、そのディレクトリ例です。

results
├── 2015_11_10_13_43_41
│   └── PitaliumTodoTest
│       ├── result.json
│       ├── test1_ToDoTOP_MAC_chrome.json
│       ├── test1_ToDoTOP_MAC_chrome.png
│       └── test1_ToDoTOP_MAC_chrome_TAG_NAME_body_[0].png
└── currentExpectedIds.json

この中で、currentExpectedIds.jsonに、基準値となる情報が入ります。

{
  "PitaliumTodoTest" : {
    "test1" : "2015_11_10_13_43_41"
  }
}

上記の場合テストケースのtest1は、result/2015_11_10_13_43_41にある基準画像を利用するという意味になります。

比較してみよう

それでは、実際に比較してみましょう。テストケースから画面TODO項目を追加する処理を入れて比較してみます。実行モードは、RUN_TESTとして下さい。

public class PitaliumTodoTest extends PtlTestBase {
  @Test
  public void test1() throws Exception {

      // TODOサイトのトップページを開きます
      driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");

      // 新しくTODO内容を追加します。
      driver.findElementById("txtTodo").sendKeys("新しくTODO追加");
      driver.findElementById("btnRegist").click();

      // 比較対象を使用して検証を実行します。
      assertionView.assertView("ToDoTOP");
  }
}

上記でJUnitを実行すると、項目が新しく追加されて基準値となる画面と比較して変更が出ていますのでテストはエラーとなります。

Compare JUnit
Compare JUnit

※ 画面はIntelliJ IDEAのものです。

以上が、Pitaliumの画面比較機能の利用方法です。

部分的なDOMに変更があった場合

Pitaliumはもう一つ画面比較の特徴があり、DOMレベルで画面比較が可能です。Pitalium 1.0.1で加えられたBuilderパターンを使用し、addNewTargetメソッドでDOM要素を設定します。DOM要素は複数指定可能です。

@Test
public void test2() throws Exception {

    // TODOサイトのトップページを開きます
    driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");

    // 比較対象をDOMレベルで指定します。
    ScreenshotArgument arg = ScreenshotArgument.builder("ToDo-LastChild")
               // 撮影対象を指定
               .addNewTarget(SelectorType.ID, "list")
               .addNewTarget(SelectorType.CSS_SELECTOR, "#list tbody tr:last-child")
               .build();
    // 比較対象を使用して検証を実行します。 
    assertionView.assertView(arg);
}

また、部分的に比較を行わないという操作なども可能です。次のように、addExcludeメソッドで指定します。

@Test
public void test3() throws Exception {

    // TODOサイトのトップページを開きます
    driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");

    ScreenshotArgument arg = ScreenshotArgument.builder("ToDo-LastChild")
               // 比較対象をDOMレベルで指定します。 
               .addNewTarget(SelectorType.ID, "list")
                   // DOMレベルで除外指定します。ここでは、最後のTODO項目を除外します。 
                   .addExclude(SelectorType.CSS_SELECTOR, "#list tbody tr:last-child")
               .build();
    // 比較対象を使用して検証を実行します。
    assertionView.assertView(arg);
}

テストケース・エラー時のワークフロー

実際のプロジェクトが進めば、当然エラーになるケースが出てくるでしょう。この場合、まずはエラーとなったケースを見極めることから始めます。大きく分けて次の2通りとなるでしょう。

テストケースが問題の場合

  • 画面のレイアウト変更があった
  • 文言の修正が入った
  • 動的なコードが挿入された

テストケースが問題の場合は、もう一度基準画面を取り直すことでOKでしょう。ただし動的なコードが挿入された場合は比較から除外するなどのテストコード修正が必要になります。

コードが問題の場合

  • 間違えてCSSを弄った
  • 間違えてレイアウトを変更してしまった

こちらはテストケースに影響がないので対象のクラスや画面テンプレートを正しく変更し、再度テストを行えば良いでしょう。

また、Pitaliumの画面比較チェックは当然ですが内部的なコードの解析は行われません。その辺りは、Selenium側のテストで行えばよいでしょう。

最後に

Pitaliumを利用した画面比較のワークフローを見ていきましたが、いかがでしたでしょうか。簡単に設定が可能ですし、ワークフローさえ手順化されていればテストで迷うことはないと思います。

ただしPitaliumの画面比較を導入する場合は、その導入時期を見極める必要があるでしょう。頻繁に画面が更新される初期の開発において画面比較チェックまで含めてしまうとテストケースで頻繁にエラーが起こり、その都度テストが止まってしまう可能性が大きいです。導入は時期を見て、画面レイアウトが固まった段階で行うべきでしょう。

Pitaliumにご興味のある方はチュートリアル(Pitalium:hifiveリグレッションテストライブラリ) – hifiveも参考にして下さい。

過去のPitaliumの投稿はこちら


Dockerを使って素早くSelenium Grid環境を構築しよう

$
0
0

Pitaliumを使う際にはSelenium Gridを構築する必要があります。中央集約的にSelenium Hubというサーバを立てて、そこにぶら下がる形でSelenium Nodeを立てていきます。

Selenium Hubを立てても良いのですが、管理を簡易化するためにDockerを使った方法を紹介します。

Docker Toolboxを使おう

UbuntuやCentOSといったLinux環境であればDockerのインストールはさほど難しくありません。apt-getやyumを使ってインストールできます。対してWindowsやMac OSXの場合はLinuxの仮想環境を構築して、そこにDockerをインストールする必要があるので若干手間がかかります。そこで使いたいのがDocker Toolboxです。Docker Toolboxを使えばDockerに必要な環境が簡単にインストールできます。

インストールするとDockerはもちろんのこと、VirtualBoxであったり、Docker Machine、Docker Compose(Mac OSXのみ)などがインストールされます。インストール後、専用のコマンドプロンプト/コンソールを開くスクリプトが生成されますので、それを実行します。

Dockerを実行する

Dockerを起動したら、Selenium Hubのイメージを取得します。

$ docker run -d -p 4444:4444 --name selenium-hub selenium/hub:2.48.2

これだけでSelenium Hubが立ち上がります。Selenium Hubにアクセスする場合は、仮想環境のIPアドレスなので http://192.168.99.100:4444/grid/console などになるかと思います。

そしてさらにこの環境向けにGoogle ChromeやFirefoxを使いたい場合は、

$ docker run -d --link selenium-hub:hub selenium/node-chrome:2.48.2
$ docker run -d --link selenium-hub:hub selenium/node-firefox:2.48.2

でそれぞれ準備ができます。この二つを接続すると、Selenium Hubの管理画面は次のようになります。

Safariを接続する

今回はMac OSX上で実行していますので、Safariも接続してみます。まず最初に専用のSafari機能拡張が必要です。これはSeleniumのGitリポジトリでコンパイルするのが推奨されますが、Google Code上で公開されているものを使うこともできます。ただ2.45で更新が止まっていますので最新版のSafariでは動かない可能性がありますのでご注意ください。

次にApple Developer Program – Apple Developerとして登録し、証明書を作成する必要があります。この辺りの手順は省きますが、iOSアプリの開発時に作成する証明書の手順と同等になります。

機能拡張をインストールすると、次のように表示されます。

インストールが終わったらSeleniumを自分でコンパイルするか、バイナリ公開されている最新版である2.48.2をダウンロードして、次のようにコマンドを実行します。

java -jar selenium-server-standalone-2.48.2.jar -role node -browserName=safari -hub http://192.168.99.100:4444/grid/register

これでSafariが接続されました。接続されると次のように表示されます。

テストスクリプトを書いてみる

今回はテストスクリプトとしてRubyで書いてみました。予め gem install selenium-webdriver を実行しておきます。

require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers

def setup
  @driver = Selenium::WebDriver.for(
    :remote,
    url: 'http://192.168.99.100:4444/wd/hub',
    desired_capabilities: :safari) # you can also use :chrome, :safari, etc.
end

def teardown
  @driver.quit
end

def run
  setup
  yield
  teardown
end

run do
  begin
    @driver.get 'http://www.htmlhifive.com/'
    # hifive - HTML5 Development Platform for Corporate Web Systems - hifive
    expect(@driver.title).to eq('hifive - HTML5企業Webシステムのための開発プラットフォーム - hifive')
  rescue
  end
end

これはSafariを起動するスクリプトなので、Mac OSXのSafariが立ち上がってhifiveのサイトが表示されます。

safariとなっているところをchrome、firefoxに変更すると、それぞれDocker内部で立ち上がって実行されます。そのため、この場合はブラウザが立ち上がることなくテストができますので邪魔になりません。もし実行している状態を見たい場合は、Selenium Nodeを

$ docker run -d -P --link selenium-hub:hub selenium/node-chrome-debug:2.48.2
$ docker run -d -P --link selenium-hub:hub selenium/node-firefox-debug:2.48.2

として立ち上げ、その上で

$ docker ps
CONTAINER ID        IMAGE
4211324efc16        selenium/node-firefox:2.48.2
356db01e6bd2        selenium/node-chrome:2.48.2
f016e29aa44a        selenium/hub:2.48.2

を実行してコンテナIDを確認し、

$ docker port 4211324efc16 5900

と実行することでVNCサーバのポートが開きます。後はRealVNCやMac OSX標準の画面共有アプリなどを使って接続できます。


Dockerを使えばテスト環境の構築がとても手軽になります。Selenium Hubを立ち上げれば、後はWindowsやMac OSXなどは関係なく、それぞれHubにつないでテストできるようになります。テストマシンを用意することで個々のマシンの負荷も軽減でき、さらにテストの自動化も考えられるようになるでしょう。

Pitaliumに関する過去の記事はこちら



Pitaliumをつかってみた〜 DockerとJenkinsでデバッグ 〜

$
0
0

前回までの記事で、すでにPitaliumを利用したデバッグ環境ができあがっていると思います。今回は、Jenkinsを利用して、PitaliumのCI(継続的インテグレーション)周りを見ていきましょう。尚、今回のサーバー構成とそのプロセスは次のような形を想定しています。

server-composition
server-composition

本テストではJenkins、Selenium Hub、Nodeサーバは全てDockerでの設定とします。管理されるコードはGitHubとし、JenkinsによりコードのチェックアウトとGradleを起動して、Seleniumサーバへ接続します。

今回はGitHubのリポジトリよりコードを取得しますので、あらかじめテストコードをGitHubへ配備しておきましょう。また、前回までの記事の中のSeleniumサーバとGradleの設定を利用しますので、ぜひ本シリーズの記事も合わせてご覧下さい。

1.Dockerを利用してJenkinsとSeleniumサーバを立ち上げる

まずは、Dockerを利用してJenkinsを立ち上げましょう。WindowsユーザもMacユーザもDocker Toolboxが利用できます。Docker Toolbox | dockerよりツールをダウンロードしてインストールして下さい。

※ 執筆時点ではWindowsでの動作は不安定のようです。MacもしくはLinux環境での利用をお勧めします。

今回はKitematicでDockerをコントロールしていきます。インストールして起動するとこのような画面が表示されます。

kitematic
kitematic

ここからJenkinsを選び、CreateボタンをクリックするとJenkinsのインストールが始まります。

インストールが完了するとJenkinsの起動画面となります。VOLUMESをクリックしてJenkinsが利用するディレクトリを設定します。

kitematic-volumes
kitematic-volumes

その後、左上あたりの「WEB PREVIEW」をクリックするとJenkinsが起動します。

次にSeleniumのサーバを設定、起動します。こちらはコマンドラインから以下のコマンドを実行して下さい。

docker run -d -p 4444:4444 --name selenium-hub selenium/hub
docker run -d -v /dev/urandom:/dev/random -P --link selenium-hub:hub selenium/node-chrome-debug

Dockerの設定は以上です。改めてDockerは便利だと感じます。

2.リソースファイルの修正

capabilitiesのplatform項目をLINUXとします。

/src/test/resources/capabilities.json

[
  {
    "platform": "LINUX",
    "browserName": "chrome"
  }
]

environmentConfig.jsonにSelenium hubのアドレスを指定します。

/src/test/resources/environmentConfig.json

{
  "hubHost": "xxx.xxx.xxx.xxx",
  "hubPort": 4444
}

Selenium Hubの起動アドレスの取得方法は色々ありますが、DockerのKitematicから下記の通り表示されますので、その値を設定して下さい。

jenkins-address
jenkins-address

3. Jenkinsでプロジェクトを設定する。

Jenkinsが起動すると次のような画面が表示されます。

jenkins-start
jenkins-start

今回はGitHubのリポジトリを利用しますので、GitHubプラグインのインストールが必要になります。まずはJenkinsのプラグイン設定を行います。サイドメニューよりJnekinsの管理 -> プラグインの管理 と進みます。

jenkins-plugin
jenkins-plugin

プラグイン管理の画面で 利用可能 タブをクリックして、左上のフィルタの項目に git plugin と入力します。絞り込まれた中に GIT plugin がありますのでチェックを入れて下さい。その後 再起動せずにインストール をクリックします。

jenkins-plugin−git
jenkins-plugin−git

すぐにインストールが始まります。念のため インストール完了後、ジョブが無ければJenkinsを再起動する にチェックを入れ、Jenkinsを再起動しておきましょう。

jenkins-plugin−restart
jenkins-plugin−restart

再起動したら、ダッシュボードから新しいジョブをクリックします。ジョブ名は pitalium-job としましたが任意でOKです。そして フリースタイル・プロジェクトのビルド にチェックして、 OK ボタンをクリックして下さい。

jenkins-newjob
jenkins-newjob

すぐにプロジェクトが作成され設定画面が開きます。プロジェクト名は入っていますが変更も可能です。

jenkins-project
jenkins-project

ソースコード管理のセクションで Git にチェックを入れます。リポジトリの設定フィールドが展開されますので、GITのデータを Repository URLCredentials の項目に設定します。Credentials は新しく追加をしておきます。Credentialsの 追加 ボタンをクリックして、次の画面を表示します。

jenkins-credentials
jenkins-credentials

ユーザ名パスワード にGitHubリポジトリにログインする値を設定して下さい。

下の方にスクロールして、ビルドセクションにテストのためのシェルの記述を行います。ビルド手順の追加 -> シェルの実行 をクリックすると、スクリプトの記入エリアが展開されます。ここに以下の一行を追記します。

$WORKSPACE/gradlew clean build

jenkins-build-setting
jenkins-build-setting

保存して終了します。そしてサイドメニューより ビルド実行 をクリックして下さい。問題がなければビルド履歴に正常終了を表す青丸となって終了します。正常終了の場合、Resultディレクトリ配下にスクリーンショットが配備されていますので確認して下さい。

jenkins-buildrun
jenkins-buildrun

赤丸となった場合は何らかのエラーですので、次の項目を再度チェックしてみて下さい。

  • リポジトリは正しいか?(ID、パスワードを含む)
  • コードはチェックアウトされているか?
  • VOLUEMESのディレクトリをクリックしてチェックして下さい。
    デフォルトでは/var/jenkins_home/jobs/pitalium-job/workspace/ 配下に配備されます。
  • DockerのSeleniumサーバは起動しているか?(ポートなどもチェック)

最後に

Jenkinsを利用してPitaliumを利用することで、定期的にテストを実行することが可能になります。Jenkinsは便利な反面、導入までの敷居が高いですが、Dockerを利用する事で簡単に設定することができました。

Seleniumサーバの設置も思いの外、簡単だったと思います。これを機会にぜひ導入を検討してみて下さい。

 

Pitaliumに関する過去の記事はこちら


Pitaliumをつかってみた 〜 サーバ周りのお話し 〜

$
0
0

今回はSelenium HubとNodeについてです。概ね想定できる設定について、主な設定箇所と注意するべきポイントをまとめてみました。どのような環境で構築したら良いのか、テスト環境構築方針を考慮する参考にして下さい。

HubとNodeが同一サーバで稼働している場合

この場合、明示的にHubとNodeを分けてサーバを起動させる必要はありません。

local-only
local-only

実行方法も、以下の通りコマンドラインから稼働させる事が出来ます。

java -jar selenium-server-standalone-2.48.2.jar

ただ、外部からのNode接続がある、もしくは今後その想定である場合はHubとNodeで分けた方が良いでしょう。

HubとNodeがリモートサーバ側にある場合

テスト環境からみて、Seleniumサーバが外部に存在する場合です。このケースではHubとNodeサーバを設定した方が良いでしょう。

local-linux
local-linux

Hubの起動

java -jar selenium-server-standalone-2.48.2.jar -role hub

Nodeの起動

java -jar selenium-server-standalone-2.48.2.jar \
    -role node \
    -nodeConfig NodeConfigBrowser.json \
    -Dwebdriver.chrome.driver=chromedriver

ケース図でのnodeConfig設定 NodeConfigBrowser.json

{
  "capabilities": [
    {
      "browserName": "firefox",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "chrome",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "safari",
      "maxInstances": 3,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "configuration": {
    "hub": "http://192.168.0.100:4444/grid/register"
  }
}

テスト環境では、リモートに接続する設定が必要になります。

environmentConfig.json 環境設定をHubのアドレスに設定します。

{
  "hubHost": "192.168.0.100",
  "hubPort": 4444
}

capabilities.json プラットフォーム指定は対象のサーバに合わせて下さい。

[
  {
    "platform": "LINUX",
    "browserName": "chrome"
  }
]

HubとNodeがリモートサーバ側にあり、さらにNodeが別のサーバの場合

Hubが確定してしまえばNodeがどこに増えたとしても基本的には同じです。

local-linux2
local-linux2

Nodeサーバの設定では configuration 項目で hub のアドレスを正しく設定します。

ただしテスト環境の capabilities.json ファイルでは注意が必要です。上記の例だとMac環境がSafariになっていますので、platformは MAC とする必要があります。

[
  {
    "platform": "MAC",
    "browserName": "safari"
  },
  {
    "platform": "LINUX",
    "browserName": "chrome"
  },
  {
    "platform": "LINUX",
    "browserName": "firefox"
  }
]

このようにテストが行なえるノードを確認しておかないと、接続できなくなる(対象のNodeがない)と言うことになりかねません。

まとめ

簡単にサーバ設定をみていきましたが、いかがでしたでしょうか?本番環境と等しく、あらかじめテストのためのサーバ構成を考慮することは大事です。参考にしてください。

Pitaliumに関する過去の記事はこちら


Pitaliumでページ読み込み完了まで待つには?

$
0
0

Seleniumを使ったテストの中で厄介なのが画面遷移を伴う操作で、画面の読み込み完了判定を行う時ではないでしょうか。StackOverflowでも同様の質問があがっており、その際に解答に上がっていたのは、

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

のようにJavaScriptを実行してreadyStateを監視するというものでした。

Pitaliumでは専用のメソッドを提供しています。それがPtlWebDriverのuntilLoadです。使い方は以下の通りです。

driver.get(url);
PtlWebDriverWait wait = new PtlWebDriverWait(driver, 30);
// ロードするまで待つ 
wait.untilLoad();
// ロードが完了してからスクリーンショットを取得する
assertionView.assertView("load_complete");

untilLoadの実際のコードは次のようになっています。

/**
 * ページのLoadイベント終了まで待機します。
 */
public void untilLoad() {
    final int sleepMillis = 100;
    try {
        Thread.sleep(sleepMillis);
        String beforeURL = getURL();
        try {
            addElement(DUMMY_TAG_ID);
            // このタイミングでページが切り替わるとタイムアウトを待つため、時間がかかる。
            until(FIND_DUMMY_TAG_CONDITION);
            deleteElement(DUMMY_TAG_ID);
        } catch (Exception ex) {
            String afterURL = getURL();
            if (!beforeURL.equals(afterURL)) {
                LOG.warn("wait前と後でページが切り替わっているため、waitを継続します");
                // URLが違う場合、切り替わっていないため、もう一度実行する。
                untilLoad();
            } else {
                throw new TestRuntimeException(ex);
            }
        }
    } catch (InterruptedException e) {
            throw new TestRuntimeException(e);
    }
}

このようにダミーのDOMを追加して、その状態を見て読み込み状態を判別するようになっています。

簡単に使えますのでぜひ試してみてください。

PtlWebDriverWait


Enterprise HTML5 Developers Meetup #2 が開催されました!

$
0
0

12月01日、Enterprise HTML5 Developers Meetup #2が21cafe@渋谷にて開催されました。多くの開発者の方にご参加いただき、盛り上がりました。

今回は全部で3つのセッションがありました。

Edison/Node.js/MQTT/BaaSによるIoTの始め方

MOONGIFT 中津川さん

私がSeleniumを使ってスクリーンショットを撮るまでに出会った闇の全て

新日鉄住金ソリューションズ 石川さん

Onsen UI 2.0とUIライブラリの未来

アシアル株式会社 久保田さん


また、LTでは飛び入りを含めてお二方がお話されました。

会場としてお借りした21Cafeの管理人の方もレポートを書いてくださっています。

次回は2016年の頭に行う予定です。ぜひご参加ください!


開発者ツールを巡る旅(その1)「Google Chrome DevTools」

$
0
0

フロントエンド開発において欠かせない存在になっているのがWebブラウザに付随する開発者ツールです。Google Chrome、Firefox、Safari、IEと各ブラウザに実装されていますが、その使い勝手や機能は細かく違っています。

そこで各ブラウザにおける操作性や機能の違いを掘り下げて紹介します。最初になる今回は最も利用者が多いと思われるGoogle Chromeです。

Google Chromeにおける開発者用ツール「DevTools」

Google Chromeやその元になるChromiumではDeveloper ToolsまたはDevToolsと呼ばれています。F12を押すと呼び出されます。

多機能かつ使いやすさとしては逸品ではないでしょうか。

機能はタブに分かれており、

  • Elements
  • Network
  • Sources
  • Profiles
  • Resources
  • Audits
  • Console

に分かれています。まず各タブの機能を紹介します。

HTML、スタイルシートを確認できるElements

ElementsタブではHTMLソースの確認やスタイルシートの状態を確認できます。ソースは単にサーバから受け取ったものではなく、その後のJavaScriptによる操作も反映した状態が確認できます。

さらにHTMLを編集したり、要素のCSSパスやXPathでコピーもできます。これを使うことでJavaScriptから操作するDOMの指定が簡単に分かるようになります。

スタイルの設定はどのスタイルシートファイルなのか一目で分かりますし、設定が適用されているかどうかも分かります。適用されていない(そもそもサポートされていない、または上書きされている)場合は打ち消し線が表示されているのですぐに分かります。また、スタイルの設定を追加、編集、外す(チェックボックスを外す)指定も行えます。

HTMLも変更できます。

ただしHTMLの変更やスタイルシートの編集やあくまでもWebブラウザ上だけのものになりますので実際のファイルへは反映されません。再読込すると元に戻ってしまうのでご注意ください。

他にもイベントリスナーの一覧を確認することもできます。ただしこれは実際にaddEventListnerを設定したメソッドが呼ばれるので、jQueryなどのラッピングしてくれるライブラリを使っている場合は処理を追いかけるのは難しいかも知れません。

リソースの読み込み状態を確認できるNetwork

NetworkタブではWebサイトを表示するのに使われている各リソースのダウンロード時間を確認することができます。Webページの表示に時間がかかっている場合、ここでチェックすることで全体の表示にかかっている時間を確認することができます。

JavaScriptのダウンロードにかかる時間であったり、さらにそこから動的に読み込まれるスクリプト群の時間、各種画像など計測してみるとどれくらい時間がかかっているのか一目で分かるようになります。

さらにタイミングごとのスクリーンショットを撮ってくれる機能があります。これを見るとWebサイトの読み込みが完了するまでの表示(大抵崩れていたりするものです)を確認できます。

ネットワーク速度を変える機能があります。一番遅い場合で50KB/sまで落とすことができます。モバイルでの表示速度を確認したり、オフライン時の表示を確認するのに便利です。

ネットワークはプロファイルが多数登録されています。これは自作可能です。

各種リソースの確認ができるSources

Sourcesタブではページを表示する際に読み込んでいる各種コンテンツをツリービューで確認できます。HTML/JavaScript/CSSファイルの他、画像やWeb Fontなども確認できます。HTMLやJavaScriptファイルに対してブレークポイントを差し込むこともできます。これはデバッグではよく使われる機能ですね。

実際にブレークポイントに来た時は行がハイライト表示されます。

マウスオーバーでその値を確認できます。

ウォッチも用意されていますので逐次変化していく値を追いかけることもできます。JavaScriptは変数がすぐにグローバルになってしまうのでウォッチが役立つでしょう。

スタイルシートの内容確認もできます。

Sourcesの中にはスニペット機能もあります。ここによく使う開発用便利スクリプトを残しておくと使い回しができて便利です。

処理にかかっている時間を細かく確認できるTimeline

Timelineタブでは各種処理時間をレコーディングしてグラフ化します。

主にローディング、スクリプト、レンダリング、描画、その他となっています。メモリに関する測定もできます。

CPU/メモリの解析ができるProfiles

ProfilesタブではCPUやメモリのプロファイルができます。

全体の処理について、どこで遅延が発生しているか、メモリが使われているかなどを測定するのに役立ちます。ハイパフォーマンスを求める場合は必須の機能でしょう。

ストレージ、Cookiesの状態が分かるResources

かつてはCookieくらいだったのが、HTML5になって多くのデータがWebブラウザ内部に蓄積できるようになっています。それが可視化されるのがResourcesタブです。

Web SQL、IndexedDB、LocalStorage、Session Storage、Cookies、Application Cache、Cache Storageについてデータを一覧で確認できます。

Webサイトの高速化に関するレポートを出力するAudit

Webサイトにおける改善ポイントを指摘くれるのがAuditタブです。外部JavaScriptファイルに関する指摘や、ブラウザキャッシュ、スタイルシートやJavaScriptの並び順最適化など多くの項目に関してレポーティングします。

開発の基本ともいえるConsole

ConsoleタブはWebアプリケーション開発における基本とも言えるタブです。制限されている変数に対する補完も行われるので効率的なデバッグができます。

関数の中身も確認できます。ただしここからブレークポイントを仕込むことはできません。

その他の機能

その他の機能として、スマートフォンやタブレットの画面サイズをエミュレートする機能があります。

デバイス名を選ぶだけでサイズを設定してくれるのが便利です。

設定ではレンダリングにおける指定ができます。FPS表示はWebゲーム開発で役立つでしょう。

検索機能も便利で、HTML/JavaScript/CSSファイルを縦断的に検索してくれます。正規表現も使えます。

USBをつないで外部デバイスのデバッグにDevToolsを使うこともできます。

各種プラグインによる拡張もサポート

DevToolsはプラグインで拡張ができます。例えばPHPのデバッグメッセージをChromeで受けられるPHP Console、Ruby on RailsであればRailsPanel、Django向けにはDjango Debug Panel、React向けのReact Developer Toolsなどがあります。こうした機能拡張を組み合わせることでより効率的な開発体制ができるはずです。

Google ChromeのDevToolsはHTML5フロントエンド開発において充実した機能を備えています。ぜひ多くの機能を使いこなして安全かつ高速なWebアプリケーションを開発してください。


Viewing all 274 articles
Browse latest View live