我正在尝试在我的网站上测试可能的竞争条件,因此需要两个testNG测试方法(使用selenium 2.0)在两个不同的浏览器中完全同时执行。我正在使用Eclipse(Indigo)的testNG插件。时机很重要,因为我想看看当两个更新同时执行时会发生什么,以及它是否会抛出异常。我已经尝试将testng.xml中的'parallel'属性设置为类,测试和方法,但是一个测试总是先于另一个测试,因此它们不同步。另外一个测试可能需要更长的时间才能执行(几毫秒),因此我不确定如何使时间恰到好处。
目前我在两个不同的班级进行测试,因为这给了我最接近我想要的结果。
第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:syncTest.SyncTest@3e9d75c5]" 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:syncTest.SyncTest@3e9d75c5]" 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:syncTest.SyncTest@3e9d75c5]" 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:syncTest.NewSyncTest@539ef8a0]" 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:syncTest.NewSyncTest@539ef8a0]" 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:syncTest.NewSyncTest@539ef8a0]" 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 :(得分:1)
尝试通过在“完全相同的时间”进行两次访问来测试竞争条件可能是徒劳的,并且也没有用。无用是因为你永远无法实现它,因为当访问在“完全相同的时间”发生但是当原子操作(通常是读和写)以共享变量的视图交错时不会出现数据竞争是徒劳的两个进程得到的结果不一致。
如果你有2个进程,比如说,读取后跟同一个变量的写入,请考虑而不是4个原子操作可以发生的所有方式(R1 - 进程1读取等):
R1,W1,R2,W2
R1,R2,W2,W1
等
重写测试,以便您可以控制每个进程的R和W之间的间隔,使这些间隔足够长以控制原子操作的交错,并检查您的程序是否应对。
答案 1 :(得分: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等一些性能测试工具来实现这样的结果。刚提到这是因为你使用的是硒。