$.ajaxファイルアップロードでの進捗表示
こんにちは。フロントエンドエンジニアの本間です。
今日は$.ajaxファイルアップロードでプログレスバー表示についてです。
UIUXにおいて体感速度を短縮するのは重要で、同じ待ち時間でも進捗表示することによって体感速度が向上します。
さらにプログレスバーの色や模様によっても体感速度が変わってくるという研究結果もでているようです。
PRTIMESでは企業管理画面のリリース配信登録画面でワードファイルをアップする際に使っています。
やり方は$.ajaxの引数にxhrオブジェクトを渡し、progressイベントハンドラで取得します。
$.ajax({ url : api.url, async: true, xhr : function(){ var XHR = $.ajaxSettings.xhr(); if(XHR.upload){ XHR.upload.addEventListener('progress',function(e){ var progre = parseInt(e.loaded/e.total*100); $hoge.css({width: progre+'%'}); }, false); } return XHR; }, })
簡単ですね。
8行目e.totalがトータルサイズでe.loadedがアップし終わったファイルサイズです。それをパーセントに直して次の行で$hogeの横幅に代入してます。
プログレスバーは必要な時に表示してアップロード後に、消すといった使い方がほとんどだと思いますので、 表示切り替えはbeforeSendとcompleteを使うといいと思います。
生のjavascriptの場合は下記
var req = new XMLHttpRequest(); req.addEventListener('progress', updateProgress, false); req.open(); function updateProgress(e) { var progre = parseInt(e.loaded/e.total*100); document.getElementById(hoge).style.width=progre+'%'; }
非同期前提なのでasyncがfalseだと取得できません。
ですので古いブラウザ対応などでよくやる空のiframeからsubmitしてレスポンスを親に渡すやり方でも取得できませんのでご注意!
ちなみにprogressイベントのブラウザ対応状況は下記です。
PC
Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|
7以上 | 3.5以上 | 10以上 | 12以上 | 対応 |
mobile
Android | Android Webview | Firefox Mobile | Safari Mobile | IE Mobile |
---|---|---|---|---|
対応 | 対応 | 1.0以上 | 対応 | 10.0以上 |
今回はファイルアップロードでそこまで長くない時間でしたが、時間のかかる処理をする際に楽しげなアニメーションGifを動かしたり、広告スペースに活用したりと工夫してあるサイトも多いですね。
体感時間について下記の記事が面白かったのでご紹介致します。
第46回 体感時間のコントロール | WIRED VISION
待っているという事実を一瞬忘れさせるのが体感時間短縮の鍵ですね。
最後まで読んでいただきありがとうございます。
PR TIMESは東証マザーズに上場しました!
PR TIMESフロントエンジニアの山田です。
※この記事はエイプリルフールではありません!
昨日、3月31日にPR TIMESは東証マザーズに上場しました。
prtimes.co.jp
なかなか体験することができないセレモニーにも参加することができ、感慨深い想いです。
エンジニアも含め参加した社員も、静かに見守る、その場を楽しむ、興奮して写真を撮りまくるなど様々な反応でしたが、サービスをご利用頂いている方々に感謝し、そしてサービスをより良くしていこうという想いは皆変わらないと思います。
prtimes.jp
そんなPR TIMESのエンジニアチームでは一緒にサービスを発展させて頂ける仲間を募集しています。興味を持たれた方は以下のフォームからご応募ください。
オフィス訪問も受け付けていますので、お気軽にどうぞ。
VR導入-開発裏話
PR TIMESフロントエンジニアの山田です。
Oculus Riftの出荷が開始されたり、サムスンが発表会でGEAR VRを利用して話題になったり、VRが盛り上がってますね。
PR TIMESでも3/29の記者会見で発表させて頂いたように、配信されるプレスリリース内にVRが埋め込めるようになっています。
prtimes.jp
Flic360、ストリートビュー、YouTubeなど360度回転して見られるフォトや動画がご利用可能です。
シルク・ドゥ・ソレイユさんにも早速ご利用頂き、臨場感が伝わります。
prtimes.jp
埋め込みは簡単、VRのURLをフォーム内に入力し挿入ボタンを押すだけ。
表にはサラッとだしていますが、裏ではPR TIMESのエンジニアチーム一同が頑張りました。
最初の開発が始まったのが1月。オフィス移転のタイミングでPR TIMESのリリースを出すときに、ストリートビューでオフィス内を見せることができたらいいねという話から。移転までわずか数日というタイミングでした。
果たして間に合うのかという状況で手をつけ始めましたが、実際やってみるとなんとかなるもの。リリースを出すタイミングを少し遅らせて頂きましたが、無事インドアビューを埋め込んで配信することができました。
prtimes.jp
もちろん徹夜のデスマーチとかしてません!ちゃんと営業時間内の作業で終わらせました。技術力だけでなく、こういたところもPR TIMESエンジニア・チームの誇れるところ。
当初ストリートビューだけだった機能も、その後VR提携の話などもありFlic360を追加。YouTubeのVR動画にも対応。そして、これからも使える形式を増やしていく予定。
PR TIMESでは今後も時代に合わせた機能を追加していきますので、ご期待ください!
RedisのZSETを使った集計方法
PRTIMESエンジニアの吉です。 弊社ではNode.JSとRedisを使って一部の機能を実装しています。 今日はRedisをつかった集計方法ノウハウをみなさんと共有したく、簡単に紹介したいと思います。
なぜ集計にRedisを使うのか
最近のWebアプリケーションは様々なシーンにおいて大量のデータをサーバーに送ってきます。 特にユーザーのアクセス情報や行動ログ、内部セッションデータの保存などデータ間の関係性が低い情報に関してはNoSQLに保存するのが望ましいと思います。
ここで登場するのがRedisです。 Redisはデータをメモリ上に保持するので非常に高速な処理が可能です。 また、list, set, zset, hashといったデータ構造を持っていて効果的にデータを保存できる点からデータの集計に向いていると考えているからです。
以下、Redisのzsetを使って期間別のデータを絞り込んでScoreを合算する方法の一部をまとめました。
データ保存時のzset構成
Index用データzset
ここで登録するデータは期間別に登録された情報を絞り込むためのIndexの役割をします。 タインプスタンプがscore、実データkey名がvalueとなります。 以下、redisの登録コマンドです。
ZADD data:index 1458010816 data:1
集計対象データzset
ここで登録するデータは実データ、集計対象となるデータです。 集計したい値がscore、項目名がvalueとなります。以下、redisの登録コマンドです。
ZADD data:1 10 value_1 20 value_2 30 value_3 ...
集計
集計対象データのkey名を取得
まずはindex用zsetデータから期間を絞り込んで集計対象となるデータのkey nameを抽出します。 以下、redisの抽出コマンドです。
ZRANGEBYSCORE data:index 1458010816 1458010816
結果作成
取得したkey名をもとに集計を実施します。zunionstoreを実行すると新たなdata:sumというzsetが生成されます。 data:sumにはzunionstoreで指定したzsetの合算値が入ります。 以下、redis集計コマンドです。
ZUNIONSTORE data:sum 4 data:2 data:3 data:5 data:6
感想
今回のブログではredisのzsetを使った集計の一例を紹介しました。 みなさんご存知のとおり、簡単にデータの保存ができて高速に処理が行われることにすごく感銘を受けています。 集計以外でもRedisは様々な使い道がありますので積極的にredisを使いブログを通じて紹介したいと思います。
CentOS6.7にNginx+PHP5.6+MySQLの環境を作ってWordpressの引っ越しをする
PRTIMESエンジニアの深川です。
リファクタリングの季節、春ですね。PRTIMESでもサーバのリファクタリングということで社内で運用しているサイトの棚卸しの実施中。 利用状況や現状の構成をレビューして、必要があればサーバの移行を進めています。
中でも、 * Wordpressで運用しているサイト * PHP&Apache&MySQLの構成 * チューニング次第でサーバリソースの要求水準は高くない
このようなサイトは複数あるので、今回移行にあわせて、PHPのバージョンを5.6にしつつ、 WEBサーバをApacheからNginxに切替えています。
今回はその辺りの手順を公開してみます。
本来ならプロビジョニングツールで一括!となりますが、 自動化の前に手続きを確認ということで、今回はコマンドベースでの手順の公開です。
クラウドコンピューティングのイラスト | 無料イラスト かわいいフリー素材集 いらすとや
■移行における作業項目の今回の対象範囲
WordPressで運用しているサイトの移行となると、必要そうな手順をざっくり書いてみます。
- サーバの確保
- 移行先検討
- 契約
- サーバ構築
- アカウントの作成
- 運用ユーザ作成
- MySQLユーザ作成
- リソースの転送
- WordPressソース一式
- DBのデータ
- 動作テスト
- サイト
- 管理機能
- プラグイン周り
- ドメイン
- DNSレコード更新
- 旧サイト転送対応
で、今回の記事で対象にする部分はこちらです。
サーバの確保-
移行先検討 -
契約
-
- サーバ構築
アカウントの作成-
運用ユーザ作成*MySQLユーザ作成
-
- リソースの転送
- WordPressソース一式
- DBのデータ
動作テスト-
サイト -
管理機能 -
プラグイン周り
-
ドメイン-
DNSレコード更新 -
旧サイト転送対応
-
■サーバ構築
□PHPインストール
リポジトリの追加
PHP5.6をインストールするために、epelとremiのリポジトリを追加
% sudo rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm % sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
インストール
% sudo yum install --enablerepo=remi --enablerepo=remi-php56 php php-opcache php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof
PHP設定変更
phpの設定を変更。コメントアウトとしている部分は5.6では非推奨となる項目なので、該当する設定が適用されていたら、対象行をコメントアウト
% sudo vim /etc/php.ini
default_charset = "UTF-8" date.timezone = "Asia/Tokyo" [mbstring] mbstring.language = Japanese ;mbstring.internal_encoding = EUC-JP ;mbstring.http_input = auto ;mbstring.http_output = SJIS
□MySQLインストール
インストール
% sudo yum -y --enablerepo=remi install mysql-server
初期化スクリプトを実行
% sudo mysql_install_db --datadir=/var/lib/mysql --user=mysql
起動、自動起動設定
% sudo /etc/init.d/mysqld start
% sudo chkconfig mysqld on
セキュリティ設定スクリプトを実行(基本すべてYで)
% sudo mysql_secure_installation
□PHP-fpmインストール
インストール
% sudo yum install --enablerepo=remi --enablerepo=remi-php56 php-fpm
設定ファイル編集
% sudo vim /etc/php-fpm.d/www.conf
user = nginx group = nginx
起動、自動起動設定
% sudo service php-fpm start
% sudo chkconfig php-fpm on
□Nginxインストール
インストール
% sudo yum -y install nginx
設定ファイル(ファイル名は任意で)
% /etc/nginx/conf.d/wp.conf
server { listen 80; server_name wp.jp; # 取得したドメインを指定してください root /var/www/wp; index index.php; # 以下、パーマリンク対応 # URL デフォルトのリンクから変更した場合 location / { try_files $uri $uri/ @wordpress; } # index.php などの.phpでのアクセス location ~ \.php$ { try_files $uri @wordpress; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/wp$fastcgi_script_name; include fastcgi_params; } # 階層型URLのパーマリンクでアクセスされた場合 location @wordpress { fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/wp/index.php; include fastcgi_params; } }
% sudo nginx -t % sudo service nginx reload
■リソースの転送
□WordPressソース一式
(移行元サーバでの作業)wordpress一式が/var/www/wp/にある想定で、移行先サーバに転送します。
sudo rsync -av -e ssh /var/www/wp 移行先サーバユーザ名@移行先サーバホスト名:/var/www/isuta/
※ 今回は雑にまとめて転送していますが、ファイル容量次第では転送量と時間が大変なことになるので、 ソースはgitなどで管理している場合は、移行先サーバの該当ディレクトリに先にgit cloneしておくと良いかもれしません
□DBのデータ
(移行元サーバでの作業)MySQLバックアップ
mysqldump --single-transaction -u (wordpressデータベースユーザ名) -p (wordpressデータベース名) > wp_db.dmp
バックアップしたファイルを移行先サーバに転送後に(移行先サーバでの作業)MySQLリストア
mysql -u (wordpressデータベースユーザ名) -p (wordpressデータベース名) < wp_db.dmp
簡単となりますが、以上です。
似たような構成のサイトを複数あって、個々に手動で対応するのは面倒で手作業のミスも発生するので、 構築の作業と可能な範囲のリソース配置はAnsibleやChefによるプロビジョニング対応しておきたいところです。
UX DAYS TOKYO 2016 カンファレスレポート
こんにちは。PR TIMESデザイナーの新井です。
UXの重要性は年々高まってきていますが、自分たちのビジネスにどう活かすかを世界の第一線で活躍しているUXデザイナーたちから学べる機会はなかなかないので前年に引き続き、今年もUX Days Tokyoに参加してきました。今回、PR TIMESはゴールドスポンサーをさせていただきました。
2016.uxdaystokyo.com
内容の把握、理解が完全でない点もありますが、今回参加して自分なりに解釈したことをまとめました。
続きを読むphpstorm 便利機能
こんにちわ!エンジニアの花田です
今回は多くのエンジニアに使用されているIDE「phpstorm」についてお話したいと思います。
といってもphpstormとは何か?という話ではなく、phpstormの覚えておくと便利機能をまとめてみましたので作業効率化を図れる参考なれば!
補足でブログを訪れてくれた、これからエンジニアを目指す人にphpstormって何?を軽く書いておきます。
【phpstorm】
- コード補完が優秀でカユイところに手が届く
- 他のIDEに比べると軽い
- 有料
それではphpstormの便利機能を紹介します。
使用phpstorm
10.0.3
control + j
クラス・メソッドドキュメントを表示
良く使用してるクラス・メソッドは大体覚えていますが、たまに使う物に関しては思い出すヒントとして使用してはどうでしょうか
command + alt + t
選択した行を特定のタグで囲む
全体を【if】で囲むという時に・・・
選択した行を選択しcommand + alt + t
タグ入力になりますので、【if】(囲いこみたいタグ)を入力すればOK
command + shift + v
クリップボード履歴から文字を貼り付け
先ほどまで使用していた内容を貼り付けする時には便利です
右クリックから[ Compare Directories ]
クリップボードの内容とテキスト内の差分等を比較する
差分にかける基準となるエリアをコピー
差分したい場所にて右クリックから[ Compare Directories ]を選択
差分結果が表示されます
shift2度押し
phpstorm内の全てのプロジェクト・機能・設定等を検索
指定文字 + tab
Emmet html.css等入力の短縮を補助
上記のような【a】タグはaを入力したら+ tabで
<a href=""></a>と自動的に入力されます
Emmetを利用したリストの作り方
【ul】の中に【li】を10個設置して【a】タグを配置
ul>li*10>aと記載した後に+ tabをすると・・・
こんな感じに変換されます。
いかがでしたでしょうか?
上級者の方には知っている機能ばかりかもしれませんが、phpstormを使用されている人やこれから使用してみるユーザーの方は是非試してみてください。
グラフ生成ライブラリ C3.jsについて
こんにちは!フロントエンドエンジニアの本間です。
今回はグラフ生成ライブラリのC3.jsについてです。
C3.jsとはWebグラフィックスを扱うD3.jsを利用して、オプションのような形で簡易的にグラフを作る為だけに拡張されたライブラリです。
日本だと知名度がイマイチかもしれませんが、海外ではD3.jsの人気が高く注目度の高いライブラリです。
D3.jsのみでもグラフを作成できますが、慣れるまで扱いが難しいところもあり、C3.jsを使うことでより楽にグラフを作成できます。
ドキュメントも充実していて、オプションも豊富にあり、柔軟性も高いので自分なりのグラフをさっと作りたい時など大変便利です。
データの投入方法を工夫することで動きをつけることができ、見せ方もカスタマイズできます。
以前、BIツールで月間のデータを可視化する時に使用していたことがあり、当日以降のデータを予想値として半透明にして表示したり、アニメーションを加えたりとカスタマイズしていました。
では早速、使ってみましょう。
ライブラリを記述
<link href="/path/c3.css" rel="stylesheet" type="text/css"> <script src="/path/d3.v3.min.js" charset="utf-8"> <script src="/path/c3.min.js">
はい、これが無いと始まりません。ライブラリを読み込みます。
D3.jsベースなのでこれもお忘れなく。
html
<div id="chart"></div>
グラフが展開される要素を用意します。
var chart = c3.generate({ bindto: '#chart', data: { columns: [ ['data1', 30, 200, 100, 400, 150, 250], ['data2', 50, 20, 10, 40, 15, 25] ], axes: { data2: 'y2' } }, axis: { y: { label: { // ADD text: 'Y Label', position: 'outer-middle' } }, y2: { show: true, label: { // ADD text: 'Y2 Label', position: 'outer-middle' } } } });
上記のようなデータを読み込むと...
はい、グラフが出来ました。
データとグラフを見比べると、どこのデータがグラフ上でどう表示されるのかわかると思います。
データはCSV, JSON形式でも投入可能でURLで指定することもできます。
グラフタイプを下記のように指定すると異なるグラフが展開されます。
type: 'bar'
type : 'pie'
折れ線グラフと棒グラフは組み合わせて使うことが出来ます。
さらに動的にデータを変更してアップデートをかけるとアニメーションして表示が変わります。
サマリーとデイリーでグラフタイプを分けたり、項目をクリックして線がトランスフォームしてカッコよくアニメーションしながら詳細を表示するなんてこともできます。
データ可視化の意義や、データから行動を読み取るといったことを念頭に置いて、最適な表現できると良いですね。
他にもいろいろできますので公式ドキュメントをチェックしてみてください。
最後まで読んでいただきありがとうございました。
公式ドキュメント
c3js.org
try! Swift 2016 の感想 ☆*:.。.
PR TIMES エンジニアのうさみです。 3月2日から3月4日までの3日間、東京・渋谷にて try! Swift 2016 が開催されました!
今回、PR TIMESはシルバースポンサーとして参加させていただきました。技術的なことはもう少しSwiftの技術力がついた頃に触れるとして、イベントに参加して感じたことを少しだけ・・・
PR TIMES のロゴ、ありました!
イベント中はこちらのネックストラップを装着です☆
try! Swift が開催されたのが今回初ということもあり、ご存知でない方も多いかと思いますが、公式サイトでは以下のように紹介されています。
try! Swiftは世界中のSwiftデベロッパーが一堂に会し、知識や技術を互いに共有し高め合うことを目的としたカンファレンスです。
try! Swift (@tryswiftconf) | Twitter
カンファレンスには国内や海外の著名なエンジニアが33人招待され、3日間に渡って33のセッションが繰り広げられました。1セッション25分という講演の中には、技術本には載っていないような興味深いお話から技術的に高度なお話まで盛りだくさんで、私はイベント後半の半分程しか参加できませんでしたが、とてもお腹いっぱいになりました。すべて参加できていたら、きっとしばらく興奮をおさえることができなかったかもしれません。。
高度なお話では一瞬(?)となることもしばしばでしたが、25分という限られた時間の中でキーワードに対してざっと説明してくださっていたので、話がまったくわからなくなるということは無かったように思います。
ご提供いただいたスターバックスのコーヒーとパンをいただきながら休憩タイム
休憩中も講演者や参加者の間でSwift話が弾み会場は賑やかでした
セッションの内容については、後日、動画や資料を公開していただけるとのことですが、著名な方々や企業様のブログにてまとめ記事が既にいくつか投稿されています。(貴重な記事、ありがとうございます!)
→ 株式会社はてな様の@niwatakoさんがすべてのセッションを聞き起こしくださっています。す、すごい!途中からの参加でしたのでとても助かりました・・・ありがとうございます!
→ クラスメソッド株式会社様のエンジニアのみなさまによる最速レポートです。1日目午前から3日目午後までそれぞれまとめられています。セッションだけではなくイベントで提供いただいた朝食やランチのお写真もあります。(私はランチのお写真撮り忘れてしまいました・・・)ありがとうございます!
→ 世界的なiOSエンジニアである堤さんがイベント全体の感想をまとめられています。Swiftだけではなく、今回のように海外の方が集まる場でのコミュニケーションについてなどストレートに述べていらっしゃって、とても共感いたしました。Swiftだけではなく英語もがんばろう!という気持ちに・・・ありがとうございます!
→ セッションごとに上記の@niwatakoさんによる聞き起こしと合わせて、講演者様の発表資料やサンプルコード、レポートや関連記事等をさらに見やすくまとめていただいています。ありがとうございます!
今回のイベントについて主催者様としても「世界トップレベルのエンジニアがこれだけ集まるカンファレンスは海外と比較しても非常に稀」とのことですし、初のSwiftカンファレンスにして素晴らしいメンバーが集結され貴重な講演内容だったことと思います。
イベントが終了して日が経ち、少しずつイベント時の熱が冷めつつありますが、改めて今回のカンファレンスに参加できたことをうれしく思います!
2日目のスポンサーも参加可能なスピーカーディナー
たくさんのエンジニアの方とご挨拶させていただき、また刺激をいただきました
お料理もとてもおいしかったです
次回となるであろう「try! Swift 2017」の開催は今回の成功がかかっているとのことですが・・・
主催者様のイベントへの配慮も素晴らしく、国内や海外からたくさんの方々が集まり大盛況、イベント終了後の懇親会の盛り上がりもすごかったので、きっと次回も開催されるのではないでしょうか☆*:.。.(という期待でいっぱいです)
ぎりぎり私も写真に入れました!
前方の方々だけなので実際はもっとたくさんいらっしゃいます
try! Swift 2016 は、主催者、講演者、参加者のみなさまの「Swiftが好き」「みんなで盛り上げていこう」という思いを終始感じられるカンファレンスでした。今もなお、try! Swift の Slack への投稿は続いていますしね ( ´ - ` )
初のカンファレンスということで大変だったことと思いますが、素晴らしいイベントを開催してくださった主催者のみなさまに感謝いたします。ありがとうございました!
貴重なお話を聞いて満足して終わりにするのではなく、今後に活かしていきたいと思います。
try! Swift オリジナルTシャツや手提げ袋をいただきました☆
袋の中にはステッカー等がたくさん!
古いWebアプリケーションのブラウザテスト
エンジニアのアカイです。
今回はブラウザテストを行ってみます。
具体的には、Capybara/Poltergeistを使用して、無人テストを行います。
これらはRuby on Railsのテストのために作られている雰囲気がありますが、
他のアプリケーションでも使用できます。
条件は以下の通りです。
- 3画面構成のフォーム(入力・確認・完了)
- 入力は正常値のみ
- 自動的に完了画面まで動作させる
- サーバ上で実行
PhantomJS
$ wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 $ tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2 $ sudo mv phantomjs-2.1.1-linux-x86_64 /usr/local/ $ sudo ln -s /usr/local/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs $ sudo aptitude -y install libfontconfig
テストコード置き場
$ mkdir test $ cd test $ bundle init $ vi Gemfile $ bundle install --path=vendor/bundle
Gemfileの内容は以下のようにしました。
使わないものもありますが、あまり重要ではないのでそのままにしておきます。
# A sample Gemfile source "https://rubygems.org" # gem "rails" gem 'capybara' gem 'poltergeist' gem 'headless' gem 'rspec' gem 'activesupport' gem 'pry'
rspecを使用しますので、準備します。
$ bundle exec rspec --init
spec_helper.rbファイルを編集して、Capybara/Poltergeistを使用できるように設定します。
# coding: utf-8 require 'bundler' Bundler.require require 'capybara/rspec' require 'capybara/poltergeist' require 'headless' Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new( app, js_errors: false, inspector: true ) end Capybara.default_max_wait_time = 10 Capybara.default_driver = :poltergeist Capybara.javascript_driver = :poltergeist Capybara.run_server = false Capybara.app_host = 'http://172.17.1.111:4567' # テスト対象のホスト設定です RSpec.configure do |config| config.include Capybara::DSL config.before(:suite) do Headless.new(destroy_on_exit: true).start end end
テストは存在しませんが実行してみます。
$ bundle exec rspec No examples found. Finished in 0.00093 seconds (files took 0.34605 seconds to load) 0 examples, 0 failures test/vendor/bundle/ruby/2.2.0/gems/headless-2.2.2/lib/headless/cli_util.rb:9:in `ensure_application_exists!': Xvfb not found on your system (Headless::Exception) from test/vendor/bundle/ruby/2.2.0/gems/headless-2.2.2/lib/headless.rb:77:in `initialize' from test/spec/spec_helper.rb:26:in `new' from test/spec/spec_helper.rb:26:in `block (2 levels) in' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/example.rb:425:in `instance_exec' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/example.rb:425:in `instance_exec' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/hooks.rb:357:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `block in run_hooks_with' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `each' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `run_hooks_with' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1679:in `with_suite_hooks' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:118:in `block in run_specs' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/reporter.rb:77:in `report' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:117:in `run_specs' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:93:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:78:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:45:in `invoke' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/exe/rspec:4:in ` ' from test/vendor/bundle/ruby/2.2.0/bin/rspec:23:in `load' from test/vendor/bundle/ruby/2.2.0/bin/rspec:23:in ` ' $
xvfbがないといわれていますので、インストールします。
そういえば、フォントを入れていなかったので、念のため追加しておきます。
これは、スクリーンショットを撮る場合に、漢字ひらがななどを表示するためです。
$ sudo aptitude -y install xvfb fonts-ipafont
そしてもう一度実行します。
$ bundle exec rspec No examples found. Finished in 0.17762 seconds (files took 0.40034 seconds to load) 0 examples, 0 failures $
今度はエラーが発生せずに終了しました。
テストの記述
テストはspecディレクトリ以下に設置します。
rspecに関する説明は省略します。
それでは、早速テストを設置してみます。
フォームは3画面構成で、以下のようになっています。
path | タイトル | ボタン |
---|---|---|
/form | Registration Form | Confirm |
/confirm | Input Confirm | Regist |
/complete | Registration completed | - |
spec/form_spec.rb
# coding: utf-8 require 'spec_helper' describe 'アカウント登録' do before do visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end end
$ bundle exec rspec . Finished in 0.94537 seconds (files took 0.31413 seconds to load) 1 example, 0 failures $
次は、画面遷移を含めたテストを追加します。
# coding: utf-8 require 'spec_helper' describe 'アカウント登録' do before do visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end it 'フォームに入力して確認ボタンを押す', js: true do data = { account: "account-name-#{SecureRandom.hex(8)}", pwd: SecureRandom.hex(8) } data.each do |k, v| fill_in k, with: v end click_on 'Confirm' expect(page).to have_title 'Confirm' end end
$ bundle exec rspec .. Finished in 1.09 seconds (files took 0.32112 seconds to load) 2 examples, 0 failures $
最後に、登録完了までのテストを追加します。
# coding: utf-8 require 'spec_helper' @page = nil describe 'アカウント登録' do before do @data = { account: "account-name-#{SecureRandom.hex(8)}", pwd: SecureRandom.hex(8) } visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end it 'フォームに入力して確認ボタンを押す', js: true do @data.each do |k, v| fill_in k, with: v end click_on 'Confirm' expect(page).to have_title 'Input Confirm' end it 'フォーム入力から登録完了まで行う', js: true do @data.each do |k, v| fill_in k, with: v end click_on 'Confirm' click_on 'Regist' expect(page).to have_title 'Registration completed' end end
$ bundle exec rspec ... Finished in 1.34 seconds (files took 0.34232 seconds to load) 3 examples, 0 failures $
…リクエストパターンごとにitで分けると、pageの内容が空になってしまうようです。
いろいろ試してみましたが、最初から最後までを通して行うテストになってしまいました。
とりあえず目的は達成できましたので、今回はこれで完了とします。
この類のテストはルーチン的なものを自動的に行うことで、
時間を有効に使えるというのが大きいと思います。
ただ、動作があまり見えないこともあり、かなりハマりやすそうですので注意しましょう。