Selenium分布式测试和操作监听

前言

在使用selenium进行自动化测试时,测试过程中会不断的打开关闭浏览器,测试时需要单独使用一台设备进行测试。还有就是一台设备的执行效果也不是很高,针对这些问题,来介绍一下Selenium Grid的使用方法。本篇文章介绍使用docker在服务器上部署Selenium Grid。

docker拉取镜像

可以根据自己的需求,拉取不同的浏览器镜像进行测试。

shell 复制代码
docker pull selenium/hub

docker pull selenium/node-chrome

docker pull selenium/node-firefox

docker pull selenium/node-edge

运行Selenium Hub

首先创建网络

shell 复制代码
docker network create grid

运行hub

shell 复制代码
docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:latest
#说明:
#-p 4442-4444:4442-4444   将容器中的端口映射到宿主机对应端口
#-net grid  使用grid网络
#--name selenium-hub  容器名称
#selenium/hub:latest      使用selenium/hub镜像的latest标签版本

运行node节点

shell 复制代码
docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub --shm-size=2g -e SE_EVENT_BUS_PUBLISH_PORT=4442 -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -e SE_NODE_MAX_SESSIONS=3 --name selenium-node-chrome1 selenium/node-chrome:latest
#说明:
#-d   后台运行
#-net grid   使用grid网络
#-e SE_EVENT_BUS_HOST=selenium-hub  事件路径HOST为hub节点
#-e SE_EVENT_BUS_PUBLISH_PORT=4442  事件路径发布端口
#-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443  事件路径订阅端口
#-e SE_NODE_MAX_SESSIONS=3            设置节点最大并发数
#--name selenium-node-chrome1   容器名称
#selenium/node-chrome:latest    使用selenium/node-chrome镜像的latest标签版本

自动化测试脚本中调用

python 复制代码
WebDriver driver = null;
ChromeOptions options = OpenBrowser.openChrome();
driver = new RemoteWebDriver(new URL("http://192.168.1.2:4444/wd/hub"),options);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(2000, TimeUnit.MILLISECONDS);

访问:http://192.168.1.2:4444/ui#

可以看到grid的各个节点

运行脚本时,在Sessions中可以远程观看浏览器运行状态,默认密码:secret

Selenium操作监听

对于UI自动化测试,如果运行测试时,出现接口报错等非常规的问题,无法有效的进行报错的校验和判断,这时候可以通过实现WebDriverEventListener的接口,可以捕获各种事件,例如页面加载、元素点击、输入文本等。

操作监听主要是需要定位一些元素,如页面的接口报错弹窗、引导动画等元素,当操作后出现监听的元素后,对该元素进行操作,避免影响测试主流程或者捕获异常添加到测试结果中。

下面是使用WebDriverEventListener的示例

python 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.EventFiringWebDriver;
import org.openqa.selenium.support.events.WebDriverEventListener;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.autotest.utils.Selenium.saveFailureScreenShot;

publicclass PageListener implements WebDriverEventListener {

privatestaticfinalLogger log = LoggerFactory.getLogger(PageListener.class);

@Override
publicvoidbeforeAlertAccept(WebDriver driver) {
//编写监听 Alert.accept() 操作前的代码
    }

@Override
publicvoidafterAlertAccept(WebDriver driver) {
//编写监听 Alert.accept() 操作后的代码
    }

@Override
publicvoidafterAlertDismiss(WebDriver driver) {
//编写监听 Alert.dismiss() 操作前的代码
    }

@Override
publicvoidbeforeAlertDismiss(WebDriver driver) {
//编写监听 Alert.dismiss() 操作后的代码
    }

@Override
publicvoidbeforeNavigateTo(String url, WebDriver driver) {
//编写监听 navigate().to(String url). 操作前的代码
    }

@Override
publicvoidafterNavigateTo(String url, WebDriver driver) {
//编写监听 navigate().to(String url). 操作后的代码
    }

@Override
publicvoidbeforeNavigateBack(WebDriver driver) {
//编写监听 navigate().back(). 操作前的代码
    }

@Override
publicvoidafterNavigateBack(WebDriver driver) {
//编写监听 navigate().back(). 操作后的代码
    }

@Override
publicvoidbeforeNavigateForward(WebDriver driver) {
//编写监听 navigate().forward(). 操作前的代码
    }

@Override
publicvoidafterNavigateForward(WebDriver driver) {
//编写监听 navigate().forward(). 操作后的代码
    }

@Override
publicvoidbeforeNavigateRefresh(WebDriver driver) {
//编写监听 navigate().refresh(). 操作前的代码
    }

@Override
publicvoidafterNavigateRefresh(WebDriver driver) {
     //编写监听 navigate().refresh(). 操作后的代码
     //此示例是切换窗口后,刷新窗口,监听是否有报错弹窗出现
try {
            WebDriverWait wait = newWebDriverWait(driver, 1);
            WebElement errorPopup = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(s)));
if (errorPopup.isEnabled()) {
             //保存报错图片,返回路径
String addr = saveFailureScreenShot(driver);
//输出到结果文档Excel中
                ExcelData.outExcle(caseName,stepName,"切换窗口后监听页面出现报错弹窗",addr);
                log.info(stepName + ":切换窗口后监听页面出现报错弹窗");
                driver.quit();
            }
        }catch (Exception e) {
            log.info(stepName + ":切换窗口后监听页面没有出现报错弹窗");
        }
    }

