webDriver 測(cè)試的時(shí)候頭疼的是調(diào)試。但也遠(yuǎn)不及運(yùn)行的時(shí)候出錯(cuò),再回頭調(diào)試來(lái)的痛苦?偹苤, web 自動(dòng)化的代碼都非常脆弱,一份代碼一會(huì)運(yùn)行失敗,一會(huì)運(yùn)行成功也是很正常的事情?偟膩(lái)說(shuō)造成案例運(yùn)行失敗的原因大抵有兩點(diǎn):
環(huán)境問(wèn)題: 比如網(wǎng)絡(luò)不穩(wěn)定啊
代碼變動(dòng): 比如某個(gè)元素不在
遇到 bug :這是真的發(fā)現(xiàn) bug 了
無(wú)論哪一種,遇到了都需要花一番時(shí)間去 debug。那如果這個(gè)時(shí)候有一張運(yùn)行時(shí)候出錯(cuò)的截圖,那一目了然了。(即便不一目了然,也有很多幫助)
在運(yùn)行出錯(cuò)的時(shí)候,捕獲錯(cuò)誤并截圖有兩種思路:
自定義一個(gè) WeDdriver 的監(jiān)聽(tīng)器,在出異常的時(shí)候截圖。
利用 Juint 的 TestRule, 自定義一個(gè) Rule 在運(yùn)行失敗的時(shí)候截圖。
自定義監(jiān)聽(tīng)器
截圖的原理
截圖需要用到 RemoteWebDriver。在 Selenium 官方我們可以找到:
One nice feature of the remote
webdriver is that exceptions often
have an attached screen shot, encoded
as a Base64 PNG. In order to get this
screenshot, you need to write code
similar to:
public String extractScreenShot(WebDriverException e) {
Throwable cause = e.getCause();
if (cause instanceof ScreenshotException) {
return ((ScreenshotException) cause).getBase64EncodedScreenshot();
}
return null;
}
意思是說(shuō),每個(gè)異常都是 ScreenshotException 的對(duì)象,轉(zhuǎn)碼一下可以用了。這是截圖的本質(zhì)。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.internal.Base64Encoder;
import org.openqa.selenium.remote.ScreenshotException;
import org.openqa.selenium.support.events.AbstractWebDriverEventListener;
/**
* This is an customized webdriver event listener.
* Now it implements onException method: webdriver will take a screenshot
* when it meets an exception. It's good but not so usable. And when we use
* WebDriverWait to wait for an element appearing, the webdriver will throw
* exception always and the onException will be excuted again and again, which
* generates a lot of screenshots.
* Put here for study
* Usage:
* WebDriver driver = new FirefoxDriver();
* WebDriverEventListener listener = new CustomWebDriverEventListener();
* return new EventFiringWebDriver(driver).register(listener);
*
* @author qa
*
*/
public class CustomWebDriverEventListener extends
AbstractWebDriverEventListener {
@Override
public void onException(Throwable throwable, WebDriver driver) {
Throwable cause = throwable.getCause();
if (cause instanceof ScreenshotException) {
SimpleDateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd-hh-mm-ss");
String dateString = formatter.format(new Date());
File of = new File(dateString + "-exception.png");
FileOutputStream out = null;