有一个广泛的问题,请耐心等待。
我最近继承了一个测试套件(java,selenium,testng),它完全不在它正在测试的产品之外。该套件存在一个主要问题,即测试随着时间的推移而运行(最近一个案例是9小时,应该是90秒的测试案例)。
为了解决这个问题,我一直试图在测试中强制执行超时,但我没有运气。快速概述构建:
我们使用maven构建和测试,
mvn clean test -Dsuite=debug -Dbrowser=firefox -Dmakescreen=NO
并指定要使用xml doc运行的测试套件,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM 'http://testng.org/testng-1.0.dtd'>
<suite name="Test Debugging" verbose="1">
<suite-files>
<suite-file path="suites/DebugTest.xml"/>
</suite-files>
</suite>
DebugTest.xml类似于:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM 'http://testng.org/testng-1.0.dtd'>
<suite name="SUITENAME" verbose="1">
<test name="TESTNAME">
<parameter name="FileName" value="filename.csv" />
<classes>
<class name="tests.testpath" />
</classes>
</test>
</suite>
在更改之前,我已经确认我正在进行的测试在大约10秒内完成并且通过。
每项测试都遵循以下格式:
public class TestName extends BaseTest{
@Override
public void runTest(){
MainPage mainPage = new MainPage();
//test does various things
mainPage.assertCoreElements();
}
您将看到我正在扩展Basetest类并覆盖runtest方法。 BaseTest看起来像:
public abstract class BaseTest extends BaseEntity implements IAnalys {
/**
* To override.
*/
public abstract void runTest();
/**
* Test
*
* @throws Throwable Throwable
*/
@Test
public void xTest(ITestContext ctx) throws Throwable {
System.setProperty("location", "");
Class<? extends BaseTest> currentClass = this.getClass();
String testRailTestId = TestRailOperations.getTestIdByTitleInRun(testRailHostAddress, testRailLogin, testRailPassword, testRailRunId, ctx.getName());
checkJiraIssue(currentClass); //not an jira extended method
checkJiraIssue(currentClass.getMethod("runTest", null)); //not an jira extended method
try {
processBugAnnotation();
logger.logTestName(currentClass.getName());
zephyrExecution();
runTest();
logger.logTestEnd(currentClass.getName());
TestRailOperations.setResultToTest(lastStep, testRailHostAddress, testRailLogin, testRailPassword, testRailTestId, TestRailOperations.TestResult.PASSED, "");
zephyrTestPass();
} catch (Exception | AssertionError e) {
logger.debug(this, e);
if (shouldAnalys()) {
invokeAnalys(e, getBrowser().getDriver().getPageSource());
} else {
TestRailOperations.setResultToTest(lastStep, testRailHostAddress, testRailLogin, testRailPassword, testRailTestId, TestRailOperations.TestResult.FAILED, Logger.fatalMessage);
Logger.fatalMessage = "No info";
zephyrTestFail();
logger.warn("");
logger.warnRed(getLoc("loc.test.failed"));
logger.warn("");
throw e;
}
} finally {
if (Browser.getAnalyzeTraffic()) {
getBrowser().assertAnalyzedTrafficResponseCode();
getBrowser().assertAnalyzedTrafficLoadTime();
ProxyServ.saveToFile(this.getClass().getName());
}
makeScreen(currentClass);
printAllFormAppearingTimes();
clearFormAppearingTimes();
setIsFirstTimeLoadMainPage(true);
}
}
我在父类中也有一个before方法来获取浏览器并将我们移动到起始URL,以及退出浏览器的后续类。
我的目标
我想将这些测试配置为在给定限制下超时(最初为10ms以证明它有效)。
我尝试过的事情
这是我尝试过的第一件事,它起作用了......有问题的测试在正确的时间点确实超时,但它也会产生一个独立于原始测试运行的独立线程。这个线程会打开一个浏览器,然后在不关闭浏览器的情况下终止,在给定的运行后留下数百个打开的窗口我正在处理的任何机器。不太理想!我已经检查了我的课后方法,它显然试图关闭所有浏览器(这里没有成功)。
我的一些阅读表明,正在生成第二个控制线程,而不依赖于前后方法,后者负责挂起窗口。
这并不理想,因为我必须将粘贴复制到套件中的每一个测试中,但无论如何都要试一试。这确实有效,但似乎第二个线程似乎也有问题。如果原始测试及时完成,则会打开第二个浏览器窗口,但是没有任何内容发生,因为它似乎没有触及before方法中的任何代码,然后在断言加载页面时失败。
为了解决上述问题,我遵循了以下文档:https://github.com/junit-team/junit/wiki/Timeout-for-tests
使用两者
完全无效`@Rule public Timeout globalTimeout = Timeout.seconds(10);`
和
`@ClassRule public Timeout globalTimeout = Timeout.seconds(10);`
当我在30秒运行时将时间设置为1秒时,不会导致测试超时。
我还尝试在xml套件中设置超时值:
<suite name="Test Debugging" verbose="1" time-out="200">
即使在最小的时间片上也没有可测量的影响。
此时我真的很茫然 - 我要么需要一种方法来处理用@test注释产生的额外线程,或者我需要弄清楚为什么没有遵循其他方法的指令。
感谢您的帮助,
乔
编辑:为函数前后提供代码
@BeforeClass
public void before() {
Browser browser = getBrowser();
browser.windowMaximise();
long before = new Date().getTime();
browser.navigate(browser.getStartBrowserURL());
long openTimeFirstPage = new Date().getTime() - before;
listFormAppearingTime.add("Main Page=" + String.valueOf(openTimeFirstPage));
SikuliElement allowGeolocationChrome = new SikuliElement("ALLOW_CHROME.png", 5);
SikuliElement allowGeolocationIE = new SikuliElement("ALLOW_IE.png", 5);
if (Browser.currentBrowser.equals(Browsers.CHROME)) {
if (allowGeolocationChrome.isPresent()) {
allowGeolocationChrome.click();
}
}
if (Browser.currentBrowser.equals(Browsers.IEXPLORE)) {
if (allowGeolocationIE.isPresent()) {
allowGeolocationIE.click();
}
}
stepNumber = 1;
if (Browser.getAnalyzeTraffic()) {
browser.startAnalyzeTraffic();
}
if ("true".equalsIgnoreCase(System.getProperty(ZEPHYR_CONNECTION_KEY, "false"))) {
try {
reporter = new ZephyrJiraReporter();
newClass = true;
if (reporter.report()) {
reporter.createTestCycle();
}
} catch (Exception e) {
logger.debug(this, e);
logger.error(e.getMessage());
}
}
}
/**
* Close browser after each test Class
* And update Jira-Zephyr test cycle
*/
@AfterClass
public void after() {
ProxyServ.stopProxyServer();
if (getBrowser().isBrowserAlive()) {
if ("true".equalsIgnoreCase(System.getProperty(ZEPHYR_CONNECTION_KEY, "false"))) {
updateTestCycle();
}
getBrowser().exit();
}
}