2017-09-29 19 views
-2

異なるブラウザー間で複数回実行すると、順次テストは合格しますが、並列テストは失敗します。私はここで間違って何をしていますか?Selenium Java Testng - ページファクトリを使用した並列テストの実行?

私はthreadlocalで試しましたが、うまくいきませんでした。私はドライバオブジェクトのハッシュコードでチェックし、すべてのテストにはドライバIDとドライバオブジェクトのハッシュコードがdriver.get(url)まであり、ページオブジェクトメソッドがすべて開始されたときには空白になります。 私はmaven threadpoolsizeを並列で実行しようとしましたが、同じ結果が得られました。

私は立ち往生しています。どんな助けもありがとうございます。ページファクトリパターンで並列実行を明確に説明する単一のブログは見つかりません。テストメソッド自体で書かれたすべてのセレンのアクションを持つシンプルなスクリプトは正常に動作しますが、コードの再利用性とメンテナンスのためにページファクトリを使用する必要がない場合はそうではありません。

は、問題があなたのテストコードである複数のテストクラスと実際のシナリオのように複数のページ

public class WebDriverManager { 

     private static HashMap<Long, WebDriver> map = new HashMap<>(); 

     public static WebDriver getDriverInstance() { 
      return map.get(Thread.currentThread().getId()); 
     } 

     public static void startDriver(String OS_Browser) throws Exception { 
      WebDriver driver; 

      if (OS_Browser.equalsIgnoreCase("Win7_Chrome")) 
       ChromeDriverManager.getInstance().version("2.31").setup(); 
       driver = new ChromeDriver(); 
       map.put(Thread.currentThread().getId(), driver); 
     } 

     public static void stopDriver() { 
      WebDriver driver = map.get(Thread.currentThread().getId()); 
      if (null != driver) { 
       driver.quit(); 
       driver = null; 
      } 
     } 
    } 

<!-- language: java --> 

public class Login extends TestBase { 

    @Parameters({"OS_Browser"}) 
    @BeforeMethod(alwaysRun = true) 
    protected void oneTimeSetup(@Optional("Win7_Chrome") String OS_Browser) throws Exception { 
     WebDriverManager.startDriver(OS_Browser); 
    } 

    @AfterMethod(alwaysRun = true) 
    protected void oneTimeTeardown() { 
     WebDriverManager.stopDriver(); 
    } 


    @Test() 
    public void Test_Error_Messages_For_Blank_Invalid_Incorrect_login_Credentials() throws Exception { 
     WebDriver driver = WebDriverManager.getDriverInstance(); 
     driver.get(url); 

     Login_Page LoginPage = new Login_Page(driver); 

     LoginPage.wait_For_Login_PageLoad() 
       // UI Validation 
       .verify_Color_On_Links() 
       .verify_Texts_On_Login_Page() 
       .verify_Header_Logos() 
       // Check error messages for blank email and password 
       .click_SignIn() 
       .wait_For_Blank_Credentials_Error_Message() 
       // Check error messages for invalid email and password 
       .login("admin", "admin") 
       .wait_For_Invalid_Credentials_Error_Message() 
       // Check error messages for incorrect email and password 
       .login("[email protected]", "admin") 
       .wait_For_Incorrect_Credentials_Error_Message(); 
    } 
} 
public class Login_Page { 

    private final WebDriver driver; 

    @FindBy(css = "input#email") 
    private WebElement login_username; 
    @FindBy(css = "input#password") 
    private WebElement login_password; 
    @FindBy(css = "button#signin") 
    private WebElement button_signIn; 

    @FindBy(css = "a[ng-click*='terms']") 
    private WebElement terms_of_use; 
    @FindBy(css = "a[ng-click*='privacy']") 
    private WebElement privacy_policy; 
    @FindBy(css = "a[ng-click*='trademarks']") 
    private WebElement trademarks; 
    @FindBy(css = "a[ng-click*='ContactUs']") 
    private WebElement contactus; 

    @FindBy(css = "fieldset > div:nth-of-type(1) > p") 
    private WebElement signin_text; 
    @FindBy(css = ".container.ng-scope>img") 
    private WebElement header_logo; 

    @FindBy(css = "p[ng-show*='error.email'][aria-hidden='false']") 
    private WebElement enter_valid_email_address_error_message; 
    @FindBy(css = "p[ng-show*='loginform.emailaddress.$error.required'][aria-hidden='false']") 
    private WebElement email_required_error_message; 
    @FindBy(css = "p[ng-show*='loginform.password.$error.required'][aria-hidden='false']") 
    private WebElement password_required_error_message; 
    @FindBy(css = "span[translate='sign_error_msg']") 
    private WebElement enter_correct_credentials; 

    @FindBy(css = "img[src='img/common/ajax_progress.gif']") 
    private WebElement pleaseWait; 

    // Constructor takes a reference to the driver 
    public Login_Page(WebDriver driver) { 
     this.driver = driver; 
     PageFactory.initElements(driver, this); 
    } 

    public Login_Page click_SignIn() { 
     button_signIn.click(); 
     return this; 
    } 

    public Login_Page login(String username, String password) { 
     login_username.clear(); 
     login_username.sendKeys(username); 

     login_password.clear(); 
     login_password.sendKeys(password); 

     button_signIn.click(); 

     (new WebDriverWait(driver, 10)) 
       .until(ExpectedConditions.invisibilityOf(pleaseWait)); 
     return this; 
    } 

