当前位置: 首页 > news >正文

selenium学习笔记(二)

文章目录

  • 前言
  • 设计模式POM
    • POM概念
    • POM优势
    • POM设计原则
    • POM的实现
  • selenium的常用操作
    • 处理动态元素
    • 截图操作
    • 勾选复选框
    • 多层框架/窗口定位
    • 操作下拉框
    • 上传文件操作
    • 处理弹窗
    • 切换窗口
    • 拖拽操作
  • 如何处理浏览器驱动更新导致的问题
  • selenium与网站监控
    • 监听网页内容变化
    • 监控网络请求
  • selenium 与性能测试
    • 代码示例
    • 常见的性能指标
  • selenium与TestNG
  • 常见面试题
    • 原理相关
    • 定位元素相关
    • 操作相关
    • 脚本稳定与优化类相关

前言

1、该文是为了做个笔记,在需要的时候可以方便查找,侵权可删
2、文中的代码均为java
3、回顾前文 selenium学习笔记(一)

设计模式POM

Page Object Model (POM)
将页面分解成独立的对象,每个对象代表一个页面或页面的一部分,有助于组织测试代码和提高可维护性

POM概念

页面对象模型是一种设计模式,它提倡将UI元素抽象成对象,并围绕这些对象组织测试代码。这一模式不仅提升了测试脚本的可读性和可维护性,还促进了代码的重用

POM优势

  • 分离关注点:将测试逻辑与页面元素分离,使测试脚本更加清晰。
  • 易于维护:页面变化时,只需修改对应的页面对象类,无需改动所有测试案例。
  • 代码复用:页面对象可以在多个测试案例中重复使用,减少冗余代码。
  • 提高可读性:通过将操作封装成方法,使得测试代码更加易于理解。
  • 提高可维护性:减少测试脚本对页面结构变化的敏感度,提高测试代码的可维护性

POM设计原则

  • 抽象每一个页面:为每个页面创建一个对应的页面对象类。
  • 页面中元素不暴露:仅暴露操作元素的方法,隐藏元素的具体定位细节。
  • 页面不应该有繁琐的继承关系:避免页面对象之间的复杂继承结构。
  • 页面中不是所有元素都需要涉及到:只对核心业务元素进行建模。
  • 把页面划分功能模块:在Page中实现这些功能方法

POM的实现

  • 创建页面类:为每个页面创建一个类,该类包含页面的所有元素定位器和操作方法。
  • 封装元素操作:在页面类中封装对元素的所有操作,如点击、输入文本等。
  • 使用Page Factory:Selenium提供了Page Factory模式,可以进一步简化页面对象的创建和管理

selenium的常用操作

处理动态元素

