React.js meetup #1 に参加しました

React.js meetup #1に行ってきたのでそのメモ

発表

@naoya_ito 「React 概論」

  • 資料
  • Reactの記事を最新号のWeb+DB Pressに書いた
  • Model が変わったら View を全部書き直す => 宣言的に書けるからサーバ脳でフロントエンド実装ができる
  • 生産性より信頼性。コードを書く時間より読む時間の方が長い by Facebook
  • コンポーネント指向で、コンポーネントに関する処理を局所化できる

@hokaccha「react-rails

  • 資料
  • React を Rails のサーバサイドでレンダリングするためのもの
    • JSX の Asset Pipeline もついているが重要なのはサーバサイドレンダリング
  • react-rails は React の公式だった & 1.0.0 がリリースされた
  • がっつり動く SPA には向かないと思う。部分的に動的コンテンツがあるようなサイトに向いてる

@azu「10分で実装するFlux」

  • 資料
  • Flux 理解するには自分で実装してみるのが一番はやいよね!という話
  • 本当にデータフローが1方向になっているかはスタックトレースで確認していた

@yosuke_furukawa「mercury/mithril.js」

  • 資料
  • DeNA の古川さん
  • 一般にReactより早い mercury/mithril.js がどうやって高速化しているのかという話
  • 何か技術選択をする時に、同分野の他の技術がどうやって差別化しているか・課題解決をしているのかまで踏み込めるのは大切だと実感

@mizchi「React/SPAの設計と運用」

  • 資料
  • React/Flux で SPA を作った話
  • いろいろ問題があるので、結局スクラッチで数々のライブラリ開発した
  • 具体的で面白い話だった

(LT) @sugyan「React.jsと、Railsとかアイドルとか」

  • 資料
  • blog
  • 全然使ったことない Rails と React 使って趣味のアイドル情報サイト作ったよという話

(LT) @making「Java+React.jsでSever Side Rendering」

(LT) @tsuyoshi higuchi「React.js(React Native) + UI Design Prototyping」

  • 資料
  • GunosyのUIデザイナさん
  • React使ったUIプロトタイピング
  • 既存のプロトタイピングツールは画像ベースなのでレイヤとか意識されてなくてあまり使えない
  • フォトショのPSDファイルから、レイヤ情報を抜き出してReactのComponent出力するツールを作った
    • もうすぐ公開するらしい
    • この人本当にUIデザイナなんか、と会場がすごく盛り上がっていた

その他

  • togetterまとめ
  • いろんな人のトークで「神資料」として引用されまくっていた @hokaccha さんのIntroduction To React
  • React.js 触ったことがなかったので前日にチュートリアルHello Worldだけやって(+qiitaに晒して)から行ったら、Meetupのトーク内容がわりと飲み込めた
    • 普段触っていない技術だからこそ、ほんのすこしでも勉強会の予習をすると結構効果あるなーと思った

クロスブラウザテストのクラウド実行環境 Sauce Labs について

この記事は、Selenium/Appium Advent Calendar 2014 の21日目の記事です。 前回は18日目、akasakas さんの SeleniumWebdriver で Jenkins から Firefox 多重起動時 の 「e is null」エラー対処法 でした。

はじめに

今回は Seleniumクロスブラウザテストをクラウド上で実行できるサービス、Sauce Labs ネタです。

  • Sauce Labs の紹介
  • 実際に Sauce Labs を使ってみた様子

について書いてみようと思います。

この記事では、以下の環境を利用しています。

  • Ruby 2.1.5
  • Gem パッケージ

Sauce Labs とは

