Your SlideShare is downloading. ×
Selenium webdriver使ってみようず
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Selenium webdriver使ってみようず

12,217
views

Published on

2012/04/07 わんくま大阪#48

2012/04/07 わんくま大阪#48

Published in: Technology, Business

0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
12,217
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
48
Comments
0
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. SeleniumWebDriver 使ってみようず 2012/04/07 お だ わんくま同盟 大阪勉強会 #48
  • 2. 自己紹介• 織田 信亮(おだ しんすけ)• 大阪で開発者しています• SQLWorld 代表 (http://sqlworld.org)• http://d.hatena.ne.jp/odashinsuke/• Twitter:@shinsukeoda わんくま同盟 大阪勉強会 #48
  • 3. ~基本~わんくま同盟 大阪勉強会 #48
  • 4. Selenium ってなに?• Web アプリケーション用のテストツール• ブラウザを使って Web アプリケーション の動作確認等を行う• ブラウザの操作を Selenium が行ってくれ る わんくま同盟 大阪勉強会 #48
  • 5. Selenium WebDriver ってなに?http://seleniumhq.org/docs/03_webdriver.html• Selenium が WebDriver と統合された• Selenium 1.0 だと JavaScript/HTML で記 述がメイン• WebDriver は、Selenium ではセキュリ ティで制限されていたものが回避出来る• Selenium 2.0 で統合! わんくま同盟 大阪勉強会 #48
  • 6. API が提供されている言語• Java• C#• Python• Ruby• PHP• Perl わんくま同盟 大阪勉強会 #48
  • 7. 提供されている WebDriver• HtmlUnit Driver• Firefox Driver• Internet Explorer Driver• Chrome Driver• Opera Driver• iPhone Driver• Android Driver 言語によっては、提供されていない Driver もあ る! わんくま同盟 大阪勉強会 #48
  • 8. API の基本• ドライバー – IWebDriver (WebDriver)• エレメント – IWebElement(WebElement)• ロケーター – By わんくま同盟 大阪勉強会 #48
  • 9. とりあえず、ブラウザ起動してみるusing System;using OpenQA.Selenium.IE;using OpenQA.Selenium;class Program { static void Main(string[] args) { IWebDriver driver = new InternetExplorerDriver(); Console.ReadKey(); driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 10. ドライバー の API• ページのタイトル取得• 要素の検索 – ISearchContext を実装 • FindElement, FindElements• ページ遷移 – INavigation を保持 • GoToUrl, Back, Forward• コンテキストの切り替え – ITargetLocator を保持 • Alert, Frame, Window わんくま同盟 大阪勉強会 #48
  • 11. Bing にいってみるusing System;using OpenQA.Selenium.IE;using OpenQA.Selenium;class Program { static void Main(string[] args) { IWebDriver driver = new InternetExplorerDriver(); driver.Navigate().GoToUrl("http://www.bing.com"); Console.WriteLine(driver.Title); Console.ReadKey(); driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 12. テキストボックスに文字を入力using System;using OpenQA.Selenium.IE;using OpenQA.Selenium;class Program { static void Main(string[] args) { IWebDriver driver = new InternetExplorerDriver(); driver.Navigate().GoToUrl("http://www.bing.com"); IWebElement element = driver.FindElement(By.Name("q")); element.SendKeys("セレニウム ウェブドライバー"); Console.ReadKey(); driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 13. わんくま同盟 大阪勉強会 #48
  • 14. ロケーターには何がある?• Id• Name• TagName• ClassName• CssSelector• LinkText• PartialLinkText• XPath わんくま同盟 大阪勉強会 #48
  • 15. using System; 色んな取り方をしてみるusing OpenQA.Selenium.IE;using OpenQA.Selenium;class Program { static void Main(string[] args) { IWebDriver driver = new InternetExplorerDriver(); driver.Navigate().GoToUrl("http://www.bing.com"); IWebElement elementByName = driver.FindElement(By.Name("q")); elementByName.SendKeys("セレニウム ウェブドライバー"); IWebElement elementById = driver.FindElement(By.Id("sb_form_q")); elementById.SendKeys(" ID で取ったお"); IWebElement elementByCss = driver.FindElement( By.CssSelector("input.sw_qbox")); elementByCss.Clear(); elementByCss.SendKeys("CssSelector で"); Console.ReadKey(); driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 16. エレメント の メソッド• SendKeys• Clear• Click• GetAttribute – input タグの入力値はこれで取得する• GetCssValue• Submit• 要素の検索 (ISearchContext を実装) わんくま同盟 大阪勉強会 #48
  • 17. エレメント の プロパティ基本 get だけ• Displayed• Enabled• Location• Selected – チェックボックスや Select の Option• Size• TagName• Text – タグに挟まれたテキストのこと – テキストボックスの値じゃない! わんくま同盟 大阪勉強会 #48
  • 18. ~実践~わんくま同盟 大阪勉強会 #48
  • 19. みんな大好き IE Driver を使う• 前準備 – IE がインストールされている – ツール => インターネット オプション => セ キュリティ タブ => 全てのゾーンで「保護 モードを有効にする」チェック値を統一 わんくま同盟 大阪勉強会 #48
  • 20. Chrome Driver を使う• 前準備 – Chrome がインストールされている – ChromeDriver.exe をダウンロードする http://code.google.com/p/chromedriver/downloads/list わんくま同盟 大阪勉強会 #48
  • 21. C# で• Visual Web Developer 2010 Express (VWD2010)• 拡張機能マネージャーから NuGet インス トール• Package Manage Console(NuGet) から Install-Package Selenium.WebDriver Install-Package Selenium.Support – Support は便利だからいれてます ここでは、以下のライブラリも利用しています Nunit、ChainingAssertion.NUnit わんくま同盟 大阪勉強会 #48
  • 22. [Test]public void 検索() { var driver = new InternetExplorerDriver(); try { driver.Navigate().GoToUrl("http://www.bing.com"); var txt条件 = driver.FindElementByName("q"); txt条件.SendKeys("Microsoft"); txt条件.Submit(); Thread.Sleep(3000); // 次の画面に遷移するまで待つ var lbl件数 = driver.FindElementById("count"); Regex.Match(lbl件数.Text, "(?<=of ).*(?= results)").Value.Is("527,000,000"); } finally { driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 23. 便利なやつ その1• IWait(Wait) – Selenium.Support に含まれている • OpenQA.Selenium.Support.UI.IWait – Thread.Sleep はもう古い! – 指定条件を満たすまで待機する – タイムアウト指定することで、異常時には例 外で終了する わんくま同盟 大阪勉強会 #48
  • 24. Wait• WebDriverWait が良く使われる• コンストラクタでタイムアウト時間指定• Until メソッドに Func を渡し条件指定• Func は、既定の実装が幾つかある – ExpectedConditions IWait<IWebDriver> wait = new WebDriverWait(driver, new TimeSpan(0, 0,10)); wait.Until(ExpectedConditions.TitleIs("Microsoft - Bing"));• Func を自前で実装も可 wait.Until(d => d.Title == "Microsoft - Bing"); わんくま同盟 大阪勉強会 #48
  • 25. [Test]public void 検索() { var driver = new InternetExplorerDriver(); try { driver.Navigate().GoToUrl("http://www.bing.com"); var txt条件 = driver.FindElementByName("q"); txt条件.SendKeys("Microsoft"); txt条件.Submit(); var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 10)); wait.Until(ExpectedConditions.TitleIs("Microsoft - Bing")); var lbl件数 = driver.FindElementById("count"); Regex.Match(lbl件数.Text, "(?<=of ).*(?= results)").Value.Is("527,000,000"); } finally { driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 26. PageObject パターン• 一つの HTML の操作は一つの場所で• 一つのページを一つのオブジェクトとして 扱い、カプセル化• メソッドは実行する機能を表現する(DOM の操作ではない) http://memolog.org/2010/11/page_objects.php http://code.google.com/p/selenium/wiki/PageObjects わんくま同盟 大阪勉強会 #48
  • 27. [TestFixture]public class カプセル化 { [Test] public void 検索() { var driver = new InternetExplorerDriver(); try { var instance = BingSearch.Create(driver); instance.Input検索条件("Microsoft"); instance.Submit検索(); instance.Get検索結果件数().Is("527,000,000"); } finally { driver.Quit(); } }} わんくま同盟 大阪勉強会 #48
  • 28. public class BingSearch { public static BingSearch Create(RemoteWebDriver driver) { var instance = new BingSearch(driver); driver.Url = "http://www.bing.com"; return instance; } private readonly RemoteWebDriver driver; private BingSearch(RemoteWebDriver driver) { this.driver = driver; } private IWebElement txt条件 { get { return driver.FindElementByName("q"); } } private IWebElement lbl件数 { get { return driver.FindElementById("count"); } } わんくま同盟 大阪勉強会 #48
  • 29. public void Input検索条件(string 条件) { this.txt条件.Clear(); this.txt条件.SendKeys(条件); } public void Submit検索() { this.txt条件.Submit(); var wait = new WebDriverWait(this.driver, new TimeSpan(0, 0, 10)); wait.Until(ExpectedConditions.TitleIs( "Microsoft - Bing")); } public string Get検索結果件数() { return Regex.Match(this.lbl件数.Text, "(?<=of ).*(?= results)").Value; }} わんくま同盟 大阪勉強会 #48
  • 30. Java (Maven) で• selenium-java <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.20.0</version> </dependency>• ie-driver や support もついてくる わんくま同盟 大阪勉強会 #48
  • 31. @Testpublic void 検索() { RemoteWebDriver driver = new InternetExplorerDriver(); try { driver.navigate().to("http://www.bing.com"); WebElement txt条件 = driver.findElementByName("q"); txt条件.sendKeys("Microsoft"); txt条件.submit(); Wait<WebDriver> wait = new WebDriverWait(driver, 10); wait.until(titleIs("Microsoft - Bing")); WebElement lbl件数 = driver.findElementById("count"); assertThat(lbl件数.getText().replaceAll( "(.*of )(.*)( results)", "$2"), is("527,000,000")); } finally { driver.quit(); }} わんくま同盟 大阪勉強会 #48
  • 32. @Testpublic void カプセル化() { RemoteWebDriver driver = new InternetExplorerDriver(); try { BingSearch instance = BingSearch.create(driver); instance.input検索条件("Microsoft"); instance.submit検索(); assertThat(instance.get検索結果件数(), is("527,000,000")); } finally { driver.quit(); }} わんくま同盟 大阪勉強会 #48
  • 33. public class BingSearch { private final RemoteWebDriver driver; public static BingSearch create(RemoteWebDriver driver) { BingSearch instance = new BingSearch(driver); driver.navigate().to("http://www.bing.com"); return instance; } private BingSearch(RemoteWebDriver driver) { this.driver = driver; } private WebElement txt条件() { return driver.findElementByName("q"); } private WebElement lbl件数() { return driver.findElementById("count"); } わんくま同盟 大阪勉強会 #48
  • 34. public void input検索条件(String 条件) { this.txt条件().clear(); this.txt条件().sendKeys(条件); } public void submit検索() { this.txt条件().submit(); Wait<WebDriver> wait = new WebDriverWait(driver, 10); wait.until(titleIs("Microsoft - Bing")); } public String get検索結果件数() { return this.lbl件数().getText().replaceAll( "(.*of )(.*)( results)", "$2"); }} Java だとプロパティ(getter) の 括弧 が鬱陶しい! わんくま同盟 大阪勉強会 #48
  • 35. 便利なやつ (その2)• PageFactory – PageObject の実装を少し楽にしてくれる – アノテーション/属性 ベースで、要素とフィー ルドのマッピング • WebElement 型の フィールド – キャッシュも可能 • ページ遷移/リロードを行った場合は、キャッシュ を取り直す必要あり – PageFactory.initElements で初期化を行う わんくま同盟 大阪勉強会 #48
  • 36. public class Top { public static Top create(WebDriver driver) { driver.navigate().to("http://www.bing.com"); Top instance = new Top(driver); PageFactory.initElements(driver, instance); return instance; } private final WebDriver driver; private Top(WebDriver driver) { this.driver = driver; } @FindBy(name = "q") @CacheLookup private WebElement txt条件; わんくま同盟 大阪勉強会 #48
  • 37. public Result search(String 条件) { this.txt条件.clear(); this.txt条件.sendKeys(条件); this.txt条件.submit(); Wait<WebDriver> wait = new WebDriverWait(driver, 10); wait.until(titleIs(条件 + " - Bing")); return Result.create(driver); }} わんくま同盟 大阪勉強会 #48
  • 38. public class Result { public static Result create(WebDriver driver) { return PageFactory.initElements(driver, Result.class); } private final WebDriver driver; public Result(WebDriver driver) { this.driver = driver; } @FindBy(id="count") private WebElement lbl件数; public String 検索結果件数() { return lbl件数.getText() .replaceAll("(.*of )(.*)( results)", "$2"); }} わんくま同盟 大阪勉強会 #48
  • 39. 便利なやつ(その3)• Select – input type=“select” な WebElement のラッ パー – Option の選択や取得を容易にしてくれる – PageFactory には対応していない わんくま同盟 大阪勉強会 #48
  • 40. SelectWebElement select = ~;List<WebElement> options = select.findElements(By.tagName("option"));for (WebElement option : options) { option.click(); // 選択させる if (option.isSelected()) { // 選択していたら }}Select wrapper = new Select(select);// 選択させるwrapper.selectByIndex(0);wrapper.selectByValue("hoge");wrapper.selectByVisibleText("フヒヒ");// 選択されているもの取得wrapper.getFirstSelectedOption();wrapper.getAllSelectedOptions(); わんくま同盟 大阪勉強会 #48
  • 41. よく使いそうな操作• Table 表示のデータ取得• スクリーンショットの取得• input type=“file” へのパス指定• Alert/Confirm ダイアログ• 新しい Window わんくま同盟 大阪勉強会 #48
  • 42. Table 表示のデータ取得• Java だとこんな感じ… – 1行を表すデータ型作成 – <tr> 単位でループし、コレクションの取得 • PageFactory 等を使用しインスタンス生成 – 比較処理• .NET だと… わんくま同盟 大阪勉強会 #48
  • 43. [Test]public void Table() { var driver = new ChromeDriver(@"c:work"); try { driver.Url = "http://nabewebdriver.apphb.com/"; var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 10)); wait.Until(d => d.Title == "メニュー"); driver.FindElementByPartialLinkText("検索画面").Click(); wait.Until(d => d.Title == "Search"); driver.FindElementByXPath("//input[@type=submit and @value=検索]").Click(); wait.Until(ExpectedConditions.ElementIsVisible(By.Id("results"))); driver.FindElementsById("roop").Select(e => new { Name = e.FindElement(By.Id("resultName")).Text, Birthday = e.FindElement(By.Id("resultBirthday")).Text, Money = e.FindElement(By.Id("resultMoney")).Text }).Is( new { Name = "名前1", Birthday = "1970/12/04", Money = "10,000" }, new { Name = "名前2", Birthday = "1980/10/15", Money = "15,000" }, new { Name = "名前3", Birthday = "1979/06/23", Money = "20,000" }, new { Name = "名前4", Birthday = "1990/08/06", Money = "25,000" }, new { Name = "名前5", Birthday = "2000/07/04", Money = "30,000" } ); } finally { driver.Quit(); }} わんくま同盟 大阪勉強会 #48
  • 44. driver.FindElementsById("roop").Select(e => new { Name = e.FindElement(By.Id("resultName")).Text, Birthday = e.FindElement(By.Id("resultBirthday")).Text, Money = e.FindElement(By.Id("resultMoney")).Text}).Is( new { Name = "名前1", Birthday = "1970/12/04", Money = "10,000" }, new { Name = "名前2", Birthday = "1980/10/15", Money = "15,000" }, new { Name = "名前3", Birthday = "1979/06/23", Money = "20,000" }, new { Name = "名前4", Birthday = "1990/08/06", Money = "25,000" }, new { Name = "名前5", Birthday = "2000/07/04", Money = "30,000" }); わんくま同盟 大阪勉強会 #48
  • 45. スクリーンショットの取得• TakesScreenshot を実装している Driver が対象 – 殆どの Driver は実装している• Java だと… FileUtils.copyFile( driver.getScreenshotAs(OutputType.FILE), new File("c:/work/hoge.png") );• NET だと… driver.GetScreenshot().SaveAsFile( @"c:workhoge.png", ImageFormat.Png); わんくま同盟 大阪勉強会 #48
  • 46. input type=“file” へのパス指定• WebElement を取得し、sendKeys でフル パスを渡す。• Java だと… driver.findElement(By.id("fileupload")) .sendKeys("c:/work/result.jpg");• NET だと… driver.FindElement(By.Id("fileupload")) .SendKeys(@"c:workresult.jpg"); わんくま同盟 大阪勉強会 #48
  • 47. Alert/Confirm ダイアログ• WebDriver から TargetLocator を取得し、 alert を呼ぶ。• Java だと… Alert dialog = driver.switchTo().alert();• NET だと… var dialog = driver.SwitchTo().Alert(); わんくま同盟 大阪勉強会 #48
  • 48. Alert インターフェース• getText – 表示しているテキストを取得• accept – OK ボタンクリック• dismiss – キャンセル ボタンクリック• sendKeys わんくま同盟 大阪勉強会 #48
  • 49. Alert/Confirm ダイアログ 注意点• ダイアログが表示されている間は他の操作 は出来ない – Driver や Element の操作• accept/dismiss した後に Alert を操作 – 閉じている Dialog は操作出来ない• Alert を取得する際は、念のため Wait を使 う わんくま同盟 大阪勉強会 #48
  • 50. エラーになるケースHTML<input type="button" id="btn" value="hoge“ onclick="alert(hoge);" /><input type="text" id="txt" />C# コードvar text = driver.FindElementById("txt");driver.FindElementById("btn").Click();// text.SendKeys("hoge"); // Error// driver.FindElementById("button"); // Errorvar dialog = driver.SwitchTo().Alert();dialog.Accept();var dialogText = dialog.Text; // Error わんくま同盟 大阪勉強会 #48
  • 51. Alert 取得時の Wait• Java だと… Wait<WebDriver> wait = new WebDriverWait(driver, 10); Alert dialog = wait.until(alertIsPresent());• NET だと… var wait = new WebDriverWait( driver, new TimeSpan(0, 0, 10)); var dialog = wait.Until(d => { try { return d.SwitchTo().Alert(); } catch (Exception) { return null;} }); わんくま同盟 大阪勉強会 #48
  • 52. 新しい Window• WebDriver から TargetLocator を取得し、 window を呼ぶ。 – 戻り値は WebDriver で呼び出し元と同じイン スタンス• Java だと… driver.switchTo().window("name or handler");• NET だと… driver.SwitchTo().Window("name"); // 一応 handler でもOK わんくま同盟 大阪勉強会 #48
  • 53. WindowHandler の取得• Java だと… String current = driver.getWindowHandle(); Set<String> all = driver.getWindowHandles();• NET だと… var current = driver.CurrentWindowHandle; var all = driver.WindowHandles; わんくま同盟 大阪勉強会 #48
  • 54. 新しい Window 切替時の Wait• Java だと… Wait<WebDriver> wait = new WebDriverWait(driver, 10); wait.until(new Function<WebDriver, WebDriver>() { public WebDriver apply(WebDriver arg0) { try { return arg0.switchTo().window("windowName"); } catch (Exception e) { return null; } } });• NET だと… var wait = new WebDriverWait( driver, new TimeSpan(0, 0, 10)); wait.Until(d => { try { return d.SwitchTo().Window("windowName"); } catch (Exception) { return null;} }); わんくま同盟 大阪勉強会 #48
  • 55. ~まとめ~わんくま同盟 大阪勉強会 #48
  • 56. まとめ• 複数の言語/ブラウザに対応している – Java が API が充実してそう• 大概のことは出来ます – 今回説明省いたきましたが、Interactions を使 えば、Drag&Drop みたいな事も http://code.google.com/p/selenium/wiki/AdvancedUserInteractions# Mouse_interactions• Wait 超大事!• 当然テスト以外でも使えます – ブラウザ操作の自動化 わんくま同盟 大阪勉強会 #48