0

对于我们的BDD测试,我们使用Specflow与selenium 2 webdriver(本例中的Chrome驱动程序)交谈。Selenium2 - 在CI上运行测试会导致多个驱动程序实例

在本地主机上运行(是的,“它在我的机器上运行”在对话中出现了几次),测试正常工作。他们设置数据和一个新的webdriver,做测试,然后拆卸webdriver和数据。即使测试出现可怕的错误,因为我使用了正确的属性,拆卸总是会被打开,因此driver.Quit()正在运行,从而破坏了浏览器和驱动程序。

使用我们的持续集成[TeamCity]在我们的服务器[Windows Server 2008 r2]上运行它时,出现问题。出于某种原因,它将开始运行多个驱动程序实例,这会导致测试失败。

有没有人遇到过这个问题,并找到解决办法?我们需要一个使用驱动程序的解决方案,该驱动程序不是不是HtmlUnitDriver

额外信息:

  • 语言= C#
  • 服务器=的Windows Server 2008 R2
  • CI = TeamCity的

编辑: 的webdriver的是确保它成立尚未创建,然后创建ChromeDriver的新实例。下面的伪代码/实际代码示例显示了它的设置方式,对不起,我无法显示完整的代码,因为我们使用其他选项(例如zap或fiddler集成/语言更改等)来使用它。

设置

[SetUp] 
[BeforeScenario()] 
public static void BeforeWebScenario() 
{ 
    if driver == null 
    driver = new ChromeDriver(); 
    // Code to start page 
} 

推倒

[TearDown] 
[AfterScenario()] 
public static void AfterWebScenario() 
{ 
    try 
    { 
     driver.Quit(); 
    } catch (Exception) 
    { 
     throw Exception 
    } 
    driver = null; 
} 
+0

你可以给一个样本测试,再现这个? – Arran

+0

有两个问题:首先,您如何使用ChromeDriver或RemoteWebDriver启动驱动程序?其次,测试驱动程序的典型构造函数是什么样的? – JimEvans

+0

嗨,感谢您的兴趣,它很难给出一个示例测试,因为他们使用我创建并操作页面对象模型(有很多抽象)的框架。我将编辑帖子以显示如何设置驱动程序。 – Ankou

回答

1

我也有这个问题。我通过在我的testSetup()方法中杀死任何正在运行的chromedriver.exe实例来修复它。我使用了VBScript和一些Groovy代码来运行脚本。对不起,这个答案有点长。

我在我的设置有这个):

if (wshsc.isRunningByCommandLineContents("chromedriver.exe")) 
    wshsc.killProcessByCommandLineContents("chromedriver.exe") 

isRunningByCommandLineContents:

If WScript.Arguments.Count = 1 Then 

strCmdLine = WScript.Arguments.Item(0) 
On Error Resume Next 
strComputer = "." 
Set objWMIService = GetObject("winmgmts:" _ 
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set objShell = CreateObject("WScript.Shell") 
Set colProcessList = objWMIService.ExecQuery _ 
    ("Select * from Win32_Process") 
If colProcessList.Count > 0 Then 
    For Each objItem in colProcessList 
     If (InStr(objItem.CommandLine, strCmdLine)) Then 
      If (InStr(objItem.CommandLine, "cscript")) Then 
      Else 
       WScript.StdOut.Write "A process is running with " + strCmdLine + " in its command line = " + objItem.Name 
      End If 
     End If 
    Next 
End If 
End If 

killProcessByCommandLineContents:

If WScript.Arguments.Count = 1 Then 
strProcess = WScript.Arguments.Item(0) 
On Error Resume Next 
strComputer = "." 
Set objWMIService = GetObject("winmgmts:" _ 
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set objShell = CreateObject("WScript.Shell") 
Set colProcessList = objWMIService.ExecQuery _ 
    ("Select * from Win32_Process") 

If colProcessList.Count > 0 Then 
    For Each objItem in colProcessList 
     If InStr(objItem.CommandLine, strProcess) Then 
      If (InStr(objItem.CommandLine, "cscript")) Then 
      Else 
       WScript.StdOut.Write objItem.Name + " " 
       objItem.Terminate() 
      End If 
     End If 
    Next 
Else 
    WScript.StdOut.Write "No instances found running" 
End If 
Else 
WScript.StdOut.Write "Bad Arguments" 
End If 

与 “运行脚本的一部分”:

public void killProcessByCommandLineContents(String contents) { 
    List<String> arg = new ArrayList<String>() 
    arg.add(contents) 
    String [] args = arg.toArray() 
    runScript("killByCmdLineContents.vbs", args, true) 
} 
public boolean isRunningByCommandLineContents(String contents) { 
    List<String> arg = new ArrayList<String>() 
    arg.add(contents) 
    String [] args = arg.toArray() 
    String returnData = runScript("IsRunningByCmdLineContents.vbs", args, true) 
    if (returnData.contains(contents)) { 
     return true 
    } else { 
     return false 
    } 
} 
public String runScript(String name, String [] args, boolean returnOutput) { 
    String s = null; 
    List<String> cmdLine = new ArrayList<String>() 
    cmdLine.add("C://Windows//System32//cscript.exe") 
    cmdLine.add(dir + "dir//src//com//misc//wshScripts//" + name) 
    int index = 0 
    args.each() { 
     cmdLine.add(args[index]) 
     index++ 
    } 

    try { 
     String [] cmdLineArray = cmdLine.toArray() 
     Process p = Runtime.getRuntime().exec(cmdLineArray, null); 
     if (returnOutput) { 
      BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 
      BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
      String dataToReturn 
      Log.logger.info("Standard output: "); 
      while ((s = stdInput.readLine()) != null) { 
       Log.logger.info(s) 
       dataToReturn = s // should get last line 
      } 

      Log.logger.info("Standard error: "); 
      while ((s = stdError.readLine()) != null) {Log.logger.info(s);} 
      return dataToReturn 
     } else { 
      return "" 
     } 
    } 
    catch (IOException e) { 
     Log.logger.info(e.message, e); 
    } 
} 
+0

谢谢,这似乎可以解决问题,至少直到我找出为什么它创建它们开始。今晚我会运行我们的夜间训练,并在明天与结果联系。谢谢 – Ankou

+0

谢谢,这帮助我确定了真正的问题(我也把它作为一个很好的整理)。 我在构建服务器上收到“OpenQA.Selenium.WebDriverException:服务器对URL没有响应”。当我看着这个时候,似乎任何时候在使用'.FindElement(obj)'之后,你应该做一个'Thread.Sleep(200)',因为如果调用了太多的find,就会出现某种竞争状态。 – Ankou

+0

很酷。很高兴知道。我从来没有想过这一点。 – chrismead

0

如果您使用DriverService接口,请坚持使用该服务,直到完成驱动程序并调用DriverService.stop()为止。对我来说,driver.quit()还不够,因为我也使用DriverService。

driver.close(); 
driver.quit(); 
driverService.stop(); 
相关问题