Sauce Labs (https://saucelabs.com/) とは、OS/ブラウザ横断の自動テスト実行環境をクラウド上に提供しているサービスです。非常に豊富な OS/ブラウザ が利用可能となっており、それらを自前で準備・メンテするコストが不要になることが大きな特徴です。 Sauce Labs は Selenium の実行環境の他に

の実行環境も提供していますが、今回は割愛します。

利用できる OS/ブラウザ

この記事の執筆時点では、465もの OS/ブラウザ (+デバイス)を利用することができます。詳しくは 公式の Platform リスト にありますが、

といったバリエーションが用意されており、一般的なOS/ブラウザの組み合わせはほぼ網羅できています。

テストレポート

Sauce Labs 上で実行したテストは、その結果も確認できるようになっています。

といった情報が記録されています。これらのレポートを出力する処理を実装しないで済むので、非常に便利です。特にスクリーンキャスト(動画)は、テスト実行の様子がそのまま録画されているので、テストが落ちた際のシューティングに役立ちます。

また、複数アカウントのチームマネジメントにも対応しているため、アカウントによってテスト結果を見せる・見せないといった制御も可能になっています。

Firewall 内のサーバにもアクセスできる Sauce Connect

実際に Selenium のテストを実行したい対象のアプリは社内ネットワーク内からのみアクセスできる開発環境などに置いてあることが多いと思いますが、そういった環境にも Sauce Labs のサーバからアクセスできるようにするのが Sauce Connect です。

f:id:deme0607:20141221132703p:plain

Sauce Connect のイメージ図 (公式ドキュメントから引用)

テスト対象のサーバにアクセスできるマシンと Sauce Labs との間にトンネルを張ることで、外部ネットワークからのアクセスを遮断しているサーバに対しても Sauce Labs のテストを実行できるようになります。

Sauce Labs 上で Selenium のテストを動かす

ここでは実際に Sauce Labs を使って Selenium のブラウザテストを動かす様子を簡単にご紹介します。 Ruby + selenium-webdriver を使ってテストを実行するには、大きく分けて2つの方法があります。

  • Sauce Labs の Selenium Grid を直接利用する方法
    • 細かいカスタマイズが可能
    • 実装コストが多少大きい(特に並列実行周り)
  • Sauce Gem を利用する方法
    • Sauce Labs がリリースしている Sauce Gem を利用する
    • WebDriver, capybara や paralles-tests のラッパーとなっていて、既存のテストを簡単に Sauce Labs の並列テストに対応できる
    • WebDriver や Capybara をカスタマイズして利用しているような場合には導入が難しい

Sauce Labs の Selenium Grid を直接利用する方法

要は Sauce Labs とは Selenium Grid を提供しているサービスなので、 適切な Capability を指定して WebDriver の向き先を Souce Labs の Hub にしてやれば、既存のテストの実行環境を Sauce Labs に移すことができます。

Sauce Labs の Selenium Hub の URL http://ondemand.saucelabs.com:80/wd/hub に Sauce Labs のアカウント作成時に発行されるユーザ名と API KEY をつけて指定すれば OK です。

例えば、RSpec を利用しているようなケースでは

require 'selenium-webdriver'

RSpec.configure do |config|

    config.before(:each) do
        caps = Selenium::WebDriver::Remote::Capabilities.firefox
        caps.version = "34"
        caps.platform = "OS X 10.10"
        caps[:name] = self.example.metadata[:full_description]
        # caps[:name]: Sauce Labs 上で結果を確認する際のジョブ名

        @driver = Selenium::WebDriver.for(:remote,
            url: "http://SAUCE_USERNAME:SAUCE_API_KEY@ondemand.saucelabs.com:80/wd/hub",
            desired_capabilities: caps
        )
    end

    config.after(:each) do
        @driver.quit
    end

end

とすれば OS X 10.10 (Yosemite) 上で動作する Firefox34 の driver を取得することができます。

もちろん、Firefox の Profile も指定することができます。Capability を設定する際に Firefox の extension(firebug) の有効化と UA の指定をする処理はこのように書けます。

profile = ::Selenium::WebDriver::Firefox::Profile.new

profile.add_extension "../path/to/firebug.xpi"
profile["general.useragent.override"] = "Customized UserAgent" 

caps = Selenium::WebDriver::Remote::Capabilities.firefox(firefox_profile: profile)
caps.version = ...

また、Sauce Labs はジョブごとに指定した OS/ブラウザ の VM を起動するオーバヘッドがあるので、WebDriver を呼び出す際にタイムアウトを起こすことがあります。そういった場合には、一時的にタイムアウトを長めに設定しておくことでエラーを防ぐことができます。

http_client = ::Selenium::WebDriver::Remote::Http::Persistent.new
http_client.timeout = 300 # タイムアウトを長く設定

caps = Selenium::WebDriver::Remote::Capabilities.firefox
# Capability を設定

@driver = ::Selenium::WebDriver.for(:remote,
    url: "http://SAUCE_USERNAME:SAUCE_API_KEY@ondemand.saucelabs.com:80/wd/hub",
    desired_capabilities: caps,
    http_client: http_client,
)

http_client.timeout = 90 # 延長していたタイムアウトは元に戻しておく

Sauce Gem を利用する方法

公式のチュートリアルに記載されている方法はこちらの Sauce Gem を利用するパターンです。

この Gem パッケージぱ WebDriver, capybara や paralles-tests のラッパーとなっていて、既存のテストを比較的少ない変更で Sauce Labs のクロスブラウザ・並列実行テストに対応させることができます。

Gemfile に sauce を追加し、

rake sauce:install:spec

を実行すると Sauce Labs の設定を記述する sauce_helper.rb の生成と、spec_helper の修正が行われます。 あとは sauce_helper.rb で Capybara の driver と Sauce Labs の設定を記述すれば、:sauce = true タグのついたテストケースが Sauce Labs 上で実行されるようになります。

require "sauce"
require "sauce/capybara"
require "capybara/rspec"

Capybara.default_driver = :sauce

Sauce.config do |c|
  c[:browsers] = [
    ["Windows 8", "Internet Explorer", "10"],
    ["Windows 7", "Firefox", "20"],
    ["OS X 10.8", "Safari", "6"],
    ["Linux", "Chrome", nil]
  ]
end

sauce_helper の設定と、テストケースへの :sauce タグ付けが完了したら、Sauce Labs のユーザ名・アクセスキーを環境変数で渡して rake sauce:spec コマンドでテストが実行されます。

SAUCE_USERNAME=xxx SAUCE_ACCESS_KEY=xxx rake sauce:spec

sauce_helperc[:browsers] で指定した各 OS, ブラウザに対してのテストが paralles_tests を利用して並列に実行されます。 DB を利用するテストなど並列実行時にテスト間で副作用が発生してしまう場合は、paralles_tests と同じく ENV['TEST_ENV_NUMBER'] を使ってコンフリクトを避けるようにしておきます。

通常の paralles_tests はテストをファイルごとに分割して並列実行しますが、Sauce Gem ではパッチが当てられていてテストケースごとの分割で並列実行されます。テストの構造によっては、その点は注意が必要かもしれません。

まとめ

今回は最近実験的に触っている Sauce Labs について書いてみました。触ってみた感想としては、数多くのパターン・ノード数のブラウザテスト実行環境がメンテ不要・手軽に利用でき、その結果が記録されることはやはり素晴らしいです。

しかしテスト実行に毎回 VM の起動が伴う点、Sauce Labs のサーバが米国にある点から、ブラウザの起動やブラウザ <=> テスト対象サーバへのアクセスのオーバヘッドは手元のマシンや国内サーバでのテスト実行に比べると大きくなります。従って、テストの並列数が小さかったり、テストの実行時間そのものが長くないような場合には Sauce Labs のメリットは小さくなってしまいます。大量のOS/ブラウザでテストを実施したい場合・長時間かかるテストケースを並列実行してテスト実行時間を短縮したい場合などは、これだけの環境を自前の Selenium Grid で準備・メンテしていくコストを考えると非常に有効な選択肢になると思います。

Sauce Labs は 14日間 or 自動テスト80時間 の無料トライアルも用意されているので、興味のあるかたは是非こちらからサインアップして触ってみてください。 まだまだ実運用に向けたような情報は不足しているので、皆さまの Sauce Labs 情報発信を楽しみにしています!

Selenium/Appium Advent Calendar 2014、次の記事は machさん です。よろしくお願いします!

YAPC::Asia Tokyo 2014 に 参加しました & 発表しました #yapcasia

もう1ヶ月前になりますが、YAPC::Asia Tokyo 2014に参加してきました。 YAPCには去年から参加していますが、今年は思い切ってトークの登壇に応募してみたら採択されたので JSON Shema と API テストというテーマで発表もさせていただきました。

トーク発表「JSON Shema と API テスト」

JSON Schema と API テスト YAPC::Asia Tokyo 2014

トーク概要

業務では JSON Schema で仕様が記述された API結合テストを書くことが多いのですが、その JSON Shema を使ってテストを楽にできないか?ということで

についてお話しました。

頂いた質問

JSON Shema で仕様を記述すること自体の普及活動も行なっているのか?

私の周りでは API の仕様を JSON Shema で記述し、サーバサイドのバリデータとして活用することが既に普及していたので、その必要はありませんでした。 JSON Schema を使っていない環境で1から導入・普及させることを考えると、JSON Schema は XML Schema 等に比べるとシンプルに記述できますが、はやり書くには一定の慣れ・スキルが必要なのは事実です。

  • JSON Schema を簡単に・正確に記述するための仕組みを作る
  • JSON Schema を書くと嬉しいこと」を増やす

このあたりが達成されるようになると、JSON Schema の普及は更に進むであろうと思います。 JSON Schema を入力とするバリデータの json-schema や、今回作ったテスト入力データの自動生成ツールである json-fuzz-generator は後者のアプローチですね。

json-fuzz-generator は Hyper Schema には対応しているのか?

対応していませんorz

後述の通り今回はかなりカツカツのスケジュールで作ったものなので、その余裕がありませんでした。 しかし実用的な JSON Schema は Hyper Schema を駆使することになるので、json-fuzz-generator でも今後対応させようと思っています。

発表してみて

実は今回が社会人になって初の対外プレゼンだったのですが、めちゃくちゃ大変でした。。。

7月にトーク登壇の申し込みをした時点では今回のトーク内容の構想はあったものの、スライドはおろか json-fuzz-generator も全くの未実装の状態でしたので、完全に LT 駆動開発の状態でした。 そんな中、何とか業務外の時間を捻出してコードを書いたりスライドの準備をし、何とか発表の形にもっていくことができたのは「脱・職業エンジニア」を目指している自分にとって大きな自信になりました。(発表の構想やプレゼンのレビューにご協力いただいた @ikasam_a さん、@shyouhei さん、@okitan さん、ありがとうございました!m(__)m)

とは言え突貫工事で作ったライブラリは実用レベルには全く到達していませんし、YAPC の他のスピーカーの方々の発表内容やプレゼン・スライドの完成度には圧倒されっぱなしであったので、

  • 普段から自信をもって LT で話せるようなネタ作り(=開発)をやる
    • YAPC前1ヶ月間のような生活を普段からできるようになりたい
  • プレゼンのスキルもちゃんと磨く
  • json-fuzz-generator を実用レベルにもっていく
    • このままでは出しっぱなしで終わってしまうので、追加で開発を続けます
    • 今は人に見せるの恥ずかしいような状態なので…

このあたりをこの先1年間ぐらいの目標にして生きていこうと思います。

YAPC 参加レポート

普段は Perl をメインで使っているわけではないので、言語に依存しないようなテーマのトークを中心に聞いてきました。 その中で個人的に印象深かったトークが以下の2つです。

Git を使ったツール開発

Speaker: @motemen さん

Git を便利に使うツールと、そういった Git ツールを作るにあたっての tips のご紹介でした。

Git 便利ツール: git-pr-release

開発ブランチにリリースする機能の Pull Request を merge しておいて、git-pr-release を実行するとリリースする機能のリスト付きリリース Pull Request を自動生成してくれるというもの。 リリースブランチを使うような開発・リリース方針をとっている人/チームにとって非常に便利なツールですね。

これを使えばリリースブランチに意図しないブランチが混じっていてリリース後に気付いて…というトラブルは防げそうです。

Git ツールの作り方

motemen さんが作った Git ツールの共通点は

  • .git/** 以下を直接いじるような操作はしない
  • libgit2 を使うのではなく、Git のサブコマンドを使う

の2点だそうです。 git help -a を叩くと Git のサブコマンドの一覧を全て見ることができます。 手元でも実行してみたところ、160以上のサブコマンドがありました。普段使っているのはその1割程度ので、便利ツール作成以前にこれらのコマンドの働きを把握するだけでも Git ライフが効率化できそうです…!

git --exec-path コマンドで得られる場所にある Git のサブコマンドを見てみると、実行ビットが立っていないものが多々あります。 この実行ビットが立っていない Git サブコマンド達は、シェルスクリプトから実行するための、つまり便利ツールに活用するためのコマンドだということを今回初めて知りました。

Git はチームで開発するにあたって他人に迷惑がかからない程度に使い方を知っている、という完全にペーペー状態なので、今回伺ったお話を活用して社内外で便利な Git ツールを作ってみたいと思います。

コマンドラインツールについて語るときに僕の語ること

Speaker: Taichi Nakashima さん

上記と同様 CLI ツール関係のお話ですが、こちらはもう少しジェネラルな、「イケてる CLI ツールの作り方」的なお話でした。

CLI ツールって普段から利用する機会は非常に多いのですが、いざ自分で作るとなるとお作法が全くわからない状態だったので、とても勉強になりました。 詳しくはこちらのスライドを見ていただくと良いのですが、中でもしっかり心に留めておきたいトピックについてメモしておます。

"良い" CLI ツールとは?

  • 1つの CLI ツールは、1つのことに集中している
    • UNIX のコマンド群と同じ考え方ですね。ついつい欲張っていろんな機能を盛り込んだものを作ってしまいそうになりますが、2つ以上のことをやろうとすると途端に複雑度が増してしまいます。
  • 直感的に使える
    • CLI ツールにも UI/UX が存在し、そのパターンにも慣習があるので、それに則って作ることが大切
  • 他のツールと連携できる
    • 上記「1つの CLI ツールは、1つのことに集中している」に通じている部分ですね。2つ以上のことをやるために、1つのことを上手くやるツール同士を連携させるのです。
    • exit code の出し分けや、output stream の使い分けをサボるとこういう部分で泣くことになりますね。

いかに"良い" CLI ツールを作り始めるか

こちらのトピックで最も印象的だったのが、「README.md から書き始める」ということでした。(README Driven Development と言うらしいです) その理由としては、

  • 何が作りたいのか整理できる
  • ユーザ視点でデザインできる
  • 1番テンションが高いときにドキュメントが書ける

といったことが挙げられます。 これらは CLI ツールに限った話でもないので、私も YAPC の翌日からさっそく意識して README Driven Development を導入しています。

また、 README に記述する内容の例として、「CI バッジをつける」というのも印象的でした。 テスト結果をユーザに見せ続けることで、テストを書くモチベーションを保ち続けることができる、という理由です。 テストを書くことがメインの業務に携わりながら[自分が公開したライブラリ[(https://rubygems.org/gems/randexp-multibyte)にはテストが入っていなかったり、といった笑えない状態なので、しっかり見習わなくてはなりません。。。

以上、しれっと書いてしまいましたが実は初ポストの deme0607 でした。