読者です 読者をやめる 読者になる 読者になる

クラウド上でSeleniumスクリプトを走らせることができる、SourceLabsをGebで試してみたよ

確かJenkinsの生みの親が語る、継続的インテグレーションの未来 − @ITで出てきたSauceLabsというのが気になったので、ちょっと試してみました。

ちなみに、クラウドと言ったらもちろんコレですよね。
http://pub.ne.jp/sakurabu/image/user/1208648202.jpg


概要

SauceLabsとは

Cross browser testing with Selenium - Sauce Labsは、クラウド上でSeleniumテストケースを実行することができるものです。自動でスクリーンショットやビデオを撮る機能があり、いわゆるSelenium 1はもちろんSelenium 2(WebDriver)も対応しています。200分/1ヶ月の無料枠やGithubアカウントでのログインもあり、チュートリアルも結構豊富なので、試すだけならすぐに試すことができます。

ちなみに、似たようなサービスとして"CloudTesting"というものもあります。残念ながらこちらはプログラマブルSelenium RCは対応してなく、Selenium IDEで出力されるHTML形式のテストケースしか実行できないようですが。

SauceLabsにはいくつかの機能が提供されています。

Sauce OnDemand
SauceLabs上のSelenium RC
Sauce Scout
手動でSauceLabs上のブラウザを操作できる機能
Sauce Builder
SauceLabsでの操作をサポートするFirefox plugin
Sauce Connect
イントラ内のWebサーバに対しても、SauceLabs上から参照できるようにする
Gebとは

通常のSelenium(WebDriver)を実行するだけではツマラナイので、今回はGebを使ってみます。Gebとは一言でいうと、Groovyを使ってJQuery風の要素指定ができるようにしたものです。"$('div')"といった形で、要素を指定できます。

Gebについての詳細は、JGGUGが発行しているG* Magagine Vol.1に導入編が載っているので、そちらも参照ください。

実践

今回作成したソースコードは、Github上に置いてます。

また、テスト結果はこちらのリンクに記録されています。スクリーンショットやビデオ、Seleniumの実行結果がこちらから参照できます。

前準備

ここでは、GebTestもしくはGetReportingTestを継承して、テストケースを作成する前提とします。

まず、SauceLabsのサーバを指定したDriverを作成します。createDriver()をオーバーライドして、username/accessKeyを指定したDriverを作ります。

final def USERNAME = 'XXXXXXXX'
final def ACCESS_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

@Override
WebDriver createDriver() {
	def dc = new DesiredCapabilities([
				browserName: 'firefox',
				version: '3.6.',
				platform: Platform.WINDOWS,

				username: USERNAME,
				accessKey: ACCESS_KEY,
				name: "Hello, Sauce OnDemand with Geb!",
	])

	new RemoteWebDriver(new URL('http://ondemand.saucelabs.com:80/wd/hub'), dc)
}

続いて、テストを実行した後に接続を切断するための処理を入れておきます。これをしておかないと(GebTestデフォルトのままだと)、SauceLabs側でテストが終了とみなされず、SauceLabsを利用出来る時間がどんどん消費されていくので、必ずやっておきましょう。

なお、@Afterアノテーションだとサブクラス側のメソッドが先に呼ばれてその後にスーパークラスの@afterメソッドが呼ばれるのですが、スーパークラス側ではすでに切断された状態で処理しようとするため、NullPointerExceptionが発生します。なので、ちょっとカッコ悪いですが、スーパークラスの@afterメソッドをオーバーライドして、先にスーパークラスの処理を行ってからdriver.quit()しています*1

@Override
void clearBrowserCookies() {
	super.clearBrowserCookies()

	browser.driver.quit()
}
テストコード作成

ここでは、BacklogというBTSで「ログイン -> ダッシュボード -> プロジェクト」に遷移するだけの簡単なGebテストを実行してみます。

@Test
void "ログインして1番目のプロジェクトの最新課題にコメントする"() {

	// ログインページ
	to LoginPage
	assert at(LoginPage)
	userId = 'demo'
	password = 'demo'
	submit.click()

	// ダッシュボードページ
	waitFor { at(DashboardPage) }
	firstProject.click()

	// プロジェクトページ
	waitFor { at(ProjectPage) }
}

これで、SauceLabs側でGeb(Selenium)が走ります。上記のリンクで示したところから、スクリーンショットやビデオ、Seleniumの実行結果がを参照できます。一応、リンクをも一度ぺたり。

感想

スクリプトの作りが悪いのかもしれないけど、ちょっと いやかなり重かったです。ほんとは、「課題にコメントする」というのも実装しているのですが、SauceLabs上でテストしても遅くて高々画面4,5遷移しかしないのに多分5分以上レスポンスが全然返ってきませんでした。ローカルで走らせたときはまだそこまで時間がかからなかった30秒ぐらいで終わったんですけどねー。特にそういうドキュメントは見当たりませんでしたが、有料だとこの辺緩和されるのかな?とかも思ったり。

(自分にとっては)すぐさま実用的なものとはならないと思いますが、SeleniumやGebの復習ができたのでよしとします。

*1:Spock+Gebだとこの手法が使えなかったので断念しました。GebSpecの@afterをオーバーライドしようとすると、Spock側で「そんなことやっちゃだめよ、Specificationのfixtureを使えよハゲ」と怒られるのです。