2012-02-27 130 views
0

我想在我的網站上測試可能的競爭條件,因此希望兩個testNG測試方法(使用selenium 2.0)在兩個不同的瀏覽器中完全同時執行。我正在使用Eclipse的testNG插件(Indigo)。時機很重要,因爲我想知道當兩次更新同時執行時會發生什麼,以及是否會拋出異常。我試着將testng.xml中的'parallel'屬性設置爲類,測試和方法,但是一個測試總是先於另一個測試,所以它們不同步。另外一個測試可能需要更長的時間來執行(幾毫秒),所以我不確定如何讓時機恰到好處。定時兩個testNG測試方法並行運行並在同一時間運行?

目前我有兩個不同類的測試,因爲這給我最接近我想要的結果。

第1類:

public class SyncTest { 

WebDriver driver; 
WebElement element; 


@BeforeMethod 
public void setUp() throws Exception { 

    driver = new FirefoxDriver(); 

} 


@Test(timeOut = 15000) 
public void testSync() throws Exception { 
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); 
    //Login 
    driver.get("http://mySite.com"); 
    driver.findElement(By.name("username")).sendKeys("admin"); 
    driver.findElement(By.name("password")).sendKeys("admin"); 
    try { 
    element = driver.findElement(By.id("centralLogin_0")); 
    element.click(); 
    } catch (Exception e){ 
     System.out.println("Error submitting: " + e.toString()); 
    } 

    //open issue 
    driver.findElement(By.linkText("Sync Test")).click(); 
    driver.switchTo().frame("mobile_vault"); 
    //Change status 
    Select select = new Select(driver.findElement(By.id("statusSelect"))); 
    //select.deselectAll(); 
    select.selectByVisibleText("Open"); 
    List <WebElement> elements; 
    //driver.findElement(By.className("button nextDialogue")).click(); 
    try { 
    driver.findElement(By.cssSelector("div.button.nextDialogue > div")).click(); 
    } catch (Exception e){ 
     System.out.println("Not found"); 
    } 

    Thread.sleep(2000);  
    try { 
    driver.findElement(By.xpath("//form[@id='frmcall']/fieldset/div[14]/div[2]/div[1]")).click(); 
    } catch (Exception e) { 
     System.out.println("Not Found"); 
     System.out.println(e.toString()); 
    } 

    Thread.sleep(3000); 
    driver.navigate().refresh(); 





} 





@AfterMethod 
public void tearDown() { 
    driver.quit(); 
} 

}

這2類:

public class NewSyncTest { 

WebDriver driver; 
WebElement element; 

    @Test 
    public void testF() throws Exception { 

     driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); 

    //Login 
    driver.get("http://mySite.com"); 
    driver.findElement(By.name("username")).sendKeys("admin"); 
    driver.findElement(By.name("password")).sendKeys("admin"); 

    try { 
    element = driver.findElement(By.id("centralLogin_0")); 
    element.click(); 
    } catch (Exception e){ 
     System.out.println("Error submitting: " + e.toString()); 
    } 


    //open admin page 
    driver.get("http://mySite.com/admin"); 

    Thread.sleep(2000); 



try { 

    driver.findElement(By.cssSelector("input[type='submit']")).click(); 

} catch (Exception e){ 
     System.out.println("Not found"); 
    } 



    } 
    @BeforeMethod 
    public void beforeMethod() { 

    driver = new FirefoxDriver(); 
    } 

    @AfterMethod 
    public void afterMethod() { 

    driver.quit(); 
    } 

} 

我意識到我的使用TestNG的註釋可能是不正確的,我不知道這將是最好(@BeforeSuite,@BeforeMethod等)

我的testng.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> 
<suite name="Suite" parallel="classes"> 
<test name="Test" preserve-order="false"> 
<classes> 
    <class name="syncTest.SyncTest"/> 
    <class name = "syncTest.NewSyncTest"/> 


</classes> 
</test> 
</suite> 

