2016-07-27 8 views
-2

セレンテストに使用できる一般的なWebdriverクラスを作成しました。新しいテストを作成するたびに、私はこのクラスからwebdriverを取得します。 SauceLabs上で実行されます。ここSeleniumテストをSauceLabsに接続

私はここで

package com.atmn.config; 

import java.net.MalformedURLException; 
import java.net.URL; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.remote.CapabilityType; 
import org.openqa.selenium.remote.DesiredCapabilities; 
import org.openqa.selenium.remote.RemoteWebDriver; 

public class Driver { 


    private static Log log = LogFactory.getLog(Driver.class); 
    public static String USERNAME = "name"; 
    public static String ACCESS_KEY = "key"; 

    public static WebDriver driver = createDriver("firefox", "47.0", "Windows 10"); 

    public static WebDriver createDriver(String browser, String version, String os) { 

     try{ 
      DesiredCapabilities capabilities = new DesiredCapabilities(); 
      capabilities.setCapability(CapabilityType.BROWSER_NAME, browser); 
      capabilities.setCapability(CapabilityType.VERSION, version); 
      capabilities.setCapability(CapabilityType.PLATFORM, os); 

      // Launch remote browser and set it as the current thread 
      return new RemoteWebDriver(
        new URL("http://"+USERNAME+":"+ACCESS_KEY+"@ondemand.saucelabs.com:80/wd/hub"), 
        capabilities); 
     } 
     catch(MalformedURLException e) 
     { 
      e.printStackTrace(); 
      //log message 
      log.info(e.getMessage()); 
     } 
     return null; 
    } 

は私のテストで私のドライバを作成するために使用していますものですが、Windowsの10およびFirefox 47

package com.atmn.tests; 

import com.tplus.atmn.tasks.CommonTasks; 
import com.tplus.atmn.objects.TOA6; 
import java.lang.reflect.Method; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.openqa.selenium.By; 
import org.testng.Assert; 
import org.testng.annotations.DataProvider; 
import org.testng.annotations.Test; 
import com.tplus.atmn.tasks.HttpRequest; 


public class Testing extends CommonTasks { 

    private static Log log = LogFactory.getLog(TB6_TOA.class); 


    @Test (groups = {"Testing"}) 
    public static void endToEnd() throws Exception { 


     //Load URL 
     HttpRequest http = new HttpRequest(); 
     String URL = http.internetWebAddress(); 
     driver.get(URL); 


     //Page 1 
      // Item Text 
     verifyText(Object.ItemText, "Multiple Choice - Single Answer Radio - Vertical"); 
     verifyText(Object.Progress_PercentComplete, "0%"); 
      //URL 
     verifyNoRedirect(); 
      //Go to next page 
     driver.findElement(Object.Start).click(); 
     System.out.println("Next Button was clicked."); 

} 
} 

の代わりにちょうど私を実行しているを使用しますSauceLabsの1つのブラウザでテストして、このテストを複数のブラウザ/ OSの組み合わせで並行して実行したいと思います。これを実現するためにドライバクラスを変更する方法がわかりません。

+0

あなたはこの質問をグーグルましたか?彼らの助けwikiを読んだことがありますか? – JeffC

+0

それは深刻な問題ですか?はい、私はそれをgoogled。はい、私はwikiを見ました。私はそれを理解することができないので、私は質問を投稿した。 – TestRaptor

+0

はい、それは深刻な問題です。あなたの質問にグーグルで答えることができ、60歳未満で答えを見つけることができるとき、私は一般的に、質問者が自分の質問にグーグルで悩まされているかどうか尋ねます。 Saucelabs wikiの[Running Tests in Parallel](https://wiki.saucelabs.com/display/DOCS/Java+Test+Setup+Example#JavaTestSetupExample-RunningTestsinParallel)というこの記事を読んでいましたか?あなたが探しているものを持っているように見えます。そうでない場合、何が欠けていますか? – JeffC

答えて

0

TestNGを使用しています。このテストフレームワークは、組み込みの並列実行をサポートしています(これはスイートファイルに追加することも、他の方法で設定することもできます)。また、DataProviderを使用して、テストメソッドへの引数を取り込むこともできます。テストフレームワークを設定する方法はたくさんありますが、構造の仕方にはさまざまな要素があります。

まず、Driverクラスに静的なWebDriverインスタンスを作成していますが、これはあなたが望むものではありません。実際に何をしたいのかは複数のインスタンスが必要です。そのクラスのファクトリメソッドは、必要に応じて各メソッドのWebDriverを作成することができます。考慮すべきもう一つの考慮点は、TestNGがメソッドごとにテストクラスオブジェクトの新しいインスタンスを作成しないという事実です。そのため、競合を避けるようにしない限り、テストクラスオブジェクトにフィールドとして状態を格納することはできません(たとえば、ThreadLocalフィールドなど)。残念ながら、Seleniumテストの場合、WebDriverを終了してSauceLabsリソースを解放する必要があります。通常は@AfterMethodの設定方法でこれを行うことができますが、設定メソッドがテストメソッドと同じスレッドで実行される保証はありませんので、ThreadLocalフィールドを使用すると、同じ引数にアクセスすることはできませんウェブドライバ)。クラスオブジェクトのWebドライバにテストメソッドのマップを使用することができます(TestNGではテストメソッドを引数として注入できます)が、複数のOS /ブラウザの組み合わせを可能にするデータプロバイダの場合は、同じテストが行​​われますメソッドも同様です。 TestNGとSeleniumの最後では、私の経験上、DataProviderを使用してテストクラスオブジェクトにフィールドを格納し、並列性をクラスレベルに制限するのが最も良い(または少なくとも最も簡単な)方法です。

これは、並列メソッドでテストする方法の例です。単純なpom.xml依存セクションから始めて、この例で使用するバージョンを表示してください。あなたのバージョンが少し異なっていても、それは非常に似ているはずです。

<dependencies> 
    <dependency> 
     <groupId>org.seleniumhq.selenium</groupId> 
     <artifactId>selenium-java</artifactId> 
     <version>2.53.1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.testng</groupId> 
     <artifactId>testng</artifactId> 
     <version>6.9.10</version> 
    </dependency> 
</dependencies> 

Driverクラスを更新して、毎回新しいドライバインスタンスを確実に返すようにします。私はちょうどいくらかのスペースを節約するために、そのロガー部分を削除しました。また、実際には静的なファクトリであり、インスタンスを許可することが意味をなさないため、インスタンス化できません。また、純粋に実装の詳細なので、名前やキーのようなものへのアクセスを許可しないでください。

public final class Driver { 

