目录
关注我,学习更多企业开发和面试内容~
异常
搜索塞尔达,并点击塞尔达相关界面的链接。发生了报错。
在确定元素确实存在后,我强制等待3秒,代码反而不报错了。
【出现NoSuchElementException常见的原因及解决方法】
- 第一步:在报错的代码前添加Thread.sleep
- 第二步:在自动化执行的浏览器页面,打开开发者工具,检查元素是否存在。
- 自动化打开的页面不存在该元素:
- 手动打开的元素和自动化打开的页面不一样,很可能是登录状态和未登录状态下页面不一样。
- 元素为动态元素,如下。
![]()
- 【解决办法】id是动态的,但上一级标签不是动态的,先定位上一级标签,然后取子集,代码为:body >
div > section > article。- 自动化打开的元素存在该元素
- 代码执行的速度比页面渲染的速度要快,页面还没渲染出来,程序已经开始执行了,导致元素没有找到。
- 【解决办法】 添加等待。
1. 等待
1.1 强制等待
Thread.sleep(),强制等待主要用于调试。
【优点】 写法简单,好理解,直接阻塞程序。
【缺点】 极大的增加了自动化的执行时间。假设有2000个用例,每个用例都强制等待3秒,那就是一个半多小时。理想的情况下,自动化测试时间为2~3分钟。最长不能超过10分钟。
【案例】
1.2 隐式等待
隐式等待: 是一种智能等待,在查找元素时(调用findElement方法),在指定时间内以轮询方式查找元素。若找到代码则继续执行,直到超时没找到元素才会报错。
implicitlyWait(Duration D),参数为Duration类中提供的毫秒,秒,小时,天都可以。通常等待秒就可以,ofSeconds在英文中的意思为“秒”。
【代码演示】
driver();
webDriver.findElement(By.cssSelector("#kw")).sendKeys("塞尔达");
webDriver.findElement(By.cssSelector("#su")).click();
//隐式等待
webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
webDriver.findElement(By.cssSelector("#\\32 > div > div > div > div:nth-child(1) > div:nth-child(2) > div > div.c-row.c-gap-top-xsmall.video-main-title_S_LlQ > div > a > span")).click();
webDriver.quit();
【注】
- 隐式等待只看元素在不在,而不看对不对,也就是说,findElement后,你是clear也好,还是sendKeys也罢,它不管,这就导致有些操作会出问题,比如代码还没有输入关键字,就已经clear了。
- 隐式等待作用域是它后边的所有代码,但只能查找元素且每次查找元素都要等待。
- 隐式等待不能作用于弹窗上。
【典型案例】
搜索完迪丽热巴,又搜索邓紫棋。显示出来的却是迪丽热巴。 放强制等待也是有讲究的。
解决方法:在查找邓紫棋之前,设置强制等待,给页面留出渲染时间即可。只能设在findElement之前,不能是click这种之前。
1.3 显式等待
显式等待: 是一种智能等待,在指定超时时间范围内只要满足操作的条件,就会执行后续代码。
new WebDriverWait(驱动对象,Duration D).until(条件),参数为ExpectedConditions
//连续写法
new WebDriverWait(webDriver,Duration.ofSeconds(3)).until(ExpectedConditions.elementToBeClickable(By.cssSelector("#su")));
//分开写法
//先保证元素存在
WebDriverWait webDriverWait = new WebDriverWait(webDriver,Duration.ofSeconds(3));
webDriverWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#su")));
//确认存在后,直接进行点击操作
webDriver.findElement(By.cssSelector("#su")).click();
【示例方法】其他方法自己去用。
-
elementToBeClickable(By locator),元素是否可点击。
new WebDriverWait(webDriver,Duration.ofSeconds(3)).until(ExpectedConditions.elementToBeClickable(By.cssSelector("#su")));
-
textToBe(Bylocator,String str),文本精确匹配,是只匹配与该关键词一模一样的词。与之相对的是模糊匹配,只要含该关键词的就会匹配到。
//切换到百度首页 webDriver.get("https://www.baidu.com"); //精确匹配百度首页的"新闻" webDriverWait.until(ExpectedConditions.textToBe(By.cssSelector("#s-top-left > a:nth-child(1)"),"新闻")); //如果写成“新闻2”,就会报错,因为该方法是精确匹配。 webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
【注】
- 只作用于当前条件上,后边想用还得重新写。
- 显式等待和隐式等待不能同时用。
2. 弹窗
弹窗不能通过元素进行定位。
driver对象当前作用于页面上,而弹窗不属于页面,所以需要作用到弹窗上,和前面切换窗口不太一样。处理弹窗后,driver对象会自动切换到页面。
如果不处理弹窗,页面会无法用元素定位。
2.1 弹窗种类
2.2 弹窗操作
-
切换弹窗
//切换弹窗 Alert alert = webDriver.switchTo().alert();
-
点击确认
//点击弹窗的确认按钮 alert.accept();
-
点击取消
alert.dismiss();
-
输入文本信息,输入的文本通过页面是看不到的,但实际输入了。
webDriver.get("file:///D:/%E4%B8%8A%E8%AF%BE%E7%9B%B8%E5%85%B3/selenium4html/Prompt.html"); //调起弹窗 webDriver.findElement(By.cssSelector("body > input[type=button]")).click(); //输入文本 webDriver.switchTo().alert().sendKeys("达达利亚"); //点击确认 webDriver.switchTo().alert().accept();
【代码演示】
//将页面转到弹窗代码界面
webDriver.get("file:///D:/%E4%B8%8A%E8%AF%BE%E7%9B%B8%E5%85%B3/selenium4html/confirm.html");
//调起弹窗
webDriver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(3000);
//点击确认
webDriver.switchTo().alert().accept();
Thread.sleep(3000);
//刷新页面
webDriver.navigate().refresh();
Thread.sleep(3000);
//再调起弹窗
webDriver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(3000);
//再点击取消
webDriver.switchTo().alert().dismiss();
Thread.sleep(3000);
3. 网站
3.1 打开网站
//方式一
webDriver.navigate().to("https://www.baidu.com");
//方式二
webDriver.get("https://www.baidu.com");
3.2 浏览器的前进、后退、刷新
//回退
webDriver.navigate().back();
//前进
webDriver.navigate().forward();
//刷新
webDriver.navigate().refresh();
4. 文件上传
如图所示,上传文件的弹窗是系统的弹窗,不是浏览器的弹窗,Selenium无法控制。但可以用sendKeys指定路径,效果是一样的。
【代码演示】
void test09() throws InterruptedException {
driver();
webDriver.get("file:///D:/%E4%B8%8A%E8%AF%BE%E7%9B%B8%E5%85%B3/selenium4html/upload.html");
WebElement webElement = webDriver.findElement(By.cssSelector("body > div > div > input[type=file]"));
//不能直接点击
// webDriver.findElement(By.cssSelector("body > div > div > input[type=file]")).click();
webElement.sendKeys("D:\\上课相关\\selenium4html");
Thread.sleep(9000);
webDriver.quit();
}
【图示】
5. 浏览器参数设置
5.1 设置无头模式
工作中测试工作基本都是无头模式,代码是运行在云服务器上的。自动化测试不会人工盯着看执行效果,一般设置无头模式,通过自动化执行的结果来分析。
【代码演示】
//允许打开所有网页
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
//设置无头模式
options.addArguments("-headless");
//实例化一个操作对象
webDriver = new ChromeDriver(options);
5.2 设置浏览器加载策略
有种特殊情况需要用该设置。手动打开网页渲染很快,自动化打开的网页渲染却很慢,慢到等待都报错了。
- normal,默认是normal,等所有资源下载完再执行代码。比如,打开一个网页后立刻退出,能看到页面都渲染出来才退出。
- eager,DOM访问已准备就绪,但是图像视频等资源可能还在加载。如果页面没有图片资源啥的,可以用eager。
- none,刚打开页面,一点都没渲染就开始执行代码。比如,打开一个网页,能看到页面都加载出来了。比如,打开一个网页后立刻退出,能看到页面还没渲染就立刻退出了。
【注】不要使用none,一定会报错,想加快自动化运行的速度最多用eager。