使用显式等待 和 隐式等待来处理动态元素

  • 1、使用WebDriverWait和Expected Conditions

    动态元素往往是在页面加载完成后通过JavaScript动态生成的。使用WebDriverWait结合Expected Conditions可以等待元素在页面上可见或可点击后再进行操作

    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("dynamicElement")));
    
  • 2、根据部分属性值定位

    如果元素的ID或class是动态生成的,可以使用XPath中的contains()、starts-with()和ends-with()函数来根据部分属性值定位元素
    // 这样可以匹配ID中包含"auto-id"的元素,即使ID是动态生成的
    driver.findElement(By.xpath(“//div[contains(@id, ‘auto-id’)]”));

  • 3、根据相对关系定位

    如果动态元素与其附近的父节点、子节点或兄弟节点有固定的相对关系,可以根据这些固定元素来定位动态元素

  • 4、根据DOM顺序index定位

    找到元素在DOM中的顺序索引,然后根据索引进行定位。这种方法可能不够稳定,如果可以,还是推荐使用其他方法

  • 5、使用CSS选择器

    CSS选择器提供了一种灵活的方式来定位元素,尤其是当元素的ID或class是动态生成时。例如,可以使用CSS属性选择器来定位元素
    driver.findElement(By.cssSelector(“input[type=‘text’]”));

  • 6、结合使用多种定位方法

    在某些情况下,可以结合使用多种定位方法来提高定位的准确性和成功率。例如,可以先通过CSS选择器定位到一个父元素,然后再通过相对路径定位到其子元素

  • 7、优化等待时间

    动态元素的加载可能需要时间,因此合理设置等待时间是提高脚本稳定性的关键。避免使用硬编码的等待时间(如Thread.sleep),而是使用WebDriverWait来动态等待元素加载完成

截图操作

需要导入依赖包,如Commons IO,进行截图操作

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.8.0</version>
</dependency>
//浏览器截图private static void test11() throws InterruptedException, IOException {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#su")).click();sleep(3000);//强制转换进行截图以文件形式存储File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File("d://测试.png"));}

勾选复选框

private static void page01() {// 创建一个浏览器驱动WebDriver webDriver = new ChromeDriver();// 打开网页webDriver.get("http://localhost:63342/Test/src/main/page/teste01.html?_ijt=bbsd02k86b9564t8p03vfmeff1&_ij_reload=RELOAD_ON_SAVE");// 获取到所有的input标签对应的元素List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));// 判断每一个input标签里面type值是checkbox进行点击,否则不点击for(int i = 0; i < webElements.size(); i++) {if(webElements.get(i).getAttribute("type").equals("checkbox")) {webElements.get(i).click();} }}

多层框架/窗口定位

对于一个web 应用,经常会出现框架(iframe) 或窗口(window)的应用,这样如果我们定位元素就不能直接右击copy他的xpath或者是cssselector来定位;但是可以通过switchTo()方法定位到frame下或者window下,然后通过元素css选择器或者xpath定位

 private static void page02() {// 创建浏览器驱动WebDriver webDriver = new ChromeDriver();// 打开网页webDriver.get("http://www.xxx.com");// 需要先定位到frame下再定位到clickwebDriver.switchTo().frame("f1");webDriver.findElement(By.cssSelector("body > div > div > a")).click();// 目标元素不在iframe,可以直接获取
//        String h3_text = webDriver.findElement(By.cssSelector("body > div > div > h3")).getText();
//        System.out.println(h3_text);}

操作下拉框

下拉框里的内容需要进行两次定位,先定位到下拉框对下拉框进行操作后,再定位到下拉框内里的选项

 private static void page03() {// 创建浏览器驱动WebDriver webDriver = new ChromeDriver();// 打开网页webDriver.get("http://url地址");// 操作下拉框Select select = new Select(webDriver.findElement(By.cssSelector("#ShippingMethod")));
//        select.selectByValue("12.51");select.selectByIndex(2);}

上传文件操作

在selenium webdriver 只要定位上传按钮,通过sendKeys 添加本地文件路径就可以了。
绝对路径和相对路径都可以,关键是上传的文件存在

 private static void page05() {WebDriver webDriver = new ChromeDriver();webDriver.get("http://url地址");// 找到按钮(上传文件的按钮),输入一个字符串webDriver.findElement(By.cssSelector("input")).sendKeys("C:\Users\34085\Desktop\hello.txt");}

处理弹窗

使用Alert类来处理弹窗:
1.text 返回alert 中的文字信息。
2.accept 点击确认按钮。
3.dismiss 点击取消按钮,如果有的话。
4.sendKeys 输入值,如果alert 没有对话框就不能用了,不然会报错。

private static void page04() throws InterruptedException {WebDriver webDriver = new ChromeDriver();webDriver.get("http://url地址");webDriver.findElement(By.cssSelector("button")).click();// alert弹窗确定
//        webDriver.switchTo().alert().accept();// alert弹窗取消
//        webDriver.switchTo().alert().dismiss();webDriver.switchTo().alert().sendKeys("你好");webDriver.switchTo().alert().accept();}

切换窗口

获取当前窗口句柄并切换到新窗口

// 进入百度页面然后点击新闻进入新闻页面,此时如果我们需要在新闻页面输入相关内容,是不能直接通过选择器定位实现的
// 我们需要先实现页面切换才能在新闻页面搜索内容
//浏览器切换窗口private static void test10() throws InterruptedException {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");//点击新闻页面,在新闻面输入相关信息webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();//getWindowHandles获得所有窗口句柄//getWindowHandle获取get打开的窗口句柄// 获取到浏览器所有的窗口句柄Set<String> handles = webDriver.getWindowHandles();//遍历所有的窗口句柄String target_handle = "";for(String handle:handles) {//赋值target_handle = handle;}//System.out.println(target_handle);//在新闻页面搜索新闻联播webDriver.switchTo().window(target_handle);sleep(3000);webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");webDriver.findElement(By.cssSelector("#s_btn_wr")).click();}

拖拽操作

使用Actions类进行复杂的鼠标操作,如拖拽

from selenium.webdriver.common.action_chains import ActionChains
private static void test() {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.URL地址/");element_to_drag = driver.find_element_by_id("source");target_element = driver.find_element_by_id("target");// 方法一:直接将源元素拖拽到目标元素上actionsA = ActionChains(driver);actionsA.drag_and_drop(element_to_drag, target_element).perform();// 方法二:模拟了更细致的拖拽过程,包括按住源元素(click_and_hold)、移动到目标元素位置(move_to_element)、然后释放(release)actionsB = ActionChains(driver)actionsB.click_and_hold(element_to_drag).move_to_element(target_element).release().perform()}

如何处理浏览器驱动更新导致的问题

  • 1、确保webdriver与浏览器版本匹配
  • 2、手动下载WebDriver并使用Selenium的Service类来加载。这样可以控制WebDriver的版本,避免自动更新带来的问题
  • 3、在代码中添加异常处理逻辑,捕获TimeoutException并提供相应的错误信息和日志,以便进行问题定位和调试
  • 4、定期更新selenium和webdriver
  • 5、避免浏览器自动更新
  • 6、在测试开始之前,确保浏览器是干净的,没有被其他扩展或插件干扰。如果浏览器崩溃或被关闭,可以考虑重启浏览器并重新运行测试

selenium与网站监控

监听网页内容变化

通过定期检查网页上特定元素的内容,可以监控网页内容的变化。例如,可以监控商品价格、库存状态或新闻更新等

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
// 这段代码会在指定的网页上查找价格元素,并检测其内容的变化。如果价格发生变化,它会输出新的价格。
// 我们可以结合邮件报警+定时任务,当价格有变动时,可以发送邮件
public class PriceWatcher {public static void main(String[] args) throws InterruptedException {System.setProperty("webdriver.chrome.driver", "chromedriver的地址");WebDriver driver = new ChromeDriver();driver.get("http://url地址");String previousPrice = "";while (true) {WebElement priceElement = driver.findElement(By.id("price")); // 假设价格的ID是"price"String currentPrice = priceElement.getText();if (!currentPrice.equals(previousPrice)) {System.out.println("价格变动: " + currentPrice);previousPrice = currentPrice;}Thread.sleep(5000); // 每5秒检查一次}}
}

补充:如果是监控价格:
(1)可以将每次检查的价格存储到CSV文件或数据库中,以便进行历史价格分析。这可以通过在上述代码中添加文件写入逻辑来实现;
(2)发送通知,如集成邮件报警;
(3)添加异常处理

监控网络请求

Selenium可以结合BrowserMob Proxy或其他工具来监控网络请求。BrowserMob Proxy是一个开源的代理服务器,可以捕获HTTP请求和响应

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.List;
// 这段代码通过BrowserMob Proxy捕获了浏览器的所有HTTP请求和响应,并打印了请求的URL和响应状态。
// 通过这些方法,Selenium不仅可以用于自动化测试,还可以用于网站监控,帮助开发者和测试人员及时发现和响应网站的变化。
public class MonitorHttpRequests {public static void main(String[] args) {// 启动BrowserMob ProxyBrowserMobProxy proxy = new BrowserMobProxyServer();proxy.start(0);// 获取代理的地址Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);// 设置WebDriver的代理ChromeOptions options = new ChromeOptions();options.setProxy(seleniumProxy);WebDriver driver = new ChromeDriver(options);// 启动请求捕获proxy.newHar("myHar");// 导航到网页driver.get("http://url地址");// 获取请求数据List<HarEntry> entries = proxy.getHar().getLog().getEntries();for (HarEntry entry : entries) {System.out.println("请求网址: " + entry.getRequest().getUrl());System.out.println("响应状态: " + entry.getResponse().getStatus());}// 关闭WebDriver与Proxydriver.quit();proxy.stop();}
}

selenium 与性能测试

代码示例

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
// 配置性能日志记录
public class PerformanceTestSetup {public static void main(String[] args) {// 设置ChromeDriver路径System.setProperty("webdriver.chrome.driver", "chromedriver路径");// 创建ChromeOptions对象ChromeOptions options = new ChromeOptions();// 启用性能日志记录options.setCapability("perfLoggingPrefs", "{\"enableNetwork\": true, \"enablePage\": true}");// 将配置应用于WebDriver对象WebDriver driver = new ChromeDriver(options);// 打开网页driver.get("http://example.com");// 执行操作// 关闭浏览器driver.quit();}
}
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
// 获取并分析性能日志
public class PerformanceLogging {public static void main(String[] args) {// 设置WebDriver路径System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");// 设置Chrome选项ChromeOptions options = new ChromeOptions();options.addArguments("--auto-open-devtools-for-tabs");// 创建WebDriver实例WebDriver driver = new ChromeDriver(options);// 获取DevTools实例。 注意:以下代码需要Selenium 4及以上版本org.openqa.selenium.devtools.DevTools devTools = ((ChromeDriver) driver).getDevTools();devTools.createSession();// 启动性能监控devTools.send(org.openqa.selenium.devtools.v93.performance.Performance.enable());// 访问目标页面driver.get("http://example.com");// 获取性能指标LogEntries entries = driver.manage().logs().get(org.openqa.selenium.logging.LogType.PERFORMANCE);for (LogEntry entry : entries) {System.out.println(entry.getMessage());}// 关闭驱动driver.quit();}
}

常见的性能指标

  • 响应时间(Response Time):客户端发送请求到接收到服务器响应的时间
  • 吞吐量(Throughput):指系统在单位时间内能处理的事务或请求的数量。高吞吐量表明系统能够处理大量的请求
  • 并发用户数(Concurrent Users):指系统能同时支持的最大用户数量( 这个指标对于理解系统在高负载下的表现非常重要)
  • 事务处理速率(Transaction Rate):系统在单位时间内能完成的事务数量。事务可以是任何用户操作,如登录、查询、更新等
  • 资源利用率(Resource Utilization):系统资源(如CPU/内存/磁盘I/O/网络带宽)的使用情况。高资源利用率可能表明性能瓶颈
  • 错误率(Error Rate):指在一定时间内失败的事务或请求所占的比例。低错误率是系统稳定性的重要指标
  • 页面加载时间(Page Load Time):对于Web应用,指从用户点击链接或输入网址到页面完全加载完成所需的时间
  • 首次内容绘制(Time to First Contentful Paint, TTFCP):指页面开始加载到首次内容(如文本或图像)被渲染到屏幕上的时间
  • 最大内容绘制(Time to Largest Contentful Paint, LTCP):指页面开始加载到最大文本块或图像被渲染到屏幕上的时间
  • 交互时间(Time to Interactive, TTI):指页面加载到主要子资源加载完成,且页面能够快速响应用户输入的时间
  • 总页面加载时间(Total Page Load Time):从用户开始导航到页面完全加载完成的时间
  • 服务器响应时间(Server Response Time):服务器处理请求并返回响应所需的时间
  • 网络时间(Network Time):数据在网络中传输的时间,包括请求和响应的往返时间
  • 数据库响应时间(Database Response Time):数据库处理请求并返回结果所需的时间
  • 系统稳定性(System Stability):在长时间运行或高负载下,系统是否能够保持性能和不出现故障
  • 可扩展性(Scalability):系统在增加负载时,性能如何变化,以及是否能够通过增加资源来提高性能

selenium与TestNG

TestNG是一个测试框架,它支持各种测试场景,包括单元测试、集成测试、端到端测试等

  • 1、添加依赖

    <!-- Selenium -->
    <dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version>
    </dependency><!-- TestNG -->
    <dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>7.4.0</version><scope>test</scope>
    </dependency>
    
  • 2、创建测试类,并使用TestNG的注解来定义测试方法和测试套件

    import org.testng.annotations.AfterMethod;
    import org.testng.annotations.BeforeMethod;
    import org.testng.annotations.Test;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    public class SeleniumTestNGExample {private WebDriver driver;@BeforeMethodpublic void setUp() {// 设置WebDriver路径System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");// 初始化WebDriverdriver = new ChromeDriver();}@Testpublic void testGoogleSearch() {// 打开Google首页driver.get("https://www.baidu.com");// 执行测试逻辑}@AfterMethodpublic void tearDown() {// 关闭浏览器driver.quit();}
    }
    
  • 3、运行测试

    在命令行中运行:testng path/to/your/test-class/SeleniumTestNGExample.java

  • 4、TestNG的高级功能

    (1)@BeforeSuite 和 @AfterSuite:在测试套件开始前和结束后执行。
    (2)@BeforeTest 和 @AfterTest:在每个测试类的所有测试方法执行前和执行后执行。
    (3)@BeforeClass 和 @AfterClass:在同一个类中的所有测试方法执行前和执行后执行。
    (4)@BeforeMethod 和 @AfterMethod:在每个测试方法执行前和执行后执行。
    (5)@Test:标记一个方法为测试方法,可以指定测试的优先级、依赖关系等。

常见面试题

原理相关

  • 介绍一下selenium及其工作原理

    Selenium 是一个开源的自动化测试框架,专门用于Web应用程序的测试。它支持多种编程语言,如Java、C#、Python、Ruby等,并提供了不同的工具和库来模拟用户在浏览器中的交互行为

    selenium的原理涉及到3个部分,分别是:浏览器、driver(一般我们都会下载driver)、client(也就是我们写的代码)
    client其实并不知道浏览器是怎么工作的,但是driver知道,在selenium启动以后,driver其实充当了服务器的角色,跟client和浏览器通信,client根据webdriver协议发送请求给driver,driver解析请求,并在浏览器上执行相应的操作,并把执行结果返回给client。这就是selenium工作的大致原理。

  • selenium由哪些组件构成?常见的驱动有哪些

    Selenium WebDriver:核心组件,用于编写浏览器自动化脚本,支持多种浏览器。
    Selenium Grid:用于在不同机器和浏览器上并行运行测试。
    Selenium IDE:Firefox插件,用于记录和回放用户操作,适合创建简单测试。
    Page Object Model (POM):设计模式,用于组织和管理测试代码,提高可维护性

    FireFoxDriver ;InternetExplorerDriver ;ChromeDriver ;SafariDriver ;OperaDriver ;AndroidDriver

  • webdriver的协议是什么

    client与driver之间的约定,无论client是使用java实现还是c#实现,只要通过这个约定,client就可以准确的告诉drier它要做什么以及怎么做。
    webdriver协议本身是http协议,数据传输使用json

  • selenium是如何驱动浏览器做各种操作的呢

    1.对于每一条Selenium脚本,一个http请求会被创建并且发送给浏览器的驱动,最开始建立连接时服务端返回一个sessionid给客户端,后续的交互都是通过sessionid进行交互
    2.浏览器驱动中包含了一个HTTP Server,用来接收这些http请求
    3.HTTP Server接收到请求后根据请求来具体操控对应的浏览器
    4.浏览器执行具体的测试步骤
    5.浏览器将步骤执行结果返回给HTTP Server
    6.HTTP Server又将结果返回给Selenium的脚本,如果是错误的http代码我们就会在控制台看到对应的报错信息。

  • selenium webdriver有什么优点

    1.主流浏览器如Chrome、Firefox、IE、Safari等,可以在不同浏览器上运行和测试应用。
    2.支持大多数语言,如Java,Python,Ruby,C#等。
    3.Selenium提供了丰富的API可以根据测试需求进行扩展,实现定制化的测试用例。
    4.Selenium可以很好地与Jenkins,测试管理工具等集成,实现自动化测试的持续集成和持续交付。

  • POM设计模式和page factory

    page object:简单来说就是用class去表示被测页面。在class中定义页面上的元素和一些该页面上专属的方法。
    Page Factory 实际上是官方给出的java page object的工厂模式实现

  • 什么是Selenium Grid?

    Selenium-Grid允许在不同的机器上针对不同的浏览器并行运行测试。也就是说,在不同的机器、不同的浏览器和操作系统上同时运行多个测试。本质上,Selenium-Grid支持分布式测试执行

  • 举例Selenium中重载的方法

    // 方法一:通过 iframe的索引值,在页面中的位置
    driver.switchTo().frame(index);
    // 方法二:通过 iframe 的name 或者id
    driver.switchTo().frame(nameOrId);
    // 方法三:通过iframe 对应的webElement
    driver.switchTo().frame(frameElement);

  • selenium是否支持桌面应用软件的自动化测试

    不支持。selenium是根据网页元素的属性来确定范围元素的

定位元素相关

  • selenium中如何判断元素是否存在?

    selenium中没有提供原生的方法判断元素是否存在,一般我们可以通过定位元素+异常捕获的方式判断

  • 如何查找元素是否显示在屏幕上?

    WebDriver通过isDisplayed(), isSelected(), isEnabled(),这三种方法判断Web元素的可见性,这类方法将返回结果是布尔类型;Web元素可以是按钮,下拉框,复选框,单选按钮,标签等。

    ①isDisplayed(): boolean b1 = driver.findElement(By.id(“XXX”)).isDisplayed();
    ②isSelected(): boolean b2 = driver.findElement(By.id(“XXX”)).isSelected();
    ③isEnabled(): boolean b3 = driver.findElement(By.id(“XXX”)).isEnabled();

  • selenium中hidden或者是display = none的元素是否可以定位到?

    不可以,selenium不能定位不可见的元素。display=none的元素实际上是不可见元素

  • selenium自动化页面元素找不到存在异常的原因?

    ① 元素定位错误
    ② 页面加载时间过慢,需要查找的元素程序已经完成,单页面还未加载,此时可以加载页面等待时间
    ③ 有可能元素包含在iframe或者frame里面,需要切换。

  • selenium中如何保证操作元素的成功率?即如何保证我点击的元素一定是可以点击的?

    1、当网速不好的情况下,使用合适的等待时间;
    2、被点击的元素一定要占一定的空间,因为selenium默认会去点这个元素的中心点,不占空间的元素算不出来中心点;
    3、被点击的元素不能被其他元素遮挡;
    4、被点击的元素不能在viewport之外,也就是说如果元素必须是可见的或者通过滚动条操作使得元素可见;
    5、判断元素是否是可以被点击的。

  • id,name,clas,xpath,css selector这些定位器,你最偏爱哪一种,为什么?

    xpath和css最为灵活。id、name等需要开发支持
    xpath定位时采用遍历页面的方式,性能指标较差。xpath定位有通过绝对路径定位的,有时会不准确;对于动态元素可以使用xpath
    css选择器定位比较简洁,运行速度更快,通常用于性能要求严格的场景。

  • selenium为什么不推荐使用xpath定位?

    selenium使用xpath定位时采用遍历页面的方式,性能指标较差。另外xpath定位有通过绝对路径定位的,有时会不准确;
    而用css选择器定位比较简洁,运行速度更快,通常用于性能要求严格的场景。

  • 如何判断一个页面上元素是否存在?

    1、用try…except 在代码块加上
    2、用elements定义组元素方法 然后根其元素个数len()<1 存在返回True, 不存在则返回False
    3、结合WebDriverWait和excepted_conditions条件判断(强烈推荐) 显示等待,每间隔1秒判断一次,30秒超时,存在返回True,不存在则返回False

  • 一个元素明明定位了,点击无效(也没报错),如何解决?

    使用js点击,selenium有时候点击元素时会失效
    #js 点击
    js = ‘document.getElementById(‘baidu’).click()’
    driver.execute_script(js)

  • selenium调用js(execute_script),有哪些场景?

    ① 对input执行输入 ② 对富文本框的操作 ③ 滚动到指定位置操作

  • 如何去定位属性动态变化的元素?

    属性动态变化是指该element没有固定的属性值,只能通过相对位置定位。
    第一种方法:用findelements遍历
    第二种方法:通过xpath的轴 parent / following-sibling / precent-sibling

    一个是属性动态,定位时,若id是动态的,就不要用id定位,用其他定位元素方法
    另一个还是这个元素一会在页面上方,一会在下方,飘忽不定,定位方法也是一样,根据元素属性定位(元素的tag name属性是不会变的,动的只是class属性和style属性)

  • 如何通过子元素定位父元素?

    第一种:通过子元素定位父元素,selenium提供了parent方法,但是只能定位到父元素,却不能获取元素属性,也不能操作。
    第二种:通过xpath的语法直接定位。 如.//*[@name=”hello”]/… 两个点代表父级元素。

  • findElement和findElements有什么区别?

    这两个方法都是WebDriver接口的抽象方法,用于在网页中查找元素。
    findElemen():用于查找一个Web元素。它只返回一个WebElement类型。
    findElements():用于查找多个Web元素。它返回WebElements集合。

  • selenium中隐藏元素定位,你该如何做?

    隐藏元素可以正常定位到,只是不能操作(定位元素和操作元素是两码事,操作元素是指click 、clear 、send_keys等这些方法)。我们可以用js来操作隐藏元素。js和selenium不同,只有页面上有的元素(在dom里面的)都能正常操作。

操作相关

  • 如何获取当前页面的url

    driver.getCurrentUrl()

  • 如何在webdriver中调用应用程序?

    driver.get(‘url’) 或者 driver.navigate().to(‘url’)

  • 如何使用WebDriver执行右键单击?

    // contextClick方法用于模拟右键单击操作。perform方法用于执行链中存储的所有操作
    Actions actions = new Actions(driver);
    actions.contextClick(element).perform();

  • 登录按钮除了click之外还有什么方法

    使用submit()方法,但它只能在属性type=submit时使用

  • 如何验证复选框/单选框是否被选中

    driver.findElement(By.xpath(“元素路径”)).isSelected();

  • 如何使用WebDriver执行拖放?

    // dragAndDrop方法用于模拟从源元素拖放到目标元素的操作。perform方法用于执行链中存储的所有操作
    Actions actions = new Actions(driver);
    actions.dragAndDrop(sourceElement, targetElement).perform();

  • selenium如何处理web弹窗?js弹窗?

    使用driver.switch_to.alert()

  • 如何从文本框中获取输入的文本?

    String text = driver.findElement(By.xpath("元素路径 ")).getAttribute(“value”));

  • 如何截取一个元素的图片,不要截取全部图片?

    1、截取当前页面并自定义保存
    2、根据要截取元素图片的属性来获取该元素的坐标和大小 ele.location ele.size
    3、分别left = ele.location[‘x’] top = ele.location[‘y’] right = ele.location[‘x’] + ele.size[‘width’]
    bottom = ele.location[‘y’] + ele.size[‘height’]
    4、获取该元素的图片的坐标大小
    5、再次打开刚开始保存的,通过image类中的crop方法(相当于拷贝该元素的一个矩形区域),然后做保存操作就可以了。

  • 上传图片的几种方式?

    send_keys和AutoIT工具实现.

  • 截图应当怎么操作?

    driver.get_screenshot_as_file(‘C:\test.jpg’)

脚本稳定与优化类相关

  • 单斜杠和双斜杠有什么区别

    /用于标识直接子节点
    //用于在整个结构中查找

  • Assert和Verify有什么区别?

    Assert和Verify都是用于验证结果。如果测试用例失败,那么Assert将停止测试用例的执行,并且不再往下执行后续的测试步骤。
    对于Verify如果测试用例失败,都不会停止当前的程序执行,并且所有测试步骤都将被执行到。

  • 如何提高脚本的稳定性?

    首先只要页面一直没变过,说明定位方法是没问题的。
    优化方向:
    ① 自己写相对路径,多用id为节点查找,少用右键复制xpath,那种不稳定。
    ② 第二个影响因素就是等待了,sleep等待尽量少用(影响执行时间) 尽量使用显式等待
    ③ 定位元素方法重新封装,结合WebDriverWait和excepted_conditions判断元素方法,自己封装一套定位元素方法
    ④ 尽量使用测试专用环境,避免其他类型的测试同时进行,对数据造成干扰

  • 如何提高selenium脚本的执行速度?

    1、使用更高配置的电脑和选择更快的网络环境;
    2、使用效率更高的语言,比如java执行速度就快过python;
    3、优化代码;
    4、不要盲目的加sleep,尽量使用显式等待;
    5、可以考虑分布式执行(如,配置testNG实现多线程)或者使用selenium grid;
    6、对于firefox,考虑使用测试专用的profile,因为每次启动浏览器的时候firefox会创建1个新的profile,对于这个新的profile,所有的静态资源都是从服务器直接下载,而不是从缓存里加载,这就导致网络不好的时候用例运行速度特别慢的问题;
    7、chrome浏览器和safari浏览器的执行速度看上去是最快的。

  • selenium自动化时,在平时遇到过哪些问题?如何解决的

    动态id 、有iframe的情况、没加等待等因素

  • selenium中常见的异常

    NoSuchElementException - 元素未找到异常
    ElementNotVisibleException - 元素不可见异常
    ElementNotSelectableException - 元素不可选择异常
    NoAlertPresentException - 未找到警报异常
    NoSuchAttributeException - 未找到属性异常
    NoSuchWindowException - 未找到窗口异常
    TimeoutException - 超时异常
    WebDriverException - WebDriver异常

相关文章:

selenium学习笔记(二)

文章目录 前言设计模式POMPOM概念POM优势POM设计原则POM的实现 selenium的常用操作处理动态元素截图操作勾选复选框多层框架/窗口定位操作下拉框上传文件操作处理弹窗切换窗口拖拽操作 如何处理浏览器驱动更新导致的问题selenium与网站监控监听网页内容变化监控网络请求 seleni…...

宏集eX710物联网工控屏在石油开采机械中的应用与优势

案例概况 客户&#xff1a;天津某石油机械公司 应用产品&#xff1a;宏集eX710物联网工控屏 应用场景&#xff1a;钻井平台设备控制系统 一、应用背景 石油开采和生产过程复杂&#xff0c;涵盖钻井平台、采油设备、压缩机、分离器、管道输送系统等多种机械设备。这些设备通…...

linux——vi命令常用操作

一、vi模式 vi一般分为三种模式&#xff0c;分别是命令行模式、插入模式、末行模式 1.命令模式&#xff1a;控制屏幕光标的移动&#xff0c;按 &#xff1a;进入末行模式&#xff0c;按 i&#xff08;其他插入命令也可&#xff09; 进入插入模式&#xff1b; 2.插入模式&…...

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…...

重装荣耀X14笔记本电脑踩坑记

这几天趁着有国补搞了台荣耀 X14笔记本电脑。到手后第一件事情对我来说当然是要重装成Windows 11 LTSC版。所以按以往的经验做了个USB启动安装盘&#xff0c;但发现上电后按F12能进入启动设备选择&#xff0c;可是USB分类下没有任何设备。重启按F2进入设置界面&#xff0c;关闭…...

Android `android.graphics.drawable` 包深度解析:架构与设计模式

Android android.graphics.drawable 包深度解析:架构与设计模式 目录 引言Drawable 概述Drawable 的架构 Drawable 类层次结构Drawable 的核心方法Drawable 的设计模式 装饰者模式工厂模式状态模式常用 Drawable 子类解析 BitmapDrawableShapeDrawableLayerDrawableStateList…...

Kotlin语言的软件工程

Kotlin语言的软件工程 引言 在现代软件开发中&#xff0c;选择合适的编程语言是项目成功的关键之一。随着移动互联网的迅猛发展&#xff0c;以及大数据和人工智能等新兴技术的崛起&#xff0c;Kotlin语言凭借其简洁、高效和安全等特性&#xff0c;迅速崛起为备受欢迎的编程语…...

面试经典 150 题——数组/字符串(一)

文章目录 1、合并两个有序数组1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、移除元素2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、删除有序数组中的重复项3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、删除有序数组中的重复项 II4.1 题目链接4.2 题…...

使用亚马逊针对 PyTorch 和 MinIO 的 S3 连接器实现可迭代式数据集

2023 年 11 月&#xff0c;Amazon 宣布推出适用于 PyTorch 的 S3 连接器。适用于 PyTorch 的 Amazon S3 连接器提供了专为 S3 对象存储构建的 PyTorch 数据集基元&#xff08;数据集和数据加载器&#xff09;的实现。它支持用于随机数据访问模式的地图样式数据集和用于流式处理…...

TestMAX/DFT Compiler:时序单元的类型、连接顺序和后DFT优化

相关阅读 TestMAX/DFT Compilerhttps://blog.csdn.net/weixin_45791458/category_12865937.html?spm1001.2014.3001.5482 时序单元的状态 未映射的时序单元(Unmapped Sequential Cell) 在Design Compiler读取了一个RTL设计后&#xff0c;Design Compiler内置的HDL Compiler工…...

CAN201 Introduction to Networking(计算机网络)Pt.3 网络层

文章目录 4.Network Layter&#xff08;网络层&#xff09;4.1 Overview4.2 Router&#xff08;路由器&#xff09;4.3 Internet Protocol4.4 IPv4 addressing4.5 NAT&#xff08;network address translation&#xff0c;网路地址转换&#xff09;4.6 IPv64.7 Generalized For…...

App Factory:简化和加速私人应用开发

App Factory是Codigger提供的一套先进的开发工具、库和API&#xff0c;旨在帮助开发人员在现有的软件基础上添加特定的功能或扩展。它为私人应用的创建、开发和发布提供了一整套先进的工具集、集成的相关资源库以及强大的API接口&#xff0c;使开发者能够在现有的Codigger架构之…...

PHP语言laravel框架中基于Redis的异步队列使用实践与原理

在 Laravel 中&#xff0c;基于 Redis 的异步队列是通过 Laravel 的队列系统与 Redis 服务结合来实现的。这种队列机制允许你将任务推送到队列中&#xff0c;并由后台工作进程异步处理这些任务。这样&#xff0c;你就可以将耗时的操作&#xff08;如发送邮件、处理视频、数据同…...

全面Kafka监控方案:从配置到指标

文章目录 1.1.监控配置1.2.监控工具1.3.性能指标系统相关指标GC相关指标JVM相关指标Topic相关指标Broker相关指标 1.4.性能指标说明1.5.重要指标说明 1.1.监控配置 开启JMX服务端口&#xff1a;kafka基本分为broker、producer、consumer三个子项&#xff0c;每一项的启动都需要…...

kipotix4靶机实战

信息收集 1.判断靶机ip 原理&#xff1a;开靶机之前nmap扫一次网段&#xff0c;再开靶机之后扫一次&#xff0c;查看多出来的ip就是靶机ip ip192.168.98.1742.判断端口服务&#xff0c;系统版本 a.确定端口 b.-p指定端口进一步收集 c.信息筛选 1.端口&#xff1a;22,80,139,…...

我的秋招总结

我的秋招总结 个人背景 双非本&#xff0c;985硕&#xff0c;科班 准备情况 以求职为目的学习Java的时间大概一年。 八股&#xff0c;一开始主要是看B站黑马的八股文课程&#xff0c;背JavaGuide和小林coding还有面试鸭。 算法&#xff0c;250&#xff0c;刷了3遍左右 项目&…...

广义线性模型(GLM)全面解析

引言 广义线性模型&#xff08;Generalized Linear Model, GLM&#xff09;是统计学中一种重要的建模工具&#xff0c;它扩展了传统线性回归模型&#xff0c;能够处理响应变量的非正态分布和非线性关系。GLM 的灵活性和广泛的应用范围使其在金融、医学、社会科学等领域中成为数…...

C++ OCR 文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…...

PHP实现登录和注册(附源码)

前言 本博客主要讲述利用php环境实现一个简单的前后端结合的用户登录和注册功能。phpstudy是PHP调试环境的集成包&#xff0c;该程序包集成了 ApachePHPMySQLphpMyAdmin 等多个工具&#xff0c;是很好用的调试环境的程序集成包。 目录 前言 1. 准备工作 1.1 工具 1.2 php…...

AEO海关认证的注意事项

AEO海关认证的注意事项繁多且至关重要&#xff0c;企业需细致准备&#xff0c;确保万无一失。 首先&#xff0c;企业需深入研读相关政策文件&#xff0c;如《中华人民共和国海关注册登记和备案企业信用管理办法》及《海关高级认证企业标准》&#xff0c;以政策为指引&#xff0…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...