2012-01-26 20 views
3

私は以下のようにセレンを使用してのtestMethodを持っている:システムテストでSeleniumを使用するときにThread.Sleepを使用する代わりに何ができますか?

[TestMethod] 
     public void ShouldSendPasswordReminder() 
     { 
      // go to loginregister url 
      _fireFoxWebDriver.Navigate().GoToUrl(UkPaBaseUrl + "loginregister.aspx"); 
      Thread.Sleep(1000); 

      // click the forgotten password 
      _fireFoxWebDriver.FindElement(By.LinkText("Forgotten your password?")).Click(); 
      Thread.Sleep(1000); 

      // enter your email address 

      _fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_Username")) 
       .SendKeys("[email protected]"); 
      Thread.Sleep(1000); 

      // click submit 
      _fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_PasswordResetRequestSubmit")).Click(); 
      Thread.Sleep(5000); 

      // assert 
      Assert.IsTrue(_fireFoxWebDriver.Url.Contains("ThankYou")); 
     } 

あなたが見ることができるようにページが、それが原因JavaScriptに何を完了するためにいくつかの時間がかかる場合がありますので、私は(何回ものThread.sleepを呼び出す必要があるだろうなど)を使用しているため、SeleniumはWatiNとは異なりページの読み込みや遅延を処理できないようであるため

これはコードをかなり醜く、あまり信頼性が高くありません。

このようなシナリオを処理するにはどうすればよいでしょうか?あなたのテストで頻繁にThread.Sleepコールを書くのですか?

おかげで、

+0

これは[公式ドキュメント]をチェックし、その使用方法についての詳細情報については同じ質問http://stackoverflow.com/questions/5868439/wait-for-page-load-in-selenium – Sign

答えて

3

あなたはFindElement()が失敗する前に待つしたいベースライン時に設定する管理機能を使用することができます。私のスクリプトがより速くなったときに遅延を導入する上

_fireFoxWebDriver.Manage() 
       .Timeouts() 
       .ImplicitlyWait(TimeSpan.FromSeconds(1000)); 
+0

のようです(http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp) – dialex

0

私の一般的なヒューリスティックを私のアプリは本当に私が待っているものについて考えることです。私の意見では、スリープタイプの呼び出しは、実際には時間が経過するのを実際に待っている場合にのみ適切です。自動タイムアウトをテストしていた場合、実際には一定の時間が経過するのを実際に待っているので、Thread.sleep型の呼び出しを持つことが理にかなっているかもしれません。しかし、通常は、ロードするページ、実行するjavascriptなど、他のことが起こるのを待っています。このような場合、一定の時間待機することは、潜在的により複雑なチェック私が実際に待っているもののために。これには複数の落とし穴があります - テストをあまり遅くしているかもしれません(たとえば、上記の待機時間がそれぞれ200msに過ぎなかった場合など) - 上記の簡単なスニペットでもさらに2.5秒かかる場合がありますもう一回落ちるのは、あなたが遅いマシンに移動したり、環境の悪いものがあなたのアプリケーションを遅くしたり、1.5秒かかったらどうしたらいいのでしょうか?パスワードを忘れた場合は、 1つのマシン上のリンク。あなたのテストは失敗するかもしれませんが、それでもあなたのアプリの許容可能なパフォーマンスのスレッショルドの範囲内にある可能性があります。これは待ち時間を増やすだけで対処されることが多いですが、それは私が再び言及した最初の落とし穴につながります。

このサイクルを逃れるためには、私が物事を待っているときにできるだけ具体的にすることが非常に重要であることがわかります。 Seleniumは、特定の条件が満たされるまで待機するために使用できるWaitクラスを提供します。私は.Netバインディングにそれが含まれているかどうかはわかりませんが、私はそれを期待して使っています。 Rubyのバージョンでは、Waitにコードブロックを与えます。これは、要素の存在またはそれ以外のものを確認する必要があるかどうかを調べることができます。 waitメソッドは、タイムアウト値とインターバル値をとり、ブロックがtrueを返すかタイムアウト時間が経過するまで、インターバル秒ごとにブロックを実行します。このようなクラスを設定することで、パフォーマンススケールのローエンドを処理するためにタイムアウト値を十分に高く設定できますが、特定の実行で本当に必要な時間よりもずっと長く待つことのペナルティは発生しません。

2

明示的に待機します。 公式文書(http://www.seleniumhq.org/docs/0..。)によると、Thread.sleep()は明示的な待機の最悪のケースです。

最大待機時間を待つことなく、明示的に待機している間、指定された最大時間が経過する前に条件が発生すると、条件が発生するとすぐに処理を進めます。したがって、(指定された最大時間の間に条件が発生しなかったため)最大時間まで待たなければならないのは、明示的な待機の最悪の場合です。

Thread.sleep()は、Thread.sleep()の場合、Thread.sleep()の引数として指定されたフルタイムを待たなければならないため、明示的な待機の最悪のケースと考えられます。さらに。

なぜThread.sleep()が暗黙的に待機しているのか分かるかもしれません。 Thread.sleep()の効果は、明示的な待機のように、書かれている場所でしかないからです。ただし、暗黙的な待機の影響は、ドライバインスタンスの全ライフタイムです。

**JAVA** 
WebDriver driver = new FirefoxDriver(); 
driver.get("http://somedomain/url_that_delays_loading"); 
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement"))); 

**C#** 
using (IWebDriver driver = new FirefoxDriver()) 
{ 
driver.Url = "http://somedomain/url_that_delays_loading"; 
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
IWebElement myDynamicElement = wait.Until<IWebElement>(d => d.FindElement(By.Id("someDynamicElement"))); 
} 

これはTimeoutExceptionをスローする前に10秒まで待つか、それが見つかった場合、要素は0で、それを返します - 10秒。

私のテストケースでは、最大10秒待つことを望んでいました。以前は、Thread.Sleepを使用して次の要素を見つける前に10秒待っていました。今ではWebDriverWaitを使用していますので、要素が処理されている場合は、日々のアクティビティが速くなり、時間も節約できます。

using (IWebDriver driver = new ChromeDriver(options)) 
     { 
      TimeSpan t = TimeSpan.FromSeconds(10); 
      WebDriverWait wait = new WebDriverWait(driver,t); 
      try 
      { 
       driver.Navigate().GoToUrl("URL"); 
       //IWebElement username = driver.FindElement(By.Name("loginfmt")); 
       IWebElement username = wait.Until(ExpectedConditions.ElementIsVisible(By.Name("loginfmt")));          
       username.SendKeys(dictionaryItem); 
       //Thread.Sleep(10000); Removed my Thread.Sleep and tested my wait.Until and vola it works awesome. 
       IWebElement next = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idSIButton9"))); 
       //IWebElement nextdriver.FindElement(By.Id("idSIButton9")); 
       next.Click(); 
関連する問題