selenium学习笔记(二)

文章目录

前言

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可以等待元素在页面上可见或可点击后再进行操作

    java 复制代码
    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,进行截图操作

xml 复制代码
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>
java 复制代码
//浏览器截图
    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"));

    }

勾选复选框

java 复制代码
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定位

java 复制代码
 private static void page02() {
        // 创建浏览器驱动
        WebDriver webDriver = new ChromeDriver();
        // 打开网页
        webDriver.get("http://www.xxx.com");
        // 需要先定位到frame下再定位到click
        webDriver.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);
    }

操作下拉框

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

java 复制代码
 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 添加本地文件路径就可以了。

绝对路径和相对路径都可以,关键是上传的文件存在

java 复制代码
 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 没有对话框就不能用了,不然会报错。

java 复制代码
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();
    }

切换窗口

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

java 复制代码
// 进入百度页面然后点击新闻进入新闻页面,此时如果我们需要在新闻页面输入相关内容,是不能直接通过选择器定位实现的
// 我们需要先实现页面切换才能在新闻页面搜索内容
//浏览器切换窗口
    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类进行复杂的鼠标操作,如拖拽

java 复制代码
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与网站监控

监听网页内容变化

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

java 复制代码
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请求和响应

java 复制代码
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 Proxy
        BrowserMobProxy 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与Proxy
        driver.quit();
        proxy.stop();
    }
}

selenium 与性能测试

代码示例

java 复制代码
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();
    }
}
java 复制代码
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、添加依赖

    xml 复制代码
    <!-- 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的注解来定义测试方法和测试套件

    java 复制代码
    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;
        @BeforeMethod
        public void setUp() {
            // 设置WebDriver路径
            System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
            // 初始化WebDriver
            driver = new ChromeDriver();
        }
        @Test
        public void testGoogleSearch() {
            // 打开Google首页
            driver.get("https://www.baidu.com");
            // 执行测试逻辑
        }
    
        @AfterMethod
        public 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异常

相关推荐
MarkHD3 小时前
智能体在车联网中的应用:第51天 模仿学习与离线强化学习:破解数据效率与安全困局的双刃剑
学习·安全
Drawing stars6 小时前
JAVA后端 前端 大模型应用 学习路线
java·前端·学习
崇山峻岭之间6 小时前
Matlab学习记录33
开发语言·学习·matlab
玄〤6 小时前
黑马点评中 VoucherOrderServiceImpl 实现类中的一人一单实现解析(单机部署)
java·数据库·redis·笔记·后端·mybatis·springboot
科技林总7 小时前
【系统分析师】3.5 多处理机系统
学习
芯思路8 小时前
STM32开发学习笔记之三【按键】
笔记·stm32·学习
Lips6118 小时前
2026.1.11力扣刷题笔记
笔记·算法·leetcode
charlie1145141918 小时前
从 0 开始的机器学习——NumPy 线性代数部分
开发语言·人工智能·学习·线性代数·算法·机器学习·numpy
咚咚王者9 小时前
人工智能之核心基础 机器学习 第十二章 半监督学习
人工智能·学习·机器学习
袁气满满~_~9 小时前
Python数据分析学习
开发语言·笔记·python·学习