@Override
publicvoidbeforeFindBy(By by, WebElement element, WebDriver driver) {
//编写监听 WebDriver.findElement(...), or WebDriver.findElements(...), or WebElement.findElement(...), or WebElement.findElements(...). 操作前的代码
    }

@Override
publicvoidafterFindBy(By by, WebElement element, WebDriver driver) {
//编写监听 WebDriver.findElement(...), or WebDriver.findElements(...), or WebElement.findElement(...), or WebElement.findElements(...). 操作后的代码
    }

@Override
publicvoidbeforeClickOn(WebElement element, WebDriver driver) {
//编写 ebElement.click(). 操作前的代码
    }


@Override
publicvoidafterClickOn(WebElement element, WebDriver driver) {
     //编写 WebElement.click(). 操作后的代码
     //此示例是监听点击后,是否出现报错弹窗
try {
            WebDriverWait wait = newWebDriverWait(driver, 1);
            WebElement errorPopup = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(s)));
if (errorPopup.isEnabled()) {
//保存报错图片,返回路径
String addr = saveFailureScreenShot(driver);
//输出到结果文档Excel中
                ExcelData.outExcle(caseName,stepName,"点击后监听页面出现报错弹窗",addr);
                log.info(stepName + ":点击后监听页面出现报错弹窗");
                driver.quit();
            }
        }catch (Exception e) {
            log.info(stepName + ":点击后监听页面没有出现报错弹窗");
        }
    }

@Override
publicvoidbeforeChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {
//编写 ebElement.clear(), WebElement.sendKeys(...). 操作前的代码
    }

@Override
publicvoidafterChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {
//编写 WebElement.clear(), WebElement.sendKeys(...). 操作后的代码
    }

@Override
publicvoidbeforeScript(String script, WebDriver driver) {
//编写 org.openqa.selenium.remote.RemoteWebDriver.executeScript(String, Object[]) 操作前的代码
    }

@Override
publicvoidafterScript(String script, WebDriver driver) {
//编写 org.openqa.selenium.remote.RemoteWebDriver.executeScript(String, Object[]) 操作后的代码
    }

@Override
publicvoidbeforeSwitchToWindow(String windowName, WebDriver driver) {
//编写 WebDriver.TargetLocator.window(String) 操作前的代码
    }

@Override
publicvoidafterSwitchToWindow(String windowName, WebDriver driver) {
//编写 WebDriver.TargetLocator.window(String) 操作后的代码
    }

@Override
publicvoidonException(Throwable throwable, WebDriver driver) {
//编写抛出异常的操作代码
    }

@Override
public <X> voidbeforeGetScreenshotAs(OutputType<X> target) {
//编写 org.openqa.selenium.TakesScreenshot.getScreenshotAs(OutputType) 操作前的代码
    }

@Override
public <X> voidafterGetScreenshotAs(OutputType<X> target, X screenshot) {
//编写 org.openqa.selenium.TakesScreenshot.getScreenshotAs(OutputType) 操作后的代码
    }

@Override
publicvoidbeforeGetText(WebElement element, WebDriver driver) {
//编写 WebElement.getText() 操作前的代码
    }

@Override
publicvoidafterGetText(WebElement element, WebDriver driver, String text) {
//编写 WebElement.getText() 操作后的代码
    }
  

使用监听时,需要将其注册到WebDriver实例中

WebDriver driver = new ChromeDriver();
EventFiringWebDriver driverWithEvents = new EventFiringWebDriver(driver);
PageListener listener = new PageListener();
driverWithEvents.register(listener);
相关推荐
hankl19901 小时前
spark里使用geohash处理数据之线程安全问题
大数据·分布式·spark
_晓夏_4 小时前
【kafka】kafka如何保证数据的可靠性,kafka如何保证数据不丢失
分布式·kafka·kafka如何保证数据不丢失·kafka如何保证数据的可靠性·kafka的ack确认机制·kafka producer
余为民同志5 小时前
MIT6.824 课程-MapReduce
分布式·mapreduce·6.824
鹏大师运维6 小时前
【信创】麒麟KOS上安装使用网络抓包工具Wireshark
linux·网络·测试工具·wireshark·国产化·麒麟·kylinos2403
懂一点的陈老师6 小时前
redis分布式锁死锁场景
数据库·分布式·死锁
PLM小助手7 小时前
鼎捷新一代PLM 荣膺维科杯 “2023年度行业优秀产品奖”
java·大数据·前端·人工智能·分布式·低代码·微服务
_晓夏_8 小时前
【RabbitMQ】RabbitMQ如何保证数据的可靠性,RabbitMQ如何保证数据不丢失,数据存储
分布式·rabbitmq·rabbitmq数据不丢失·rabbitmq数据可靠性·rabbitmq如何数据存储
cyt涛9 小时前
Canal+RabbitMQ数据同步环境配置
数据库·分布式·mysql·rabbitmq·canal·数据同步·主从同步
weixin_510695559 小时前
如何用静态住宅代理实现分布式代理网络
网络·分布式·php