    private static final String USERNAME = "name"; 
    private static final String ACCESS_KEY = "key"; 

    public static WebDriver createDriver(String browser, String version, String os) { 
     // Should probably validate the arguments here 
     try { 
      DesiredCapabilities capabilities = new DesiredCapabilities(); 
      capabilities.setCapability(CapabilityType.BROWSER_NAME, browser); 
      capabilities.setCapability(CapabilityType.VERSION, version); 
      capabilities.setCapability(CapabilityType.PLATFORM, os); 
      return new RemoteWebDriver(new URL("http://" + USERNAME + ":" + ACCESS_KEY + "@ondemand.saucelabs.com:80/wd/hub"), 
             capabilities); 
     } catch (MalformedURLException e) { 
      throw new RuntimeException("Failure forming the URL to create a web driver", e); 
     } 
    } 

    private Driver() { 
     throw new AssertionError("This is a static class and shouldn't be instantiated."); 
    } 
} 

最後に、テストクラス自体では、実際のテストメソッドとデータプロバイダを定義する必要があります。複数のテスト/テストクラスに対して同じデータプロバイダが必要な場合は、問題ありません。詳細については、TestNGのドキュメントを参照してください:

http://testng.org/doc/documentation-main.html#parameters-dataproviders

import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.testng.annotations.DataProvider; 
import org.testng.annotations.Test; 

public class FooTest { 

    @DataProvider(name = "DriverInfoProvider", parallel = true) // data providers force single threaded by default 
    public Object[][] driverInfoProvider() { 
     return new Object[][] { 
      { "firefox", "47.0", "Windows 10" }, 
      { "chrome" , "51.0", "Windows 10" }, 
      // etc, etc 
     }; 
    } 

    @Test(dataProvider = "DriverInfoProvider") 
    public void testFoo(String browser, String version, String os) { 
     WebDriver driver = Driver.createDriver(browser, version, os); 
     try { 
      // simple output to see the thread for each test method instance 
      System.out.println("starting test in thread: " + Thread.currentThread().getName()); 
      // Putting this in a try catch block because you want to be sure to close the driver to free 
      // up the resources even if the test fails 
      driver.get("https://www.google.com"); 
      driver.findElement(By.name("q")).sendKeys("Hello, world"); 
     } finally { 
      driver.quit(); 
     } 
    } 
} 

私はアーキテクチャの観点から、好きではないが、私はあなた与えたかったこれらの例について多くのことがあることに注意してください考えるべきいくつかの問題のアイデアと、あなたがすでに持っているものに似ている簡単な実例です。最後に、テストクラスを並行して実行するには、TestNGスイートを作成して実行します。これらは通常XMLで定義されます(YAMLも使用できます)。

最後にGoogleにロードされ、この出力例と一緒にアクションを実行した二つの試験にそのリードを実行している
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> 
<suite name="MySuiteNameHere" parallel="methods" thread-count="15"> 

    <test name="Selenium Tests"> 
     <classes> 
      <class name="foo.bar.FooTest"/> 
     </classes> 
    </test> 
</suite> 

starting test in thread: PoolService-1 
starting test in thread: PoolService-0 
関連する問題