我的Selenium测试经常在CI上无限期挂起,总是试图在driver.get
中加载新页面。我正在使用PhantomJS 1.9.8。
经过几轮调试后,我想我已经将问题追溯到PhantomJS中没有完成的网页加载。
Selenium RemoteWebDriver向PhantomJS / GhostDriver发送了一个请求,它正在等待响应。
GhostDriver仍在接受请求。我可以通过点击curl http://localhost:port/session/:sessionId/url
看到它粘在哪个页面上,而且,如果我从命令行(curl -d '{"url": ...}' http://localhost:port/session/:sessionId/url
)重新请求同一页面,那么阻止Selenium请求从它停止的地方神奇地恢复。
UPDATE: Ghostdriver本身并没有挂起 - 但它的默认超时基本上是无限的。如果我指定页面加载超时,例如manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS)
,那么当PhantomJS中出现问题时,GhostDriver将返回错误响应并超时,测试将失败,构建将继续。
如果我调试PhantomJS本身(--debug = TRUE),那么我认为这是故障点日志中的最后一件事
2015-03-21T21:26:39 [DEBUG] WebPage - updateLoadingProgress: 86
(直到超时才达成)
挂起时Java端的堆栈跟踪如下所示:
"Forwarding get on session fd1ac2c0-ccd4-11e4-a596-a1f7b09caa5d to remote" prio=10 tid=0x0000000001f74800 nid=0x5cc3 runnable [0x00002b87c3039000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
at horg.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:316)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:295)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:66)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:276)
at org.openqa.selenium.WebDriver$get.call(Unknown Source)
at geb.Browser.go(Browser.groovy:371)
at geb.Browser$go.call(Unknown Source)
at geb.Page.to(Page.groovy:169)
感觉与此相似,但使用PhantomJS而不是Firefox:
答案 0 :(得分:1)
我希望你能找到一种方法将它实现到你的代码中,但是当我遇到与PhantomJS相似的情况时,这对我有用。
我跟踪它是挂在driver.get()
电话上,对我而言是说某些事情没有通过或者网络驱动程序不是 - 由于某种原因 - 给予将成功的命令加载回驱动程序,允许脚本继续。
所以,我添加了以下内容:
driver = webdriver.PhantomJS()
# set timeout information
driver.set_page_load_timeout(15)
我在5(秒)的时间对此进行了测试,它没有等待足够长的时间也没有发生任何事情。 15秒对我很有用,但这可能是你应该测试的东西。
除此之外,每当webdriver的选项超时时,我也会创建一个循环,以便driver.get()
可以尝试重新发送.get()
命令。实现try / except
堆叠方案,我能够接近这个:
while finished == 0:
try:
driver.get(url3)
finished = 1
except:
sleep(5)
我见过一个除句柄:
except TimeoutException as e:
#Handle your exception here
print(e)
但我对此毫无用处。但是,知道如何捕获特定的异常可能会很好。
有关超时的更多选项,请参阅此解决方案:Setting timeout on selenium webdriver.PhantomJS