就像我說的測試從未正好並行運行,我不知道如何做到這一點:(我還將包括以下TestNG的-results.xml,注意每個測試方法的時間:

<test name="Test" duration-ms="20264" started-at="2012-02-27T15:52:02Z" finished- at="2012-02-27T15:52:23Z"> 
    <class name="syncTest.SyncTest"> 
    <test-method status="PASS" signature="setUp()[pri:0, instance:[email protected]]" name="setUp" is-config="true" duration-ms="8475" started-at="2012-02-27T15:52:02Z" finished-at="2012-02-27T15:52:11Z"> 
    </test-method> 
    <test-method status="PASS" signature="testSync()[pri:0, instance:[email protected]]" name="testSync" duration-ms="11556" started-at="2012-02-27T15:52:11Z" finished-at="2012-02-27T15:52:22Z"> 
    </test-method> 
    <test-method status="PASS" signature="tearDown()[pri:0, instance:[email protected]]" name="tearDown" is-config="true" duration-ms="217" started-at="2012-02-27T15:52:22Z" finished-at="2012-02-27T15:52:23Z"> 
    </test-method> 
    </class> 
    <class name="syncTest.NewSyncTest"> 
    <test-method status="PASS" signature="beforeMethod()[pri:0, instance:[email protected]]" name="beforeMethod" is-config="true" duration-ms="4345" started-at="2012-02-27T15:52:02Z" finished-at="2012-02-27T15:52:07Z"> 
    </test-method> 
    <test-method status="PASS" signature="testF()[pri:0, instance:[email protected]]" name="testF" duration-ms="9728" started-at="2012-02-27T15:52:07Z" finished-at="2012-02-27T15:52:16Z"> 
    </test-method> 
    <test-method status="PASS" signature="afterMethod()[pri:0, instance:[email protected]]" name="afterMethod" is-config="true" duration-ms="231" started-at="2012-02-27T15:52:16Z" finished-at="2012-02-27T15:52:17Z"> 
    </test-method> 
    </class> 
</test> 

任何和所有的建議,歡迎。提前致謝! :)

+0

感謝您的答案!高性能標誌,我明白你的觀點。我將解釋我想要測試的內容:我在數據庫中有一組數據,並且有兩個視圖(中央和客戶端)。這兩個觀點顯然需要同步。其中一個(由用戶)所做的更改反映在另一箇中。我上面的第一個測試用例編輯了一個表單,用戶可以點擊提交。第二個調用web動作,檢查所有項目的編輯並將其保存到數據庫。如果用戶進行編輯並且同時進行此項檢查,那麼編輯是否會丟失?編輯將不會被支票看到? – user1088166 2012-02-28 10:56:01

+0

您試圖解釋的這種情況看起來像[幻像讀取](http://en.wikipedia.org/wiki/Isolation_(database_systems)#Phantom_reads)情況。它可以很容易地用鎖來克服。有關更多信息,請參閱[this](http://docstore.mik.ua/orelly/java-ent/ebeans/ch08_03.htm)。 – Bala 2012-03-01 08:18:59

+0

另外,在單元測試環境中重現這種情況非常困難,該環境通常處理小型測試(不管何時併發)。 – Bala 2012-03-01 08:20:41

回答

1

試圖通過在'完全同一時間'發生兩次訪問來測試競賽條件可能是徒勞的練習,也沒有用。無用的,因爲你永遠不會實現它,沒用,因爲數據競賽不會在'完全同時'出現訪問時出現,但當原子操作(通常是讀和寫)交錯時,共享變量的視圖這兩個過程得到的是不一致的。

如果你有2個進程,每個進行讀寫操作,然後寫入/來自同一個變量,請考慮代替4個原子操作可能發生的所有方式(R1 - 進程1讀取等) :

R1,W1,R2,W2 
R1,R2,W2,W1 

重寫你的測試,這樣你可以控制每一個進程R和W之間的間隔,使這些間隔足夠長的時間來控制原子操作的交織,並檢查你的程序對應。

1

正如高性能標記所指出的那樣,對於競態條件的測試不能確定。另一方面,如果你想測試一個並行執行的多個線程的測試方法,那麼你可以嘗試如下所示。

public class ConcurrentTestRunnerTest { 

    @Test(threadPoolSize = 3, invocationCount = 10,  timeOut = 10000) 
    public void shouldRunInParallel1() { 
     System.out.println("I'm running on thread " + Thread.currentThread().getName()); 
    } 

    @Test(threadPoolSize = 3, invocationCount = 10,  timeOut = 10000) 
    public void shouldRunInParallel2() { 
     System.out.println("I'm running on thread " + Thread.currentThread().getName()); 
    } 

} 

這將確保您擁有並行執行的配置線程數量。

IMO,你應該能夠使用一些性能測試工具,如JMeter,實現這樣的結果。剛纔提到這是因爲你使用硒。