2017-03-09 10 views
0

TestNGを使用して、1台のマシンでSelenium Webdriverテストを並列実行しようとしています。 3つの異なるユーザーが同じアプリケーションにログインしてホームページにアクセスする3つの@Testメソッドがあります。 @Testメソッドを並列に実行し、ExtentReportsレポートに書き込む必要があります。Selenium Webdriver TestNGテストが互いに上書きされています

私の問題は、異なるクラスの3つの全く異なるメソッドにもかかわらず、1人のユーザーが3人のブラウザのうち2人にログインしてユーザーを残してしまうことです。

ログインメソッドは、PageFactoryページオブジェクトクラスにあります。ここで

は私の3試験方法です:

@Test(enabled = true, priority = 0) 
public void JohnLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "John"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver()); 
     assertTrue(objHomePage.clientName.getText().c‌​ontains("John")); 
    } catch (Exception e) { 
    } 
} 

@Test(enabled = true, priority = 1) 
public void BobLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "Bob"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver());  
     assertTrue(objHomePage.clientName.getText().c‌​ontains("Bob")); 
    } catch (Exception e) { 
    } 
} 

@Test(enabled = true, priority = 2) 
public void SamLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "Sam"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver());  
     assertTrue(objHomePage.clientName.getText().c‌​ontains("Sam")); 
    } catch (Exception e) { 
    } 
} 

だから、私はホームページでテストを一時停止した場合。私は2つのブラウザウィンドウを "John"、1つの "Bob"と "Sam"というようにオープンさせます...失敗を引き起こします。

次はPageFactoryオブジェクトのログインメソッドです。まず

public void SignIn(String strUsername, String strPassword) throws InterruptedException { 
    WebDriverWait wait = new WebDriverWait(driver, 15); 
    username.clear(); 
    username.sendKeys(strUsername); 
    password.clear(); 
    password.sendKeys(strPassword); 
    submit.click(); 
    wait.until(ExpectedConditions.visibilityOf(homePagePanel)); 
} 

私はこの問題は、(のように、テストは@Beforeと@Afterよりも別のスレッドにあった)@BeforeMethodスレッドにあったと確信していました。しかし、私はそれがどのようになるかは分かりません。基本テストメソッドは3つのブラウザを正常に開いて閉じます。 @Testメソッドがお互いのデータを使用するように見えるだけです!しかし、その場合、私のスレッディングコードで@Beforeと@Afterがあります。

public class BaseTest { 
    public String browser; 
    private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 

@BeforeMethod(alwaysRun = true) 
@Parameters({ "browser"}) 
public void setup(String browser)throws MalformedURLException, 
InterruptedException { 

     WebDriver driver = null; 
     if (browser.equalsIgnoreCase("Internet Explorer")) { 
      System.setProperty("webdriver.ie.driver", "C:\\Selenium\\IEDriverServer.exe"); 
      driver = new InternetExplorerDriver(); 
     } else if (browser.equalsIgnoreCase("Firefox")) { 
      System.setProperty("webdriver.gecko.driver", "C:\\Selenium\\geckodriver.exe"); 
      driver = new FirefoxDriver(); 
     } else if (browser.equalsIgnoreCase("chrome")) { 
      System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe"); 
      driver = new ChromeDriver(); 
     } else if (browser.equalsIgnoreCase("MicrosoftEdge")) { 
      System.setProperty("webdriver.edge.driver", "C:\\Selenium\\MicrosoftWebDriver.exe"); 
      driver = new EdgeDriver(); 
     } 
     setWebDriver(driver); 
     this.browser = browser; 
     ClientReportFactory.getTest(ExtentTestName, ExtentTestDescription); 

baseURL = "testApp.com"; 
driver.get(baseURL); 
     driver.manage().window().maximize(); 
     } 

public WebDriver getDriver(){ 
    return threadedDriver.get(); 
} 
public void setWebDriver(WebDriver driver) { 
    threadedDriver.set(driver); 
} 

@AfterMethod 
public void afterMethod() { 
    ClientReportFactory.closeTest(ExtentTestName, ExtentTestDescription); 
    getDriver().quit(); 
    threadedDriver.set(null); 
} 

@AfterSuite 
public void afterSuite() { 
    ClientReportFactory.closeReport(); 
    if (getDriver() != null) { 
     getDriver().quit(); 
    } else { 
     System.out.println("Drivers already closed"); 
    } 
} 

答えて

2

私は、問題はおそらくあなたのThreadLocal変数がSTATICではなく、インスタンス変数であるという事実によるものであることを推測しています、あなたの@Test方法の全てが異なるクラスであると仮定すると、 。これは、すべてのインスタンスにわたってスレッド当たり所望の動作、すなわちではなく、/スレッドのインスタンス当たりとなります。。これについては、this StackOverFlowスレッドを参照してください。

今あなたが唯一のクラスレベルのデータメンバWebDriverが共有されていることを確認しようとしているためとすべての@Test方法は(同じテストクラスに属している場合にのみ場合は、ThreadLocalのインスタンスのバリアントを使用してに頼るだろう同じテストクラスに属するすべてのテストメソッド間でスレッドセーフな方法)

だからあなた@Test方法のそれぞれが独自のテストクラス内に存在する場合は、変更してみてください。

private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 

private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 
+0

クリシュナン、私の答えは間違っていますか?私は勉強したいと思います。 – Dineshmohan

+0

@Dineshmohan - 私は投票部分を修正しました。副次的に、initialValue()がメソッドスコープ内で定義され、その値が囲みスコープに依存する場合、Javaが表示する奇妙な動作に悩まされる可能性があります。私のブログ記事https://rationaleemotions.wordpress.com/2016/05/16/a-date-with-threadlocal/で詳細を読むことができます(あなたのコードが同じものを表示するかどうかはわかりません問題は発生する可能性がありますが、同じ種類のコードがあります) –

0

これを試すことができます。

public class DriverFactory(){ 

private static ThreadLocal<WebDriver> driverThread; 
public WebDriver driver; 

@Parameters("browser") 
public WebDriver instantiateDriverObject(String browser) { 
DriverFactory factory = new DriverFactory(); 
driver = factory.createInstance(browser); //Driver instantiation goes here 
driverThread = new ThreadLocal<WebDriver>() { 
    @Override 
    protected WebDriver initialValue() { 
    webDriverPool.add(driver); 
    return driver; 
    } 
}; 
return driver; 
} 

public WebDriver getDriver() { 
return driverThread.get(); 
} 

}

+0

私は誤ってそれをクリックしてしまった。謝罪いたします。昨日以来、私はそれを修正しようとしていたが運が少ししかなかった。私は今それを修正しました。混乱させて申し訳ありません。 –

関連する問題