    public Login_Page wait_For_Blank_Credentials_Error_Message() throws InterruptedException { 
     (new WebDriverWait(driver, 10)).until(ExpectedConditions.and(
       ExpectedConditions.visibilityOf(password_required_error_message), 
       ExpectedConditions.visibilityOf(email_required_error_message))); 

     String emailRequiredErrorMessage = email_required_error_message.getText().trim(); 
     Assert.assertEquals(emailRequiredErrorMessage, "Your email address is required to proceed."); 

     String passwordRequiredErrorMessage = password_required_error_message.getText().trim(); 
     Assert.assertEquals(passwordRequiredErrorMessage, "Your password is required to proceed."); 

     return this; 
    } 

    public Login_Page wait_For_Invalid_Credentials_Error_Message() throws InterruptedException { 
     (new WebDriverWait(driver, 10)) 
       .until(ExpectedConditions.visibilityOf(enter_valid_email_address_error_message)); 

     String ErrorMessage = enter_valid_email_address_error_message.getText().trim(); 
     Assert.assertEquals(ErrorMessage, "Please enter the email address in a valid format."); 

     return this; 
    } 

    public void wait_For_Incorrect_Credentials_Error_Message() { 
     (new WebDriverWait(driver, 10)) 
       .until(ExpectedConditions.visibilityOf(enter_correct_credentials)); 
     String ErrorMessage = enter_correct_credentials.getText().trim(); 
     Assert.assertEquals(ErrorMessage, "Sign-in credentials did not match. If you have not created an account with your email address and a password, you will need to do so before signing in."); 
    } 

    public Login_Page verify_Color_On_Links() { 
     String blue_Link_Color = "#026091"; 
     List<WebElement> allLinks = driver.findElements(By.cssSelector("body a[href='#']")); 
     for (WebElement ele : allLinks) { 
      String color = ele.getCssValue("color"); 
      String colorInHex = Color.fromString(color).asHex(); 
      assertEquals(colorInHex, blue_Link_Color); 
     } 
     return this; 
    } 

    public Login_Page verify_Texts_On_Login_Page() { 
     String actual1 = signin_text.getText().trim(); 
     String expected1 = "Please enter your email address and password in order to proceed."; 
     Assert.assertTrue(actual1.contains(expected1)); 
     return this; 
    } 

    public Login_Page verify_Header_Logos() { 
     int headerLogoWidth = header_logo.getSize().getWidth(); 
     int headerLogoHeight = header_logo.getSize().getHeight(); 
     Assert.assertEquals(headerLogoWidth, 480); 
     Assert.assertEquals(headerLogoHeight, 100); 
     return this; 
    } 

    public Login_Page wait_For_Login_PageLoad() { 
     JSWaiter.waitJQueryAngular(); 
     (new WebDriverWait(driver, 15)).until(ExpectedConditions.and(
       ExpectedConditions.visibilityOf(login_username), 
       ExpectedConditions.visibilityOf(login_password), 
       ExpectedConditions.visibilityOf(button_signIn))); 
     return this; 
    } 

} 
<?xml version="1.0"?> 
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 
<suite name="Login Suite" parallel="tests" thread-count="2"> 
    <parameter name="URL" value="www.google.co.in"/> 
    <test name="Login Tests - Win7_Chrome"> 
     <parameter name="OS_Browser" value="Win7_Chrome"/> 
     <classes> 
      <class name="com.company.tests.Login"/> 
     </classes> 
    </test> 
    <test name="Login Tests - Win7_IE"> 
     <parameter name="OS_Browser" value="Win7_IE"/> 
     <classes> 
      <class name="com.company.tests.Login"/> 
     </classes> 
    </test> 
</suite> 
+0

誰もこのコードを読んでいません。それを[mcve]に減らす必要があります。 [ask]、特に[mcve](MCVE)の部分、[どのくらいの研究努力が期待されていますか]を読んでください(https://meta.stackoverflow.com/questions/261592/how-much-research-effort-これは、あなた自身のプログラムをデバッグし、自分で問題を解決するのに役立ちます。あなたがこれを行い、まだまだ立ち往生している場合は、あなたがMCVEを投稿し、何を試したのか、そしてエラーメッセージを含む実行結果を投稿して、より良くあなたを助けることができます。 – JeffC

答えて

1

を想定します。あなたのコードには、@BeforeTest注釈付きメソッド内にウェブドライバ作成ロジックが格納されています。

TestNGは、<test>タグごとに1回だけ@BeforeTestメソッドを呼び出します。

あなたのコードはさらに、WebdriverのインスタンスをキーがスレッドIDであるマップに保持します。

このモデルは、順次実行で正常に動作します。しかし、並列実行モデルに移行するとすぐに、TestNGは@BeforeTestメソッドと@Testメソッドを同じスレッドで実行することを保証しないため、すぐに問題を検討しています。

@BeforeTest注釈を使用する代わりに、最初に@BeforeMethodを使用することをお勧めします。 TestNGは@BeforeMethod>@Test>@AfterMethodを常に同じスレッド上で実行するため、WebdriverインスタンスをThreadLocalに保存できます。

もう1つのオプションは、基本的に、Webdriverのインスタンス化とクリーンアップをテストクラスにアタッチできるリスナーに移動することです。そうすれば、懸念の分離に固執し、テストクラスはwebdriverライフサイクル管理ロジックで汚染されません。

私のブログポストhereでリスナーを使用してTestNGで並列実行を管理する方法の詳細を読むことができます。

+0

私はbeforeinvocationとしてあなたの方法を試しました、テスト&afterinvocationは同じスレッドで実行されます。すべてのセレンのアクションがテストメソッド自体では実行されますが、ページファクトリを持つページオブジェクトでは実行されない単純なスクリプトのための作業です。スレッドIDとwebdriverオブジェクトのハッシュコードは、ページオブジェクトが開始するまでユニークです –

関連する問題