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

测试开发(6)软件测试教程——自动化测试selenium(自动化测试介绍、如何实施、Selenium介绍 、Selenium相关的API)

接上次博客:测试开发(5)测试分类标准 :按测试对像划分、按是否查看代码划分、按开发阶段划分、按测试实施组织、按是否运行划分、按是否手工划分、按测试地域划分-CSDN博客

目录​​​​​​​

什么是自动化测试

自动化测试介绍

单元测试

接口自动化测试

UI自动化

UI自动化测试的好处 

 UI层自动化测试框架

UI自动化测试的适用对象

如何实施自动化测试

Selenium介绍 

Selenium 的原理

webdriver的工作原理

为什么使用selenium作为web自动化测试工具? 

Selenium+Java环境搭建 

验证环境是否搭建成功

Selenium相关的API

元素的定位

通过标签定位

ID定位

name 定位

tag name 定位和class name 定位

Link Text 定位

Partial Link Text 定位

CSS Selector 定位 

 XPath 定位

CSS选择器和XPath选择器之间的区别

操作测试对象

添加等待 

添加强制等待:sleep休眠

添加智能等待

显示等待

隐式等待

打印信息

浏览器的操作

浏览器最大化

设置浏览器宽、高

操作浏览器的前进、后退

控制浏览器滚动条

键盘事件

键盘按键用法

 鼠标事件

窗口句柄

通过Selenium进行截图

定位一组元素

多层框架/窗口定位

多层框架的定位

多层窗口定位

层级定位

下拉框处理 

alert、confirm、prompt 的处理

上传文件操作

DIV对话框的处理


什么是自动化测试

自动化测试是指利用自动化工具或脚本来执行测试活动的过程。它的主要目的是减少人工测试的工作量,提高测试的效率和准确性。自动化测试可以针对软件的不同方面进行,包括功能、性能、安全性、界面等,以确保软件的质量和稳定性。自动化测试通常涉及编写测试脚本、配置测试环境、执行测试、分析测试结果等步骤。相比手动测试,自动化测试具有更快的执行速度、更好的复用性、更高的覆盖率和更低的人力成本。

自动化测试介绍

自动化测试是软件测试中的一项重要技术,旨在通过编写脚本或使用自动化测试工具来模拟用户的操作行为,以验证应用程序或系统的功能、性能和稳定性。它将人为驱动的测试行为转化为机器执行的过程,从而提高了测试的效率和准确性。

在自动化测试中,通常会涉及到不同层次的测试,包括UI自动化、接口自动化和单元测试自动化。UI自动化测试主要用于测试应用程序的用户界面,模拟用户与界面进行交互的过程,以验证界面的功能和用户体验。接口自动化测试则是针对应用程序的接口或服务进行测试,验证接口的正确性和可靠性。而单元测试自动化则是针对代码的最小单元进行测试,通常在开发阶段使用,用于验证代码的逻辑正确性和功能完整性。

金字塔模型是一种常用的自动化测试规划方法,它将不同层次的测试按照数量和投入比例划分成金字塔形状,底部是单元测试,中间是接口测试,顶部是UI测试。这种规划方式能够确保在保证测试覆盖全面的同时,尽量减少投入,提高测试的效率和质量。通过合理规划和执行自动化测试,可以有效降低测试成本,提高软件质量,加速软件发布的速度,从而实现更好的自动化测试产出投入比(ROI)。

单元测试

单元测试是软件开发中至关重要的一环,其投入应该占据测试工作的主要部分。由于单元测试是针对代码中最小的可测试单元进行的,因此它的运行频率通常也会更高。

在Java领域,Junit是一种常用的单元测试框架,它为开发人员提供了一种简单而有效的方式来编写和执行单元测试。通过Junit,开发人员可以快速编写测试用例,并在代码发生变化时轻松地运行测试,确保代码的正确性和稳定性。

接口自动化测试

接口自动化测试,也称为API测试,是针对应用程序接口进行的自动化测试。相对于UI自动化,API自动化更容易实现,执行起来也更加稳定。接口自动化测试具有以下特点:

  • 可在产品前期介入:接口自动化测试可以在产品开发的早期阶段介入,甚至在接口完成后即可开始。这使得团队可以及早发现接口问题,从而更早地解决和修复。

  • 用例维护量小:由于接口的稳定性较高,且接口变动相对较小,因此接口自动化测试的用例维护量通常较少。这意味着团队可以更轻松地维护和更新测试用例,降低了测试的成本和工作量。

  • 适合变动小的项目:接口自动化测试特别适用于那些接口变动较小,但界面变动频繁的项目。通过自动化测试,团队可以更快速地验证接口的正确性和可靠性,确保应用程序的稳定性和质量。

常见的接口自动化测试工具包括RobotFramework、JMeter、SoapUI、TestNG+HttpClient、Postman等。这些工具提供了丰富的功能和灵活的使用方式,可以满足不同项目的测试需求。通过选择合适的工具和策略,团队可以提高测试效率,加速软件开发过程,同时确保应用程序的质量和稳定性。

UI自动化

UI自动化测试是针对用户界面(UI)进行的自动化测试,尽管测试金字塔告诉我们应尽量多做API层的自动化测试,但UI层的自动化测试仍然具有其独特的价值。与API测试相比,UI自动化测试更贴近用户的需求和软件系统的实际业务,因此在某些情况下,我们不得不进行UI层的测试。

UI自动化测试的特点包括:

  1. 用例维护量大:由于UI自动化测试通常涉及到页面元素的操作和验证,因此测试用例的维护量往往较大。页面结构的变化或功能的更新都可能导致大量的测试用例需要进行调整和更新,这对于测试团队来说是一个挑战。

  2. 页面相关性强:UI自动化测试与具体的页面密切相关,因此通常需要在项目的后期阶段,即项目页面开发完成后才能进行介入。在页面开发过程中,可能会有不断的修改和调整,这可能会影响到已编写的UI自动化测试用例,增加了测试工作的复杂性。

  3. 适合界面变动较小的项目:虽然UI自动化测试对页面的变动敏感,但仍适用于那些界面变动较小的项目。对于那些页面结构和功能变动频繁的项目,UI自动化测试的维护成本可能会较高,因此需要仔细评估是否值得进行UI自动化测试。

UI自动化测试的好处 

UI自动化测试带来了许多好处,其中一些主要好处有:

  1. 降低回归测试的人力投入:针对大型系统的UI自动化测试能够降低由于变更或多期开发引起的大量回归测试的人力投入。虽然自动化测试在前期需要较多的人力投入,但在后期维护阶段,可以显著节省人力资源,而手工测试在后期需要增加大量人力用于回归测试。

  2. 减少重复测试的时间:UI自动化测试可以快速执行大量的重复测试,从而实现快速回归测试。这使得在软件开发周期中的迭代过程中,可以更快速地发现和修复问题。

  3. 创建优良可靠的测试过程:通过UI自动化测试,可以建立可靠的测试过程,减少了人为错误的可能性。自动化测试的执行过程更加一致和可靠,不容易受到人为因素的影响。

  4. 执行更多更繁琐的测试:UI自动化测试可以执行更多更繁琐的测试,包括对大量输入组合的测试、多种操作场景的测试等。这些测试对于手工测试来说可能非常耗时和困难,但通过自动化测试可以轻松实现。

  5. 执行难以手工进行的测试:有些测试场景可能很难手工进行,例如对于性能测试、负载测试等,UI自动化测试可以更容易地实现这些测试,并且可以在不同环境和配置下进行测试。

  6. 更好地利用资源:UI自动化测试可以在非工作时间执行,充分利用计算机资源,从而提高了资源利用率。

  7. 测试脚本的重用性:编写的UI自动化测试脚本可以在不同的版本和环境下重复使用,节省了测试人员编写测试用例的时间,提高了测试的效率。

 UI层自动化测试框架

在UI层的测试中,有许多不同的测试框架可供选择。例如,针对Windows客户端测试可以使用AutoIT,对于Web测试则常用的有Selenium、TestPlant eggPlant、Robot Framework、QTP等。

在测试开发的讲解中,我主要以Web UI自动化测试框架Selenium为例进行详细介绍,因为Selenium具有以下优点:

  1. 免费且开源:Selenium是一个免费的开源工具,不需要为其付费,也无需担心使用非法软件破解带来的问题。这使得团队可以在没有额外成本的情况下进行自动化测试。

  2. 小巧简单:Selenium对于不同的编程语言来说只是一个包或库,相比之下,QTP需要下载安装一个体积较大的程序。Selenium的小巧简单使得它在安装和使用上更为便捷。

  3. 多语言支持:Selenium支持多种编程语言,包括C、Java、Ruby、Python、C#等。这意味着无论你之前对哪种编程语言更熟悉,你都可以通过Selenium完成自动化测试,而QTP只支持VBScript。

  4. 跨平台和多浏览器支持:Selenium支持多平台,包括Windows、Linux和Mac,同时也支持多种主流浏览器,如Internet Explorer、Firefox、Safari、Opera和Chrome等。这使得测试人员可以在不同的操作系统和浏览器环境下进行测试,确保应用程序的跨平台兼容性和浏览器兼容性。

  5. 支持分布式测试:Selenium支持将测试用例分布到不同的测试机器上执行,从而实现分布式测试。这使得测试可以更快地执行,同时也更容易进行横向扩展,以适应大规模测试的需求。

UI自动化测试的适用对象

实施自动化测试的前提条件包括:

  1. 需求变动不频繁:自动化测试需要稳定的测试环境和稳定的需求,如果需求频繁变动,可能导致自动化测试脚本频繁失效,增加了维护成本。

  2. 项目周期足够长:自动化测试需要在项目的整个生命周期内发挥作用,如果项目周期太短,可能无法收回自动化测试所需的投入成本。

  3. 自动化测试脚本可重复使用:编写的自动化测试脚本需要具有高度的可重复使用性,能够适应不同版本的测试需求,并且能够在多次执行中保持稳定性。

适合做自动化测试的项目包括:

  1. 产品型项目:针对产品型项目,特别是那些功能相对稳定、需要频繁回归测试的项目,自动化测试非常适合。通过自动化回归测试可以有效验证新功能的引入是否导致了旧功能的故障,确保产品质量。

  2. 机械且频繁的测试:对于需要频繁重复相同操作的测试场景,比如兼容性测试或性能测试,自动化测试可以大大提高效率和准确性。

不适合做自动化测试的项目包括:

  1. 需求变动频繁的项目:如果项目需求频繁变动,导致自动化测试脚本频繁失效,维护成本会变得非常高,此时自动化测试的效果不佳。

  2. 项目周期短:如果项目周期太短,无法收回自动化测试所需的投入成本,自动化测试的效益将大打折扣。

  3. 交互型较强的项目:对于需要人工干预或者交互较强的项目,自动化测试难以实施。自动化测试更适合于机械化、重复性较强的测试任务。

如何实施自动化测试

实施自动化测试通常包括以下七个关键步骤:

  1. 分析:在这一阶段,需要对系统进行全面的分析,把握系统的核心体系架构和功能点。理解系统的逻辑结构和业务流程,确定自动化测试的重点和范围。

  2. 设计:设计测试用例是自动化测试的基础。在这一阶段,需要根据系统的需求和功能特性,设计出足够明确和清晰的测试用例。测试用例应该覆盖系统的各项功能,并且要考虑到不同的测试场景和边界条件。

  3. 实现:实现测试脚本是自动化测试的核心步骤。在这一阶段,根据设计好的测试用例,编写测试脚本,并且确保脚本具有合理的断言和参数化设置。断言用于验证测试结果的正确性,参数化可以提高测试脚本的灵活性和复用性。

  4. 执行:执行测试脚本是验证自动化测试效果的关键步骤。在这一阶段,需要执行编写好的测试脚本,并且监控脚本执行过程中的异常情况。对于出现的异常,需要及时分析原因并做出相应的调整。

  5. 总结:测试结果的分析和测试过程的总结对于优化自动化测试非常重要。在这一阶段,需要对测试结果进行深入分析,找出测试中存在的问题和改进的空间,并且总结测试过程中的经验教训。

  6. 维护:自动化测试脚本的维护是持续改进的过程。随着系统的变更和需求的更新,测试脚本也需要不断地进行维护和优化。在这一阶段,需要及时更新和调整测试脚本,确保其与系统保持同步。

  7. 分析:在自动化测试过程中,深刻分析自动化用例的覆盖风险和脚本维护的成本是至关重要的。通过对自动化测试的效果进行评估和分析,可以不断改进测试策略和优化测试流程,提高自动化测试的效率和可靠性。

自动化测试需要掌握以下技能:

  1. 了解被测试系统的基本业务:深入了解被测试系统的业务流程、功能模块和用户需求,对系统的业务逻辑有清晰的认识。

  2. 了解业务的技术框架:了解被测试系统所采用的技术框架,包括前端和后端的技术栈,对系统的架构和技术实现有一定的了解。

  3. 懂得功能测试:具备功能测试的基本知识,包括测试用例设计、执行和结果验证等方面的技能。

  4. 懂得一种编程语言:至少掌握一种编程语言,例如Java、Python、JavaScript等,用于编写自动化测试脚本和实现测试工具。

  5. 懂数据库、操作系统:了解数据库的基本操作和SQL语言,能够进行简单的数据库操作和查询;熟悉常见的操作系统,如Windows、Linux等。

  6. 了解常见的测试框架:熟悉常见的测试框架和工具,如JUnit、TestNG、Selenium、Appium等,了解它们的基本原理和使用方法。

  7. 掌握版本控制工具:熟悉使用版本控制工具如Git,能够进行代码版本管理和团队协作。

  8. 具备问题分析和解决能力:能够快速定位和解决自动化测试过程中遇到的问题和异常,包括脚本编写、环境配置、执行错误等。

  9. 良好的沟通和团队合作能力:与开发人员、产品经理等团队成员进行有效的沟通和协作,共同推进自动化测试工作的进展。

  10. 持续学习和改进的意识:保持对新技术和行业趋势的关注,不断学习和提升自己的技能水平,不断改进自动化测试流程和方法。

Selenium介绍 

Selenium是一个用于Web应用程序的自动化测试框架,它基于UI,支持多平台、多浏览器和多种编程语言。在Selenium的发展历程中,早期的Selenium Remote Control(RC)已经被现在的WebDriver所取代,从某种程度上说,WebDriver可以被理解为Selenium 1.0和WebDriver的结合体,构成了现在的Selenium 2.0。一般来说,当我们谈论Selenium时,指的就是Selenium 2.0。

Selenium框架主要由三个组件组成:

  1. Selenium IDE: Selenium IDE是一个用于Selenium测试的集成开发环境。它允许测试人员直接在浏览器中录制用户操作,并且可以回放、编辑和调试测试脚本。在调试过程中,可以逐步执行测试脚本或调整执行速度,并且可以查看底部的日志以查找错误信息。Selenium IDE还支持将录制的测试脚本导出为多种编程语言,如Java、C#、Python、Ruby等,以满足不同测试人员的需求。

  2. WebDriver: Selenium WebDriver是Selenium 2.0的核心组件之一。相比Selenium RC,在WebDriver中运行JavaScript应用程序不会受到环境沙箱的限制。WebDriver可以针对不同的浏览器创建更强大、更稳定、跨平台的自动化测试脚本。它使用特定于语言的绑定(如Java、C#、Python、Ruby、Perl、JavaScript等)来驱动浏览器执行操作和验证Web元素。

  3. Selenium Grid: Selenium Grid是一个服务器,用于管理多个浏览器实例的访问。它负责管理各个节点的注册和状态信息,允许在同一时刻在不同服务器上执行不同的测试脚本。Selenium Grid支持在多个计算机上并行执行测试,从而提高测试效率。它可以在不同的操作系统和浏览器上并行运行测试,并且可以通过分布式测试用例的执行来扩展测试覆盖范围。

Selenium 的原理

Selenium 是一个用于自动化 Web 应用程序测试的工具,它提供了一组工具和库,允许开发者模拟用户在浏览器中的操作,如点击链接、填写表单、提交数据等。其原理可以简要概括如下:

  1. WebDriver 接口:WebDriver 接口是 Selenium 的核心。它定义了一系列用于控制浏览器行为的方法,如打开 URL、查找元素、模拟用户操作等。不同的浏览器都有对应的 WebDriver 实现,比如 ChromeDriver、FirefoxDriver 等。

  2. 浏览器驱动:每个 WebDriver 都是与特定浏览器版本兼容的驱动程序,用于与浏览器通信。这些驱动程序负责启动浏览器、加载页面、执行用户操作,并将结果返回给测试脚本。

  3. 定位元素:Selenium 允许通过各种方式定位 HTML 页面上的元素,如通过 ID、类名、标签名、CSS 选择器、XPath 等。这些方法可以精确定位到页面中的元素,以便进行后续操作。

  4. 模拟用户操作:一旦定位到页面上的元素,Selenium 可以模拟各种用户操作,如点击链接、填写表单、提交数据等。这些操作会触发页面上的相应事件,从而使页面的行为与用户交互一致。

  5. 获取页面状态:Selenium 还可以获取页面的状态信息,如页面标题、URL、元素属性等。这些信息可以用于验证页面行为是否符合预期。

  6. 断言和验证:测试人员可以使用断言和验证机制来验证页面的行为是否符合预期。如果页面上的某个元素存在、文本匹配、URL 包含特定内容等,测试就会通过,否则就会失败。

总的来说,Selenium 的原理就是利用 WebDriver 接口与浏览器进行通信,定位页面元素并模拟用户操作,最终验证页面行为是否符合预期。这使得开发者能够自动化执行各种 Web 应用程序的测试,提高了测试效率和质量。 

webdriver的工作原理

WebDriver的工作原理如下:

  1. 启动浏览器:首先,测试脚本会通过Selenium WebDriver启动目标浏览器。一旦浏览器启动,它将作为WebDriver的远程服务器运行,等待接收命令。

  2. 绑定到特定端口:Selenium WebDriver会将目标浏览器绑定到特定的端口,以便在远程服务器上进行通信和控制。

  3. 客户端发送请求:测试脚本(即客户端)借助CommandExecutor发送HTTP请求给远程服务器(即WebDriver的remote server)。这些请求遵循WebDriver Wire协议,在HTTP请求的body中以JSON格式的字符串指定要执行的操作。

  4. 远程服务器处理请求:远程服务器接收到来自客户端的请求后,会依赖于原生的浏览器组件,将WebDriver Wire协议中定义的命令转化为浏览器原生的调用。这些调用会直接操作浏览器,完成相应的操作,如点击按钮、输入文本等。

  5. 操作浏览器:浏览器接收到来自远程服务器的命令后,会执行相应的操作,如点击链接、填写表单等。所有这些操作都是通过WebDriver的控制来实现的,浏览器本身不会与测试脚本直接通信。

  6. 返回执行结果:浏览器执行完命令后,将执行结果返回给远程服务器,然后远程服务器再将结果返回给测试脚本。这样,测试脚本就可以获取到浏览器执行操作的结果,从而进行后续的断言或其他操作。

为什么使用selenium作为web自动化测试工具? 

Selenium是广泛应用的Web自动化测试工具,有以下几个主要原因:

  1. 跨平台性: Selenium支持多种操作系统(如Windows、Mac和Linux)和多种浏览器(如Chrome、Firefox、Edge等),使得测试工程师可以在不同的环境下开展测试工作。

  2. 开源免费: Selenium是开源的软件测试工具,用户可以免费获取并根据需要进行定制和扩展。这使得它成为了很多团队的首选,尤其是对于那些预算有限或者不想受商业工具限制的团队。

  3. 支持多种编程语言: Selenium支持多种主流编程语言,包括Java、Python、C#等,使得测试人员可以根据自己的喜好和项目的需求选择合适的语言进行测试脚本的编写。

  4. 强大的社区支持: Selenium拥有庞大的开发者社区,用户可以从社区中获取到丰富的资源、教程和解决方案。这样的社区支持使得用户能够更快地解决问题并且与其他开发者进行交流。

  5. 灵活性和可扩展性: Selenium提供了丰富的API和功能,可以进行各种形式的Web测试,包括UI测试、功能测试、性能测试等。同时,Selenium还支持与其他测试框架和工具集成,以满足更复杂的测试需求。

综上所述,Selenium因其跨平台性、开源免费、多语言支持、强大的社区支持以及灵活可扩展的特性,成为了Web自动化测试领域的首选工具之一。

Selenium+Java环境搭建 

windows电脑环境搭建-chrome浏览器

Chrome+Java(推荐)

1、下载chrome浏览器

链接地址:Google Chrome - 快速安全的网络浏览器,专为您而打造

 

2、查看chrome浏览器版本

 

3、下载chrome浏览器驱动

链接地址:ChromeDriver - WebDriver for Chrome - Downloads

如果是更高版本的浏览器,可以下载测试版本的驱动: 

配置系统环境变量PATH

解压下载好的驱动压缩包,将下载好的chromedriver.exe放到chrome浏览器安装路径下(如果是edge浏览器驱动那就将对应驱动放到edge浏览器安装路径下),这里以chrome浏览器驱动为例:

接下来编辑环境变量:

把刚刚的chrome浏览器安装路径复制粘贴进来就行了: 

验证环境是否搭建成功

创建java项目,添加pom文件中添加依赖

<dependencies><!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version></dependency>
</dependencies>

注意这里的版本是selenium3,不是selenium4。 

编写代码运行

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;public class Main {public static void main(String[] args) {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");}
}

调整代码为:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;public class Main {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");}
}

其中,驱动器可执行文件的路径必须通过 webdriver.chrome.driver 系统属性进行设置。这意味着虽然我们已经将 chromedriver.exe 移动到了 C:\Program Files\Google\Chrome\Application 下,但 Selenium 仍然无法找到它。

为了解决这个问题,我们需要确保在代码中设置了正确的系统属性。所以我们可以在代码中添加以下一行代码来设置 webdriver.chrome.driver 属性:

System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");

Selenium 在寻找浏览器驱动时,通常需要指定一个系统属性来告诉它驱动程序的路径。因此,即使你已经将 Chrome 浏览器的安装目录添加到了系统的 Path 变量中,可能仍然需要在代码中设置 webdriver.chrome.driver 系统属性,以确保 Selenium 可以找到 ChromeDriver 可执行文件。

所以,无论你将 Chrome 浏览器的安装目录添加到 Path 变量中与否,我都建议在代码中显式设置 webdriver.chrome.driver 属性,这样更加健壮和可靠。

运行后,如果打开了浏览器,说明安装成功:

Selenium相关的API

API是应用程序编程接口(Application Programming Interface)的缩写。它是一组定义了软件组件之间交互方式的规则和约定。API允许不同的软件系统之间相互通信、交换数据和执行操作,而无需了解彼此的内部实现细节。通过API,开发人员可以利用其他软件系统提供的功能,而无需重新实现这些功能,从而提高了开发效率和软件的可重用性。API通常以函数、方法或协议的形式呈现,并且可以在不同的编程语言和平台上使用。

元素的定位

对象的定位在自动化测试中是至关重要的,因为要操作一个对象,首先需要识别它。就像我们识别一个人一样,一个对象也有各种特征(属性),比如身份证号、姓名、住址等,通过这些特征我们可以找到这个对象。

在自动化测试中,我们也可以通过对象的属性来定位它,确保页面上该属性的唯一性。

WebDriver 提供了一系列的对象定位方法,常用的包括:

  1. ID(标识符): 通过对象的唯一标识符来定位,通常是对象的id属性。
  2. Name(名称): 通过对象的名称来定位,通常是对象的name属性。
  3. Class Name(类名): 通过对象的类名来定位,通常是对象的class属性。
  4. Link Text(链接文本): 通过链接的文本内容来定位超链接对象。
  5. Partial Link Text(部分链接文本): 通过链接文本的部分内容来定位超链接对象。
  6. Tag Name(标签名): 通过对象的标签名来定位,通常是HTML标签名。
  7. XPath: 使用XPath表达式来定位对象,XPath是一种用于在XML文档中导航和定位节点的语言。
  8. CSS Selector(CSS选择器): 使用CSS选择器语法来定位对象,可以通过对象的样式属性来定位。

以上提到的对象定位方法,按照定位方法的具体实现方式进行归类,即定位方法的技术实现方式,可以分为三种类型:

  1. 基于单一属性的定位方法: 这些方法依赖于对象的单一属性来定位,如ID、Name、Class Name等。它们通常适用于对象具有唯一标识符的情况。

    • ID(标识符)
    • Name(名称)
    • Class Name(类名)
  2. 基于链接的定位方法: 这些方法用于定位超链接对象,根据链接的文本内容进行定位。

    • Link Text(链接文本)
    • Partial Link Text(部分链接文本)
  3. 基于对象层级关系的定位方法: 这些方法通过对象在DOM树中的位置或者与其他对象之间的关系来定位,具有更高的灵活性。

    • Tag Name(标签名)
    • XPath
    • CSS Selector(CSS选择器)

每种定位方法都有其适用的场景和优劣势,根据具体情况选择最合适的定位方法是至关重要的。在编写自动化测试脚本时,我们需要充分了解页面结构和对象特征,以便准确地定位和操作对象。

按照定位方法的主要特征进行归类,即定位方法所依赖的元素属性或特征,元素定位方法又可以归结为三类 :

  1. 通过标签定位:包括ID、Name、Class Name、Link Text、Partial Link Text和Tag Name等方法,这些方法直接使用元素在HTML文档中的标签信息来定位元素。

  2. XPath定位:使用XPath表达式来定位对象,XPath提供了一种更灵活、更强大的定位方式,可以基于元素的属性、层级关系等进行定位。

  3. CSS Selector(CSS选择器):使用CSS选择器语法来定位元素,这种方法也是基于元素的样式属性进行选择,具有灵活性和强大的定位能力。

通过标签定位

通过前端工具,例如Chrome浏览器的F12开发者工具,我们能够轻松地获取网页元素的属性信息,例如百度搜索框的属性如下所示:

<input id="kw" class="s_ipt" type="text" maxlength="100" name="wd" autocomplete="off">

ID定位

ID是指页面元素的唯一标识属性,在网页开发中被广泛应用于元素的定位。然而,并非所有元素都具有ID属性。若一个元素具有ID属性,通常意味着在整个页面范围内其ID是唯一的,因此我们可以通过该ID来精确地定位到这个元素。 ID的唯一性使得它成为一种可靠的定位方式,为开发者提供了一种直接而有效的手段来操作特定的页面元素。

我们通过Java,使用Selenium WebDriver库来进行网页元素的定位和操作:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;public class WebElementLocate {public static void main(String[] args) {// 设置Chrome浏览器驱动路径System.setProperty("webdriver.chrome.driver", "path_to_chromedriver");// 实例化Chrome浏览器驱动对象WebDriver driver = new ChromeDriver();// 打开百度首页driver.get("https://www.baidu.com");//…………// 关闭浏览器driver.quit();}
}
// 通过ID定位百度输入框
WebElement elementById = driver.findElement(By.id("kw"));
System.out.println("通过ID定位百度输入框:" + elementById);
name 定位

使用name属性进行定位是另一种常见的方法。如果一个元素具有name属性,并且该属性在整个页面中是唯一的,那么我们同样可以借助name属性来定位这个元素。

// 通过Name定位百度输入框
WebElement elementByName = driver.findElement(By.name("wd"));
System.out.println("通过Name定位百度输入框:" + elementByName);
tag name 定位和class name 定位

除了ID和Name属性外,还可以使用Tag Name和Class Name进行定位。Tag Name是元素的标签名,而Class Name是元素的类名。但需要注意,不是所有元素都具有Tag Name或Class Name属性,并且这两种属性在页面上必须是唯一的才能够准确地定位。

// 通过Tag Name定位百度输入框
WebElement elementByTagName = driver.findElement(By.tagName("input"));
System.out.println("通过Tag Name定位百度输入框:" + elementByTagName);// 通过Class Name定位百度输入框
WebElement elementByClassName = driver.findElement(By.className("s_ipt"));
System.out.println("通过Class Name定位百度输入框:" + elementByClassName);
Link Text 定位

Text 定位是通过元素的可见文本内容来定位元素。这在处理按钮文本、段落内容或其他可见文本元素时非常有用。使用 find_element_by_link_text() 方法来实现对链接文本的定位,或使用 find_element_by_partial_link_text() 方法来实现对部分链接文本的定位。

举例来说,如果一个按钮上的文本是 "Submit",可以使用 find_element_by_link_text("Submit") 方法来定位该按钮元素。同样地,如果一个段落中包含了 "Important information",也可以使用 find_element_by_partial_link_text("Important") 来定位该段落元素。

// Link Text定位
WebElement linkByText = driver.findElement(By.linkText("Click Here"));
System.out.println("Link Text定位:" + linkByText);
Partial Link Text 定位

Partial Link Text 定位是对链接文本的部分匹配定位。有时候,链接文本可能非常长,但我们只需要匹配其中的一部分来定位元素即可。在这种情况下,使用 find_element_by_partial_link_text() 方法是很方便的。

例如,如果一个链接的文本是 "Click Here to Visit OpenAI",我们可以使用 find_element_by_partial_link_text("OpenAI") 来定位该链接元素。即使链接文本的其余部分发生变化,只要包含了 "OpenAI" 这个部分,该定位方法依然能够准确地找到对应的元素。

// Partial Link Text定位
WebElement partialLinkByText = driver.findElement(By.partialLinkText("OpenAI"));
System.out.println("Partial Link Text定位:" + partialLinkByText);

CSS Selector 定位 

CSS Selector 是一种通过 CSS 样式规则来定位元素的方法。使用 CSS Selector 可以根据元素的标签名、类名、ID 等属性来精确定位元素。相对于 XPath,CSS Selector 的定位速度通常更快。在实际应用中,可以根据需要选择合适的 CSS Selector 来定位元素。

CSS(层叠样式表)是一种用来描述 HTML 和 XML 文档的表现样式的语言。CSS 使用选择器来选择页面元素并绑定样式。这些选择器也可以被 Selenium 用作定位元素的策略。

通过使用 find_element_by_css_selector() 函数,我们可以根据 CSS Selector 来定位元素。例如,通过 find_element_by_css_selector("#kw") 就可以定位到百度输入框,其中 #kw 是表示 ID 属性的 CSS Selector。

基本的CSS选择器语法包括以下几种:

  1. 标签选择器:标签选择器是最基本的选择器,它通过元素的标签名来选择对应的元素。语法简单直接,只需写出标签名称即可。例如:div、p、a。
  2. 类选择器:类选择器允许你通过元素的类名来选择元素,以.符号开头,后跟类名。在HTML中,通过给元素指定class属性来定义类名。例如:.highlight、.button、.navbar。
  3. ID选择器:ID选择器用于选择具有特定ID属性的元素,以#符号开头,后跟ID名称。ID在整个文档中应该是唯一的。在HTML中,通过给元素指定id属性来定义ID。例如:#header、#content、#footer。
  4. 属性选择器:属性选择器允许你根据HTML元素的属性来选择元素。它们可以根据属性的存在与否、属性值的具体情况等进行选择。例如,选择所有具有指定属性的元素:[attribute],选择属性值为指定值的元素:[attribute=value]。
  5. 后代选择器:后代选择器允许你选择某个元素内部的后代元素,通过在选择器中使用空格来表示父子关系。例如,div p 会选择所有 <div> 元素内的所有 <p> 元素。
  6. 子元素选择器:子元素选择器与后代选择器类似,但只选择直接子元素,不考虑更深层次的后代关系。它使用>符号来指示子元素。例如,ul > li 会选择所有直接作为 <ul> 子元素的 <li> 元素。
  7. 父类选择器:CSS本身没有提供直接选择父元素的方法。但是,可以通过其他选择器间接选择父元素。
  8. 伪类选择器:伪类选择器用于选择元素的特定状态或位置,而不是元素自身的属性。常见的伪类包括 :hover, :active, :first-child, :nth-child() 等。例如:a:hover 会选择鼠标悬停在链接上时的状态,li:nth-child(odd) 会选择列表中奇数位置的子元素。

获取 CSS Selector 通常可以使用 Chrome 浏览器的开发者工具(F12),在 Elements 面板中右键点击元素,选择 Copy -> Copy selector 即可获取元素的 CSS Selector。

点击最左上角的图标后,在页面中选中百度输入框,跳转到该代码,点击这行代码后按Ctrl+F,下方弹出输入框:

想要选中这行代码,此时,.s_ipt并不是一个有效的CSS选择器,因为在CSS中,.用于选择具有特定类的元素,而不是选择具有特定类的元素的属性。所以,输入.s_ipt并不会选择整行代码,而是选择具有类名为s_ipt的元素。

要选中整行代码,我们可以使用更通用的CSS选择器,例如根据标签名、ID或其他属性来选择。class="s_ipt"是元素的属性,而不是元素本身。因此,要选择具有class="s_ipt"属性的元素,我们应该使用属性选择器,[class='s_ipt']。 如果要选中整行代码,我们可以使用更具体的选择器,例如input.s_ipt来选择具有类名为s_ipt的input元素。

CSS Selector 的灵活性允许我们选择控件的任意属性。因此,在实际使用中,我们可以根据页面的具体情况选择合适的 CSS Selector 来进行元素定位。

具体的语法参考:CSS 选择器参考手册


 

利用代码定位元素:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;public class Main {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");WebElement search_input = webDriver.findElement(By.cssSelector(".s_ipt"));if (search_input==null){System.out.println("测试不通过");} else {System.out.println("测试通过");}}
}

 

 XPath 定位

什么是XPath?Cover page | xpath | W3C standards and drafts | W3C

XPath 基础教程: XPath 教程

XPath是一种用于在XML文档中定位节点的语言,它是XML Path Language的缩写。在网页自动化测试中,XPath也是一种常用的元素定位方式。与CSS选择器类似,XPath允许根据元素的层级关系、属性等特征来准确定位元素。XPath的灵活性很高,使得它成为了一种强大的定位工具,但同时也需要注意XPath表达式的编写规则和语法,以确保定位的准确性和唯一性。

XPath的优势在于扩展了传统的id和name定位方式,提供了更多种可能性。通过XPath,可以精确地定位页面中的任何一个元素,而不仅限于id和name属性。XPath的表达能力使得它可以处理各种复杂的定位需求,如基于文本内容、基于元素属性、基于元素位置等。


XPath的基本语法包括以下几个部分:

  1. 节点选择器:XPath使用路径表达式来选择节点。最简单的路径表达式是节点名称,例如 div、p、a 等。这样的路径表达式选择了文档中所有符合名称的节点。
  2. 路径操作符:XPath中的路径操作符有两种,分别是单斜杠 / 和双斜杠 //。单斜杠用于选择子节点,双斜杠用于选择子孙节点。例如,/div/p选择所有直接子节点为 <div> 的 <p> 元素,而 //div/p 选择文档中所有嵌套在 <div> 元素内的 <p> 元素。
  3. 谓语:谓语用于过滤节点,使得选择更加精确。它放在方括号[]内,可以是一个条件表达式。例如,//div[@class='example'] 选择所有class属性为 example 的 <div> 元素。
  4. 属性选择:XPath可以根据节点的属性来选择元素。使用 [@attribute] 来选择具有指定属性的节点,或者使用 [@attribute='value'] 来选择具有特定属性值的节点。
  5. 通配符:通配符 * 可以匹配任意节点。例如,//div/* 选择所有 <div> 元素的子节点。
  6. 轴:XPath提供了轴(axis),用于在文档中定位元素的位置关系。例如,ancestor::div 选择所有祖先节点中是 <div> 元素的节点。
  7. 组合:XPath允许多种选择器的组合使用,以实现更加复杂的选择逻辑。例如,//div[@class='example']//p 选择class属性为 example 的 <div> 元素内的所有 <p> 元素。

当使用XPath时,有两种主要的路径操作符:绝对路径和相对路径。

  1. 绝对路径:绝对路径从根节点开始,沿着文档结构一直到目标节点。在XPath中,绝对路径以斜杠 / 开头,表示从文档的根节点开始沿着路径查找目标节点。绝对路径的优点是确保了唯一性和准确性,因为它们不受当前节点位置的影响。然而,当页面结构发生变化时,绝对路径可能会变得不稳定,需要经常更新。

    例如,/html/body/div[1]/p[2] 是一个绝对路径,表示选择文档根节点下的第一个 <div> 元素中的第二个 <p> 元素。

  2. 相对路径:相对路径从当前节点开始,沿着文档结构查找目标节点。在XPath中,相对路径不以斜杠开头,表示相对于当前节点的路径。相对路径通常更简洁,并且在页面结构变化时更具灵活性,因为它们不依赖于文档的绝对结构。

    例如,./div/p[2] 是一个相对路径,表示从当前节点开始选择下一级的 <div> 元素中的第二个 <p> 元素。

相对路径更加灵活,因为它们不依赖于文档结构的绝对位置,而是相对于当前节点的位置。但是,绝对路径可以提供更强的准确性和稳定性,特别是在页面结构变化较少或者需要确保准确性的情况下。在实际应用中,根据页面的具体情况,我们可以灵活选择使用绝对路径或相对路径。

要获取XPath表达式,可以借助浏览器的开发者工具。例如,在Chrome浏览器中,可以使用F12开发者模式中的Elements面板,右键点击目标元素,选择“Copy” > “Copy XPath”来获取该元素的XPath表达式。这样就能够方便地将XPath表达式应用于自动化测试脚本中,实现对页面元素的准确定位和操作。


当定位元素时,我们可以使用以下四种方法:

  1. 绝对路径:使用绝对路径从根节点开始指定目标元素的路径。这种方式确保了准确性,但是当页面结构发生变化时,维护成本较高。例如:/html/body/div[1]/form/input[2]
  2. 相对路径+索引:使用相对路径结合节点索引来定位目标元素。相对路径不以斜杠开头,而是从当前节点开始。通过指定元素在父元素中的位置来定位元素。例如://div[@class="container"]/ul/li[3]
  3. 相对路径+属性值:使用相对路径结合元素的属性值来定位目标元素。通过指定元素的属性值来匹配元素。例如://input[@id="username"]
  4. 相对路径+通配符:使用相对路径结合通配符来选择目标元素。通配符 * 表示匹配任何元素。通过结合通配符和其他条件来定位元素。例如://div[@class="article"]/*
  5. 相对路径+文本匹配:使用相对路径结合元素的文本内容来定位目标元素。通过指定元素的文本内容来匹配元素。例如;//a[text()="Read More"]


这些方法可以根据页面的具体结构和需要灵活选择,以确保准确地定位目标元素。具体来看:

绝对路径:

相对路径+索引:

相对路径+属性值:

相对路径+通配符:

相对路径+文本匹配:

 

利用代码定位元素:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;public class Main {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");WebElement search_input = webDriver.findElement(By.xpath("//form/span[1]/input"));if (search_input==null){System.out.println("测试不通过");} else {System.out.println("测试通过");}}
}

关闭浏览器:

webDriver.quit();
webDriver.close();

webDriver.quit()  和 webDriver.close()  都是WebDriver中用于关闭浏览器的方法,它们之间有一些区别:

  1. webDriver.quit()

    • webDriver.quit() 方法用于关闭当前所有由WebDriver实例管理的窗口,包括所有相关的窗口和子窗口。当调用该方法时,WebDriver实例将会关闭所有与其关联的浏览器进程。
    • 使用 quit() 方法后,WebDriver实例将被销毁,无法再次使用。
    • quit() 方法适用于结束整个测试会话,并且关闭所有浏览器窗口。
  2. webDriver.close()

    • webDriver.close() 方法用于关闭当前焦点窗口或标签页,但不会关闭整个浏览器。
    • 如果浏览器窗口是最后一个窗口,那么调用close()方法后,WebDriver实例将被保留,仍然可以使用。
    • close()方法适用于在测试过程中需要关闭当前活动窗口,但仍然希望保留其他窗口或标签页的情况。

推荐的使用方式取决于测试场景和需求:

  • 如果测试过程中只需要关闭当前窗口并且不需要再打开其他窗口,则可以使用 webDriver.close() 方法。
  • 如果测试已经结束或者需要关闭所有窗口,并且不再需要WebDriver实例,则应该使用 webDriver.quit() 方法。 

当然,抛开上述内容不谈,还有最简单的选中元素的方法:

CSS选择器和XPath选择器之间的区别

CSS选择器和XPath选择器都是用于定位元素的工具,但是它们之间还是有一些区别的:

  1. 语法

    • CSS选择器使用简洁的语法来选择元素,通常基于标签名称、类名、ID等属性进行选择。
    • XPath选择器使用一种更加强大和复杂的语法,可以通过元素的层级关系、属性、文本内容等多种方式来定位元素。
  2. 性能

    • 一般情况下,CSS选择器的性能比XPath选择器更高。因为浏览器的原生实现更适合解析CSS选择器,而对XPath选择器的支持相对较弱。在大多数情况下,使用CSS选择器定位元素的效率更高,尤其是在定位简单的元素时。
    • XPath选择器的性能可能会受到浏览器引擎的影响,有些浏览器对XPath的支持不够完善,可能导致性能较差。
  3. 功能

    • XPath选择器相对于CSS选择器更加灵活和强大,可以处理更复杂的定位需求。例如,XPath支持基于元素的文本内容、属性的值、甚至是元素之间的关系来进行定位,而CSS选择器相对较简单。
    • CSS选择器更适合用于基本的元素选择和样式选择,而XPath选择器则更适合处理较为复杂的定位需求。
  4. 跨平台性

    • XPath选择器在不同的XML结构中通常具有更好的通用性,因此在处理非HTML/XML文档或者在跨平台应用中可能更有优势。
    • CSS选择器更适合用于处理HTML文档,因为HTML的结构更符合CSS选择器的简单定位需求。

综上所述,CSS选择器和XPath选择器各有优劣,具体选择取决于测试场景的要求、目标元素的复杂度以及浏览器的支持情况。通常情况下,我们还是优先考虑使用CSS选择器,只有在CSS选择器无法满足定位需求时,再考虑使用XPath选择器。

现在回过头来问你,定位元素的API是什么?

定位元素的API通常是指用于在网页上查找和定位特定元素的方法和函数。在Web自动化测试中,定位元素是非常重要的,因为测试脚本需要与页面上的各种元素进行交互,如输入文本、点击按钮、验证文本等操作。

在Selenium中,定位元素的API主要是一组方法,用于根据不同的定位策略找到网页上的元素。一些常见的定位元素的API包括:

  • findElement(By locator): 根据给定的定位器(locator)找到页面上的单个元素。
  • findElements(By locator): 根据给定的定位器(locator)找到页面上所有符合条件的元素。
  • 定位器(locator):指定元素在页面上的位置或特征,常见的有 ID、类名、标签名、CSS选择器、XPath等。

操作测试对象

前面提到的定位元素只是自动化测试的第一步,接下来需要对这些定位到的元素进行各种操作。这些操作可以是与用户交互的动作,比如点击按钮或链接,输入文本,清除输入框内容,提交表单等。针对定位到的元素进行何种操作取决于测试场景和需求。

在WebDriver中,最基本的操作对象的方法有以下几个:

click:用于点击对象,例如按钮、链接等可点击的元素,以触发相应的事件或操作。

send_keys:在对象上模拟按键输入,将指定的文本内容输入到对象中,通常用于输入框等需要用户输入信息的元素。

clear:清除对象输入的文本内容,用于将输入框中已有的文本清空,方便输入新的内容。

submit:用于提交表单,通常用于表单中的某些按钮,当按钮类型为 submit 时,可以使用该方法提交表单。

text:用于获取元素的文本信息,即元素中显示的文本内容,例如链接的文本、段落的文字等。

稍微归一下类:

  1. 鼠标点击或键盘输入

    • 如果需要模拟用户点击按钮、链接或者输入文本,可以使用相应的操作方法。
    • 使用 click() 方法来模拟鼠标点击元素,例如点击登录按钮或提交按钮。
    • 使用 send_keys() 方法来模拟键盘输入,将指定的文本内容输入到文本框或输入框中。
  2. 清除元素内容

    • 在某些情况下,可能需要清除输入框或文本框中已有的内容,以便输入新的内容。
    • 使用 clear() 方法来清除输入框或文本框中已有的文本内容,使其为空白。
  3. 提交表单

    • 对于表单页面,可能需要模拟用户提交表单的操作。
    • 使用 submit() 方法来提交表单,触发相应的提交操作。
  4. 其他操作

    • 还可以进行其他类型的操作,比如获取元素的文本内容、获取元素的属性值等。
    • 使用 text 属性来获取元素的文本信息,可以用于验证页面上显示的文本内容是否正确。

当然,测试对象的操作方法还有很多:

  1. 点击(Click):模拟用户点击对象,如按钮、链接等。
  2. 输入文本(Input Text):向文本框、输入框等输入数据。
  3. 清除文本(Clear Text):清除文本框、输入框中的已输入数据。
  4. 获取文本(Get Text):获取对象中显示的文本信息。
  5. 获取属性(Get Attribute):获取对象的属性值,如链接的URL、图片的源路径等。
  6. 提交表单(Submit Form):提交表单对象。
  7. 验证对象是否可见(Check Visibility):验证对象是否可见于页面上。
  8. 验证对象是否存在(Check Existence):验证对象是否存在于页面上。
  9. 验证对象状态(Check State):验证对象的状态,如是否可点击、是否可编辑等。
  10. 获取对象位置(Get Position):获取对象在页面上的位置信息,如坐标、尺寸等。
  11. 滚动到对象(Scroll To Element):将页面滚动到对象可见的位置。
  12. 鼠标悬停(Mouse Hover):模拟鼠标悬停在对象上的动作。
  13. 拖放(Drag and Drop):模拟拖动对象到指定位置的动作。
  14. 等待对象(Wait for Element):等待对象在页面上出现或符合特定条件。
  15. 切换窗口/帧(Switch Window/Frame):切换到对象所在的窗口或iframe。
  16. 执行JavaScript(Execute JavaScript):执行JavaScript代码与页面进行交互。
  17. 截图(Take Screenshot):对对象进行截图。
  18. 断言(Assert):验证对象的状态是否符合预期,如文本内容、属性值等。
  19. 日志记录(Log):记录测试过程中的操作和结果信息。
  20. 执行特定动作(Perform Specific Action):根据需要执行其他特定的操作,如点击键盘按键等。

在WebDriver中,操作对象的API主要包括以下几种方法:

  1. findElement(By by):根据指定的定位器(By对象)定位并返回单个 WebElement 对象。如果找不到元素,则会抛出 NoSuchElementException 异常。

  2. findElements(By by):根据指定的定位器(By对象)定位并返回一组 WebElement 对象列表。如果找不到任何元素,则返回空列表。

  3. WebElement click():点击此元素。

  4. WebElement submit():提交此元素,如果此元素是表单内的 <form> 元素,或者此元素是带有提交功能的元素(如 <input> 元素),则会提交该表单。

  5. void sendKeys(CharSequence... keysToSend):在此元素上模拟按键输入。键盘输入将会追加到当前元素的值的末尾。

  6. void clear():清除此元素上的文本。

  7. String getAttribute(String name):获取此元素的指定属性的值。

  8. String getText():获取此元素的文本内容。

  9. boolean isDisplayed():判断此元素是否可见。

  10. void submit():提交此元素,如果此元素是 <form> 元素,则提交该表单。

  11. void click():点击此元素。

  12. Point getLocation():获取此元素在页面上的位置。

  13. Dimension getSize():获取此元素的大小。

  14. String getTagName():获取此元素的标签名。

  15. String getCssValue(String propertyName):获取此元素的指定 CSS 属性的值。

这些方法可以用于定位、操作以及获取元素的信息。通过它们,我们可以完成对网页上各种元素的交互操作和状态获取。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test02();}private static void Test02() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到搜索输入框WebElement search_input = webDriver.findElement(By.cssSelector("#kw"));//向搜索输入框中输入“软件测试”search_input.sendKeys("软件测试");//找到“百度一下”文本进行点击WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//逻辑判断List<WebElement> search_results = webDriver.findElements(By.cssSelector("a em"));sleep(3000);for(int i =0;i<search_results.size();i++){if(search_results.get(i).getText().equals("软件测试"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}}

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {//Test01();//Test02();//Test03();//TureTest();//FalseTest();Test04();}private static void Test04() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");String baidu_button_text = webDriver.findElement(By.cssSelector("#su")).getAttribute("value");System.out.println("百度按钮文案是:"+baidu_button_text);}//用click不会报错private static void TureTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.click();//退出浏览器}//用submit会报错private static void FalseTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.submit();//退出浏览器}private static void Test03() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到搜索输入框WebElement search_input = webDriver.findElement(By.cssSelector("#kw"));//向搜索输入框中输入“软件测试”search_input.sendKeys("软件测试");//找到搜索输入框,并清空百度搜索输入框中的内容search_input.clear();//向搜索输入框中输入“前端开发”search_input.sendKeys("前端开发");//找到“百度一下”文本进行点击WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//校验结果是否正确List<WebElement> search_results = webDriver.findElements(By.xpath("//font[text()=\"web前端开发\"]"));for(int i =0;i<search_results.size();i++){if(search_results.get(i).getText().equals("web前端开发"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}private static void Test02() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到搜索输入框WebElement search_input = webDriver.findElement(By.cssSelector("#kw"));//向搜索输入框中输入“软件测试”search_input.sendKeys("软件测试");//找到“百度一下”文本进行点击WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//逻辑判断List<WebElement> search_results = webDriver.findElements(By.cssSelector("a em"));sleep(3000);for(int i =0;i<search_results.size();i++){if(search_results.get(i).getText().equals("软件测试"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}private static void Test01() {System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");WebElement search_input = webDriver.findElement(By.xpath("//form/span[1]/input"));if (search_input==null){System.out.println("测试不通过");} else {System.out.println("测试通过");}webDriver.quit();//webDriver.close();}
}

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {//Test01();//Test02();Test03();}private static void Test03() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到搜索输入框WebElement search_input = webDriver.findElement(By.cssSelector("#kw"));//向搜索输入框中输入“软件测试”search_input.sendKeys("软件测试");//找到搜索输入框,并清空百度搜索输入框中的内容search_input.clear();//向搜索输入框中输入“前端开发”search_input.sendKeys("前端开发");//找到“百度一下”文本进行点击WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//校验结果是否正确List<WebElement> search_results = webDriver.findElements(By.xpath("//font[text()=\"web前端开发\"]"));for(int i =0;i<search_results.size();i++){if(search_results.get(i).getText().equals("web前端开发"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}}

 

此时,将上述代码中的click方法改为submit方法,程序可以正常运行。

此处我们使用submit方法替代click方法不会报错的原因是因为百度搜索按钮(#su)是包含在一个<form>标签中的,而submit方法通常用于提交表单。在这种情况下,使用submit方法可以模拟用户按下了回车键或点击了提交按钮,从而触发表单提交操作。

当使用submit方法时,WebDriver会在找到的元素上调用提交操作,然后根据表单的设置执行提交行为。因此,即使#su按钮实际上是一个按钮元素,但由于它包含在<form>标签中,因此使用submit方法也可以顺利完成操作,而不会报错。

根据页面元素的实际情况选择使用click或submit方法是很重要的。在处理按钮时,我们通常使用click方法;而在处理表单时,我们可以尝试使用submit方法。

举个例子: 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {TureTest();//FalseTest();}//用click不会报错private static void TureTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.click();//退出浏览器}//用submit会报错private static void FalseTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.submit();//退出浏览器}}

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {//TureTest();FalseTest();}//用click不会报错private static void TureTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.click();//退出浏览器}//用submit会报错private static void FalseTest() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//找到“新闻”按钮,点击WebElement news_button = webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)"));news_button.submit();//退出浏览器}}

未正常跳转界面并报错: 

 

报错信息显示了JavaScript错误:"Unable to find owning document",这通常是由于调用了submit方法而导致的。在WebDriver中,submit方法用于将表单提交给服务器,但是在这种情况下,似乎并没有表单元素,因此调用submit方法会导致JavaScript错误。

在我们的FalseTest方法中,我们尝试对一个链接(即“新闻”按钮)使用submit方法,但是链接不是表单元素,因此调用submit方法会失败。

相反,我们在TureTest方法中使用的click方法是适当的,因为它用于单击按钮或链接。

因此,为了避免这个错误,我们应该只对表单元素使用submit方法,对于其他类型的元素,应该使用click方法。

添加等待 

添加强制等待:sleep休眠

在Java中,可以使用 Thread.sleep() 方法来实现休眠功能。这个方法接受一个参数,表示休眠的时间(以毫秒为单位),这里的休眠指固定休眠时间。

import java.util.concurrent.TimeUnit;// 休眠3秒钟
Thread.sleep(3000);

在这个例子中,Thread.sleep(3000) 表示线程将暂停执行3秒钟。

添加智能等待

在Java中,常见的时间单位包括:

  1. 秒(Seconds):以秒为单位的时间。
  2. 分钟(Minutes):以分钟为单位的时间。
  3. 小时(Hours):以小时为单位的时间。
  4. 毫秒(Milliseconds):以毫秒为单位的时间。
  5. 微秒(Microseconds):以微秒为单位的时间。
  6. 纳秒(Nanoseconds):以纳秒为单位的时间。

在Selenium WebDriver中,我们通常使用 TimeUnit 类来表示时间单位。常用的方法包括 TimeUnit.SECONDS、TimeUnit.MINUTES、TimeUnit.HOURS 等。这些时间单位用于设置隐式等待或其他时间相关的操作。

显示等待

显示等待是一种在代码中明确指定等待条件的等待方式。相比隐式等待,显示等待更加灵活,可以根据特定条件等待,而不是固定等待一段时间。这种等待方式使得测试脚本更加精确和可控。

在Selenium WebDriver中,显示等待通常通过 WebDriverWait 类来实现。WebDriverWait 类提供了 until 方法,允许指定一个期望条件(Expected Condition),并设置最长等待时间。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;// 创建 WebDriver 实例
WebDriver driver = new ChromeDriver();// 设置最长等待时间为10秒
WebDriverWait wait = new WebDriverWait(driver, 10);// 打开网页
driver.get("https://example.com");// 等待直到标题包含特定文本
WebElement element = wait.until(ExpectedConditions.titleContains("Example Domain"));// 进行其他操作,直到条件满足或超时

WebDriverWait 类接受 WebDriver 实例和最长等待时间作为参数。然后,通过 until 方法指定了一个期望条件(Expected Condition),即标题包含特定文本。WebDriver 会等待直到条件满足或超时,然后继续执行后续步骤。

显示等待的优势在于,它可以根据特定条件等待,而不是固定等待一段时间。这样可以提高测试脚本的执行效率和稳定性,特别是在处理异步加载或动态内容的情况下。

隐式等待

在Selenium WebDriver中,可以通过调用 implicitlyWait() 方法来实现隐式等待。这个方法接受一个参数,表示等待的超时时间(以秒为单位)。

当使用隐式等待时,WebDriver会在尝试定位元素时等待一定的时间,如果元素立即可用,则继续执行后续步骤;如果元素暂时不可用,WebDriver会以轮询的方式等待元素变为可用,直到超出设置的等待时长为止。

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;// 创建 WebDriver 实例
WebDriver driver = new ChromeDriver();// 设置隐式等待时间为30秒
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);// 进行其他操作,WebDriver 会在定位元素时智能等待,最长等待30秒

在这个示例中,driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS) 设置了隐式等待时间为30秒。这意味着,当需要定位元素时,WebDriver 会在最长30秒的时间内智能等待元素的出现,而不是固定地等待指定的时间。

隐式等待的优势在于,它可以根据页面加载情况自动调整等待时间,提高脚本的执行效率和稳定性。

打印信息

使用 Selenium WebDriver 打印网页标题和URL:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test05();}private static void Test05() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//获取百度页面titleString title = webDriver.getTitle();//逻辑判断if(title.equals("百度一下,你就知道"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test06();}private static void Test06() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//获取百度页面titleString url = webDriver.getCurrentUrl();//逻辑判断if(url.equals("https://www.baidu.com/"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}}

浏览器的操作

浏览器最大化

浏览器最大化是一种常见的操作,它可以让浏览器窗口占据整个屏幕空间,提供更清晰、更广阔的视野。这对于自动化测试来说尤为重要,因为它能够确保测试过程中的每个步骤都能够清晰可见,从而更方便地观察脚本的执行情况。虽然启动的浏览器默认情况下不是全屏显示,但通过使用 WebDriver 提供的 maximize() 方法,可以轻松实现浏览器最大化的效果,即使是在脚本执行期间也可以进行此操作。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test07();}private static void Test07() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//浏览器最大化webDriver.manage().window().maximize();sleep(3000);//定位到“换一换”这个元素String exp = webDriver.findElement(By.cssSelector("#hotsearch-refresh-btn > span")).getText();//逻辑判断if(exp.equals("换一换"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}
}

设置浏览器宽、高

有时候我们可能需要根据具体的测试需求来调整浏览器窗口的宽度和高度。在这种情况下,可以使用 WebDriver 提供的 setSize() 方法来设置浏览器窗口的尺寸,以便适应不同的测试场景。通过这种方式,我们可以灵活地调整浏览器的显示效果,使其符合测试的要求。

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test08();}private static void Test08() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//设置浏览器大小为200*200webDriver.manage().window().setSize(new Dimension(200,200));//校验百度搜索输入框是否存在//逻辑判断WebElement webElement = webDriver.findElement(By.cssSelector("#kw"));sleep(3000);if(webElement == null)System.out.println("测试不通过");elseSystem.out.println("测试通过");}}

操作浏览器的前进、后退

在进行自动化测试时,经常需要模拟用户在浏览器中点击“后退”和“前进”按钮的操作。WebDriver 提供了 navigate().back() 和 navigate().forward() 方法,可以实现这两种操作,从而更好地模拟用户在浏览器中的行为。

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test09();}private static void Test09() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“沙丘”webDriver.findElement(By.cssSelector("#kw")).sendKeys("沙丘");//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//浏览器后退webDriver.navigate().back();sleep(3000);//获取当前页面String url = webDriver.getCurrentUrl();//逻辑判断if(url.equals("https://www.baidu.com"))System.out.println("测试通过");elseSystem.out.println("测试不通过");}
}

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test10();}private static void Test10() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“沙丘”webDriver.findElement(By.cssSelector("#kw")).sendKeys("沙丘");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//浏览器后退webDriver.navigate().back();sleep(3000);//浏览器前进webDriver.navigate().forward();sleep(300);//获取当前的urlString url = webDriver.getCurrentUrl();System.out.println("当前的url: " + url);//逻辑判断if(url.equals("https://www.baidu.com"))System.out.println("测试不通过");elseSystem.out.println("测试通过");}
}

 

下面两者等价: 

webDriver.get("https://www.baidu.com");
webDriver.navigate().to("https://www.baidu.com");

控制浏览器滚动条

我们有时候可能需要控制浏览器的滚动条,以便查看页面上的不同部分内容。通过执行 JavaScript 脚本:document.documentElement.scrollTop=10000,就可以实现对浏览器滚动条的控制。例如,可以使用 window.scrollTo() 方法将页面滚动到指定的位置,从而方便查看页面上的特定元素或内容。这种方法对于需要在页面上执行特定操作的自动化测试非常有用,因为它可以确保测试脚本能够完整地执行,并且能够覆盖到页面的所有部分。

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test11();}private static void Test11() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“鲜花”webDriver.findElement(By.cssSelector("#kw")).sendKeys("鲜花");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//浏览器滚动条滑倒最下面((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");sleep(3000);}
}

键盘事件

键盘按键用法

使用Selenium WebDriver来模拟键盘按键和组合键的操作非常方便。

首先,需要导入Keys类:

import org.openqa.selenium.Keys;

然后,可以通过sendKeys()方法来调用单个按键:

WebElement element = driver.findElement(By.id("elementId"));
element.sendKeys(Keys.TAB); // 模拟按下TAB键
element.sendKeys(Keys.ENTER); // 模拟按下回车键
element.sendKeys(Keys.SPACE); // 模拟按下空格键
element.sendKeys(Keys.ESCAPE); // 模拟按下回退键(Esc)

如果需要模拟组合键,可以将多个键传递给sendKeys()方法:
 

element.sendKeys(Keys.CONTROL, "a"); // 模拟按下Ctrl+A,全选
element.sendKeys(Keys.CONTROL, "c"); // 模拟按下Ctrl+C,复制
element.sendKeys(Keys.CONTROL, "x"); // 模拟按下Ctrl+X,剪切
element.sendKeys(Keys.CONTROL, "v"); // 模拟按下Ctrl+V,粘贴

 

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test12();}private static void Test12() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“小猫”webDriver.findElement(By.cssSelector("#kw")).sendKeys("小猫");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//回车webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.ENTER);sleep(3000);//校验List<WebElement> webElements = webDriver.findElements(By.xpath("//*[@id=\"3001\"]/div/div[1]/div/div/h3/div/a/font"));sleep(3000);//逻辑判断for(int i =0;i<webElements.size();i++){if(webElements.get(i).getText().equals("小猫")){System.out.println("测试通过");break;} elseSystem.out.println("测试不通过");}}}

 

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test13();}private static void Test13() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“小猫”webDriver.findElement(By.cssSelector("#kw")).sendKeys("小猫");sleep(3000);//全选(Ctrl+A)webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");sleep(3000);//复制(Ctrl+C)//剪贴(Ctrl+X)webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"X");sleep(3000);//粘贴(Ctrl+V)webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(4000);//校验String unexpurl = "https://www.baidu.com";String cur_url = webDriver.getCurrentUrl();//逻辑判断if(cur_url.equals(unexpurl))System.out.println("测试不通过");elseSystem.out.println("测试通过");}
}

你可以看到输入框内电脑自行进行全选、剪切、复制操作: 

 鼠标事件

要使用鼠标事件,需要导入Actions类:

import org.openqa.selenium.interactions.Actions;

然后,可以使用Actions类来生成用户的行为。所有的行为都存储在Actions对象中,通过perform()方法执行:

Actions actions = new Actions(driver);

接下来是具体的鼠标事件操作:

// 鼠标移动到指定元素上
actions.moveToElement(element).perform();

这里是一些常见的鼠标事件:

// 右击
actions.contextClick().perform();// 双击
actions.doubleClick().perform();// 拖动
actions.dragAndDrop(sourceElement, targetElement).perform();// 移动到元素上
actions.moveToElement(element).perform();

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.util.List;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test14();}private static void Test14() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“企业微信”,搜索webDriver.findElement(By.cssSelector("#kw")).sendKeys("企业微信");webDriver.findElement(By.cssSelector("#su")).click();sleep(3000);//鼠标操作Actions actions = new Actions(webDriver);WebElement target = webDriver.findElement(By.cssSelector("#searchTag > div > div > a:nth-child(2) > span"));sleep(3000);actions.moveToElement(target).contextClick().perform();}}

如果右击要看到效果,需要执行一下perform。

鼠标挪动到了目标上:

窗口句柄


窗口句柄(Window Handle)是在浏览器窗口中唯一标识一个窗口的字符串。在 WebDriver 中,每个窗口都有一个唯一的窗口句柄,可以用来在多个窗口之间进行切换和操作。

通常情况下,当打开一个新的窗口或标签页时,WebDriver 会将新窗口的句柄存储在一个集合中。我们可以使用这些句柄来切换到新窗口,并在其上执行操作。

以下是一些关于窗口句柄的常见操作:

  • 获取当前窗口句柄:可以使用 getWindowHandle() 方法来获取当前窗口的句柄。
  • 获取所有窗口句柄:可以使用 getWindowHandles() 方法来获取所有当前打开窗口的句柄集合。
  • 切换到其他窗口:可以使用 switchTo().window() 方法并传入窗口句柄来切换到其他窗口。
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.util.List;
import java.util.Set;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test15();}private static void Test15() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//点击“新闻”按钮webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();sleep(3000);//获取到当前的窗口句柄String cur_handle = webDriver.getWindowHandle();System.out.println("当前的窗口句柄:" + cur_handle);Set<String> all_handle = webDriver.getWindowHandles();String target = "";//遍历当前浏览器所有窗口句柄for(String temp:all_handle){target = temp;}//切换窗口句柄至最后webDriver.switchTo().window(target);sleep(3000);//找到新闻搜索框,输入“经济头条”webDriver.findElement(By.cssSelector("#ww")).sendKeys("经济头条");sleep(3000);//找到搜索结果}}

 

这样也可以: 

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.util.List;
import java.util.Set;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException {Test15();}private static void Test15() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//点击“新闻”按钮webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();sleep(3000);//获取到当前的窗口句柄String cur_handle = webDriver.getWindowHandle();System.out.println("当前的窗口句柄:" + cur_handle);Set<String> all_handle = webDriver.getWindowHandles();//遍历当前浏览器所有窗口句柄for(String temp:all_handle){if(!temp.equals(cur_handle)){//切换窗口webDriver.switchTo().window(temp);}}sleep(3000);//找到新闻搜索框,输入“经济头条”webDriver.findElement(By.cssSelector("#ww")).sendKeys("经济头条");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#s_btn_wr"));baidu_button.click();sleep(3000);//找到搜索结果List<WebElement> webElements = webDriver.findElements(By.xpath("//em[text()=\"经济\"]"));for(int i =0;i<webElements.size();i++){if(webElements.get(i).getText().equals("经济")||webElements.get(i).getText().equals("头条")){System.out.println("测试通过");break;} elseSystem.out.println("测试不通过");}}}

 

通过Selenium进行截图

打开中央仓库,输入common-io:

 

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Test16();}private static void Test16() throws InterruptedException, IOException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度页面webDriver.get("https://www.baidu.com");//输入“小猫”webDriver.findElement(By.cssSelector("#kw")).sendKeys("小猫");sleep(3000);//点击“百度一下”按钮WebElement baidu_button = webDriver.findElement(By.cssSelector("#su"));baidu_button.click();sleep(3000);//截图File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File("E://截图_小猫.png"));webDriver.quit();}
}

 

定位一组元素

当我们需要在自动化测试中处理大量的页面元素时,findElements 方法就显得格外重要和实用了。它不仅可以让我们轻松地定位一组对象,还可以在这组对象中进行进一步的筛选和操作。

举例来说,在一个包含多个复选框的表单页面上,我们可能需要执行一系列操作,比如:

  1. 批量选择或取消选择: 可以通过 findElements  定位所有的复选框,然后依次对它们执行勾选或取消勾选的操作,而无需逐个定位。

  2. 获取一组元素的属性值: 有时我们需要获取一组元素的共同属性,比如获取所有复选框的状态或值,这时候可以利用 findElements 遍历并获取每个元素的属性值。

  3. 执行批量验证: 在某些情况下,我们需要验证页面上某一类元素是否都符合预期,这时候可以使用 findElements  定位所有符合条件的元素,然后逐一进行验证。

此外,findElements  还可以与其他定位方法结合使用,例如先定位到一个包含一组元素的父元素,然后再使用 findElements  在其范围内定位子元素,这种方法可以减少定位元素的范围,提高查找效率。

综上,findElements 方法为自动化测试提供了更加灵活和高效的定位方式,使得我们能够更好地处理页面上的多个元素,从而更加高效地完成测试任务。

用以下HTML示例说明:

<!DOCTYPE html>
<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>Checkbox</title>
</head>
<body>
<h3>checkbox</h3>
<div class="well"><form class="form-horizontal"><div class="control-group"><label class="control-label" for="c1">checkbox1</label><div class="controls"><input type="checkbox" id="c1" /></div></div><div class="control-group"><label class="control-label" for="c2">checkbox2</label><div class="controls"><input type="checkbox" id="c2" /></div></div><div class="control-group"><label class="control-label" for="c3">checkbox3</label><div class="controls"><input type="checkbox" id="c3" /></div></div><div class="control-group"><label class="control-label" for="r1">radio</label><div class="controls"><input type="radio" id="r1" /></div></div><div class="control-group"><label class="control-label" for="r2">radio</label><div class="controls"><input type="radio" id="r2" /></div></div></form>
</div>
</body>
</html>

用浏览器打开这个页面我们看到三个复选框和两个单选框。

下面我们就来定位这三个复选框。 

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page01();}private static void Page01() {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开网页test01页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test01.html?_ijt=bgm0t7qr1jknhme2vl5rubbir1&_ij_reload=RELOAD_ON_SAVE");List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));for(int i = 0; i < webElements.size(); i++) {if(webElements.get(i).getAttribute("type").equals("checkbox")) {webElements.get(i).click();}}}}

多层框架/窗口定位


在 Java 平台下,处理 web 应用中的框架(frame)或窗口(window)的定位问题是很常见的,因为这些框架或窗口的存在给定位元素带来了一定的困难。幸运的是,Selenium 提供了一些方法来处理这种情况。

对于定位一个 frame,我们可以使用 switch_to.frame(name_or_id_or_frame_element) 方法。这个方法可以接受 frame 的 ID、name 或者 frame 元素本身作为参数,将当前的定位主体切换到指定的 frame 中,从而可以在该 frame 中定位元素。

而对于定位一个窗口(window),我们同样可以使用 switch_to.window(name_or_id_or_frame_element) 方法。这个方法也接受窗口的 ID、name 或者窗口元素本身作为参数,将当前的定位主体切换到指定的窗口中,以便定位窗口中的元素。

多层框架的定位

当处理多层框架时,我们可能需要在不同的 frame 之间进行切换。使用 switch_to.frame() 方法可以很方便地实现这一目的。通过指定不同的 frame 的 ID、name 或者 frame 元素,我们可以在多层嵌套的框架中进行定位操作。

同时,为了跳出嵌套的 frame,返回到最外层的默认页面,我们可以使用 switch_to.default_content() 方法。这个方法会将当前的定位主体从当前的 frame 中跳出,返回到最外层的默认页面中,以便进行下一步的定位操作。

用以下HTML示例说明:

test02.html:

<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>frame</title><!--  <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />--><script type="text/javascript">$(document).ready(function(){});</script>
</head>
<body>
<div class="row-fluid"><div class="span10 well"><h3>frame</h3><iframe id="f1" src="inner.html" width="800", height="600"></iframe></div>
</div>
</body>
<!--<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>-->
</html>

Inner.html:

<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>inner</title>
</head>
<body>
<div class="row-fluid"><div class="span6 well"><h3>inner</h3><iframe id="f2" src="https://www.baidu.com/"width="700"height="500"></iframe><a href="javascript:alert('watir-webdriver better than selenium webdriver;')">click</a></div>
</div>
</body>
</html>

 

 下面通过switch_to.frame() 方法来进行定位:

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page02();}private static void Page02() throws InterruptedException {//创建一个浏览器驱动器System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开test02.html网页页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test02.html?_ijt=v8d2pl92h521nf2sqri2u8im5d&_ij_reload=RELOAD_ON_SAVE");webDriver.switchTo().frame("f1");sleep(3000);//选择click并点击webDriver.findElement(By.cssSelector("body > div > div > a")).click();}
}

多层窗口定位

在处理 web 应用时,我们可能会遇到嵌套窗口而不是框架的情况。针对这种情况,Selenium WebDriver 提供了 switch_to.window 方法,用于在不同的窗口之间进行切换,这与处理框架时使用的 switch_to.frame 方法相似。

使用 switch_to.window("windowName") 方法,我们可以将当前的定位主体切换到指定名称的窗口中。其中,"windowName" 参数可以是窗口的名称或句柄。

例如,假设我们的 web 应用中有一个名为 "popupWindow" 的弹出窗口,我们可以使用以下代码来切换到该窗口:

driver.switch_to.window("popupWindow");

这样,WebDriver 将当前的定位主体切换到名为 "popupWindow" 的窗口中,使得我们能够在该窗口中进行后续的元素定位和操作。

层级定位

在自动化测试中,有时我们需要定位的元素并不直接在页面中展示,而是需要在执行一系列操作后才会显示出来。这种情况下,我们需要通过一层层的操作来定位元素。

针对这种情况,我们可以采用以下定位思路:

  1. 点击操作触发下拉菜单的显示: 首先,我们需要执行点击操作来触发页面上的下拉菜单显示。这可能涉及点击按钮、链接或者其他交互元素。

  2. 定位到下拉菜单所在的容器元素: 下一步是定位到包含下拉菜单的容器元素,这个容器元素通常是一个 div 或 ul 元素。我们可以使用 Selenium 提供的定位方法来找到这个容器元素。

  3. 定位目标元素: 一旦下拉菜单显示出来,我们就可以在该容器元素的子元素中定位目标元素。这可能涉及到找到下拉菜单的子菜单、链接或其他元素。

在这个过程中,需要使用 Selenium WebDriver 提供的等待机制来确保页面上的元素已经加载完毕,以及使用定位方法来准确定位到目标元素。通常情况下,使用显示等待(Explicit Wait)来等待特定条件的满足是一种常见的做法,例如等待元素可见、元素存在、元素被点击等。

用以下HTML示例说明:

<!DOCTYPE html>
<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>Level Locate</title><script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script><link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />
</head>
<body><h3>Level locate</h3><div class="span3"><div class="well"><div class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Link1</a><ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" id="dropdown1"><li><a tabindex="-1" href="#">Action</a></li><li><a tabindex="-1" href="#">Another action</a></li><li><a tabindex="-1" href="#">Something else here</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Separated link</a></li></ul></div></div></div><div class="span3"><div class="well"><div class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Link2</a><ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"><li><a tabindex="-1" href="#">Action</a></li><li><a tabindex="-1" href="#">Another action</a></li><li><a tabindex="-1" href="#">Something else here</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Separated link</a></li></ul></div></div></div><script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</body>
</html>

如果我们要定位第一个下拉菜单中的 "Action" 选项,定位思路如下:

  1. 首先,我们需要执行点击操作来触发第一个下拉菜单的显示。
  2. 然后,我们需要定位到包含第一个下拉菜单的容器元素,通常是一个 ul 元素。
  3. 最后,我们在该容器元素中定位具体的 "Action" 选项链接,可能需要使用链接文本或其他属性来定位。

在实现这个定位过程时,我们需要结合使用 Selenium 的点击操作、等待机制和定位方法来确保准确地定位到目标元素。这样,我们就能够应对页面元素通过一系列操作后才展示出来的情况,并成功地定位到我们需要的元素。

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page00();}private static void Page00() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver driver = new ChromeDriver();// 设置隐式等待时间driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);// 打开网页driver.get("http://localhost:63342/AutoTest1/preparation/terminal.html?_ijt=6octqmsvlnfuem51he79d1tq37&_ij_reload=RELOAD_ON_SAVE");// 点击 Link1 链接(弹出下拉列表)WebElement link1 = driver.findElement(By.linkText("Link1"));link1.click();// 在父元素下找到 link 文本为 "Action" 的子元素WebElement dropdownMenu = driver.findElement(By.id("dropdown1")).findElement(By.linkText("Action"));// 使用 Actions 类实现鼠标悬停到子元素上Actions action = new Actions(driver);action.moveToElement(dropdownMenu).perform();// 等待 2 秒,方便观察效果Thread.sleep(2000);// 关闭浏览器driver.quit();}
}

下拉框处理 

下拉框(下拉菜单)是网页中常见的交互元素之一,但与一般的元素不同,需要进行两次定位才能操作其中的选项。

通常情况下,我们首先需要定位到下拉框本身,然后对其进行操作以展开选项。接着,我们才能再次定位到下拉框内部的选项元素,以进行具体的选择操作。

这个两步定位的过程对应了下拉框的两个不同层级:第一层级是下拉框本身,第二层级是下拉框内部的选项。

总的来说,对于下拉框的操作,我们需要采取以下步骤:

  1. 定位下拉框本身: 使用合适的定位方法找到下拉框的元素,通常是一个按钮或链接。
  2. 操作下拉框: 对下拉框进行操作,比如点击或悬停,以展开选项。
  3. 定位选项: 一旦下拉框展开,就可以再次定位到内部的选项元素,通常是一个列表,然后选择所需的选项。

这种两步定位的模式在处理下拉框时非常常见,因为下拉框的结构和行为决定了我们需要两次定位才能进行有效的操作。因此,我们需要确保对下拉框的每个步骤都进行准确的定位和操作,以保证测试的准确性和可靠性。

用以下HTML示例说明:

<html>
<body>
<select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod"><option value="12.51">UPS Next Day Air ==> $12.51</option><option value="11.61">UPS Next Day Air Saver ==> $11.61</option><option value="10.69">UPS 3 Day Select ==> $10.69</option><option value="9.03">UPS 2nd Day Air ==> $9.03</option><option value="8.34">UPS Ground ==> $8.34</option><option value="9.25">USPS Priority Mail Insured ==> $9.25</option><option value="7.45">USPS Priority Mail ==> $7.45</option><option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>

现在我们来通过脚本选择下拉列表里的$10.69:

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page03();}private static void Page03() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver webDriver = new ChromeDriver();// 打开目标页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test03.html?_ijt=9b8p6ro4c9sse954nld1u8m9pl&_ij_reload=RELOAD_ON_SAVE");// 借助Select对象WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select = new Select(webElement);//这是第一种方式// 通过序号选中选项,下标和之前学习的数组一样的,下标是从0开始select.selectByIndex(2);sleep(3000);}
}

    private static void Page03() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver webDriver = new ChromeDriver();// 打开目标页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test03.html?_ijt=6c4qfkdvumfp0jflg7qeg4imnk&_ij_reload=RELOAD_ON_SAVE");// 借助Select对象WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select = new Select(webElement);//这是第二种方式,这里的8.34是option标签里面value的值select.selectByValue("8.34");}

alert、confirm、prompt 的处理


处理网页中的 alert、confirm 和 prompt 是在自动化测试中常见的任务。

以下是对它们的处理方式:

  • text: 用于获取 alert、confirm 或 prompt 对话框中显示的文本信息。通过 switch_to.alert().getText() 方法可以获取到这些文本信息。
  • accept: 用于点击对话框中的确认按钮。通过 switch_to.alert().accept() 方法可以执行这个操作。
  • dismiss: 用于点击对话框中的取消按钮(如果存在的话)。通过 switch_to.alert().dismiss() 方法可以执行这个操作。
  • send_keys: 用于向对话框中输入文本。但是需要注意,只有对于 prompt 对话框,才能使用 send_keys 方法。如果尝试在 alert 或 confirm 对话框上使用 send_keys 方法,会导致报错。例如:
    switch_to.alert().sendKeys("input text");
    

    需要强调的是,switch_to.alert() 只能处理原生的 JavaScript 弹窗,即浏览器自带的对话框,而无法处理自定义样式或通过 JavaScript 实现的模态框。如果页面上出现了非原生的弹窗,我们需要采用其他方法进行处理,例如使用 WebDriver 的其他方法模拟对话框的行为。

用以下HTML示例说明:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<button onclick="Click()">这是一个弹窗</button>
</body>
<script type="text/javascript">function Click() {let name = prompt("请输入姓名:");let parent = document.querySelector("body");let child = document.createElement("div");child.innerHTML = name;parent.appendChild(child)}
</script>
</html>

 

 

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page04();}private static void Page04() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver webDriver = new ChromeDriver();webDriver.get("http://localhost:63342/AutoTest1/preparation/test04.html?_ijt=oo9voh03jblsp9el5vmbt9c6o0&_ij_reload=RELOAD_ON_SAVE");sleep(3000);// 点击页面上按钮,出现弹窗webDriver.findElement(By.cssSelector("body > button")).click();sleep(3000);// 点击了弹窗里面的取消webDriver.switchTo().alert().dismiss();// 点击页面上按钮,出现弹窗webDriver.findElement(By.cssSelector("body > button")).click();String name = "Dora";// 弹窗里面输入DorawebDriver.switchTo().alert().sendKeys(name);sleep(3000);// 弹窗确认webDriver.switchTo().alert().accept();sleep(3000);String text = webDriver.findElement(By.cssSelector("body > div:nth-child(4)")).getText();if (text.equals(name)) {System.out.println("测试通过");} else {System.out.println("测试不通过");}}
}

当alert中有对话框,而我们期望在alert的对话框中输入信息的时候要怎么处理呢?

用以下HTML示例说明:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><script type="text/javascript">function disp_prompt() {var name = prompt("Please enter your name", "");if (name != null && name != "") {document.write("Hello " + name + "!");}}</script>
</head>
<body>
<input type="button" onclick="disp_prompt()" value="请点击"/>
</body>
</html>

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page04_2();}private static void Page04_2() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver driver = new ChromeDriver();// 设置隐式等待时间driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);// 打开网页driver.get("http://localhost:63342/AutoTest1/preparation/test04_2.html?_ijt=3moi9kbhpbu3dcu3l40i4h4cbu&_ij_reload=RELOAD_ON_SAVE"); // 请替换为实际的 HTML 文件路径// 点击按钮,触发提示框WebElement button = driver.findElement(By.xpath("/html/body/input"));button.click();// 等待提示框出现Alert alert = driver.switchTo().alert();// 输入内容并确认alert.sendKeys("Dora");alert.accept();// 等待 5 秒,方便观察效果Thread.sleep(5000);// 关闭浏览器driver.quit();}
}

上传文件操作

文件上传操作是常见的网页功能之一,它并不需要使用新的方法或函数,关键在于正确的思路和操作方式。

通常,文件上传过程涉及打开一个本地窗口,然后从该窗口选择要上传的本地文件。因此,最困难的部分在于如何操作这个本地窗口来添加上传文件。

然而,在 Selenium WebDriver 中,处理文件上传并不像我们想象的那么复杂。实际上,我们只需要定位到上传按钮,然后使用 send_keys 方法来添加本地文件路径即可。无论是使用绝对路径还是相对路径都可以,关键是确保要上传的文件存在于指定的路径中。

这种简单直接的方法使得文件上传操作变得非常容易,并且适用于各种类型的文件上传场景。

用以下HTML示例说明:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="file">
</body>
</html>

 

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page05();}private static void Page05() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver webDriver = new ChromeDriver();// 打开目标页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test05.html?_ijt=q1evmi2otu256uese439pc4ajm&_ij_reload=RELOAD_ON_SAVE");sleep(3000);// 上传文件webDriver.findElement(By.cssSelector("body > input[type=file]")).sendKeys("D:\\二十大报告.txt");}
}

DIV对话框的处理

通常情况下,我们将某个元素的直接容器或包裹元素称为它的父级元素,这个容器或包裹元素往往是一个 DIV 块。在 HTML 中,DIV 元素通常被用来创建容器,它可以将相关的内容组织在一起,并且可以通过 CSS 样式进行布局和设计。因此,当我们在定位元素时提到父级元素,通常指的是它所在的 DIV 块或其他容器元素。

当页面元素较多,利用元素的属性无法准确地定位某个元素时,可以采取定位元素所在的父级元素,然后再去定位目标元素的策略。

这种策略的思路是,如果目标元素的属性无法唯一地标识,但它所在的父级元素具有唯一的标识属性或者特征,我们可以先定位父级元素,然后在其内部再定位目标元素。

通过定位父级元素,我们可以缩小搜索范围,使得定位目标元素更加准确可靠。这样做的好处是能够提高定位的精确度,减少定位失败的可能性,同时也使得测试脚本更加健壮可靠。

总之,定位父级元素再定位目标元素是一种有效的策略,可以在遇到难以准确定位的元素时提供一种解决方案。

用以下HTML示例说明:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>modal</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />
<script type="text/javascript">
$(document).ready(function(){$('#click').click(function(){$(this).parent().find('p').text('Click on the link to success!');});
});
</script>
</head>
<body>
<h3>modal</h3>
<div class="row-fluid"><div class="span6"><!-- Button to trigger modal --><a href="#myModal" role="button" class="btn btn-primary" data-toggle="modal" id="show_modal">Click</a><!-- Modal --><div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h3 id="myModalLabel">Modal header</h3></div><div class="modal-body"><p>Congratulations, you open the window!</p><a href="#" id="click">click me</a></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">Close</button><button class="btn btn-primary">Save changes</button></div></div></div>
</div>
</body>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</html>

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;public class Main {public static void main(String[] args) throws InterruptedException, IOException {Page06();}private static void Page06() throws InterruptedException {// 设置 Chrome 驱动器路径System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");// 创建 Chrome 驱动器实例WebDriver webDriver = new ChromeDriver();// 打开目标页面webDriver.get("http://localhost:63342/AutoTest1/preparation/test06.html?_ijt=mgh4kagfrb1qa4qfkvj40uhurf&_ij_reload=RELOAD_ON_SAVE");// 等待页面加载完成Thread.sleep(3000);// 点击打开对话框按钮WebElement openDialogButton = webDriver.findElement(By.id("show_modal"));openDialogButton.click();// 等待对话框弹出Thread.sleep(3000);// 在对话框中点击链接WebElement linkInModal = webDriver.findElement(By.id("myModal")).findElement(By.id("click"));linkInModal.click();// 等待一段时间Thread.sleep(4000);// 关闭对话框List<WebElement> buttons = webDriver.findElement(By.className("modal")).findElement(By.className("modal-footer")).findElements(By.tagName("button"));buttons.get(0).click();// 等待一段时间Thread.sleep(2000);// 关闭浏览器webDriver.quit();}
}

相关文章:

测试开发(6)软件测试教程——自动化测试selenium(自动化测试介绍、如何实施、Selenium介绍 、Selenium相关的API)

接上次博客&#xff1a;测试开发&#xff08;5&#xff09;测试分类标准 &#xff1a;按测试对像划分、按是否查看代码划分、按开发阶段划分、按测试实施组织、按是否运行划分、按是否手工划分、按测试地域划分-CSDN博客 目录​​​​​​​ 什么是自动化测试 自动化测试介绍…...

【flink】Rocksdb TTL状态全量快照持续递增

flink作业中的MapState开启了TTL&#xff0c;并且使用rocksdb作为状态后端配置了全量快照方式&#xff08;同时启用全量快照清理&#xff09;&#xff0c;希望能维持一个平稳的运行状态&#xff0c;但是经观察后发现效果不达预期&#xff0c;不仅checkpoint size持续缓慢递增&a…...

[C++] 统计程序耗时

一、简介 本文介绍了两种在C代码中统计耗时的方法&#xff0c;第一种使用<time.h>头文件中的clock()函数记录时间戳&#xff0c;统计程序耗时。第二种使用<chrono>头文件中的std::chrono::high_resolution_clock()::now()函数&#xff0c;后者可以方便地统计不同时…...

Redis是单线程还是多线程?

单线程为什么这么快的原因&#xff1a; 后来引入了多线程是因为&#xff1a;...

【MySQL】MySQL数据管理——DDL数据操作语言(数据表)

目录 创建数据表语法列类型字段属性SQL示例创建学生表 查看表和查看表的定义表类型设置表的类型 面试题&#xff1a;MyISAM和InnoDB的区别设置表的字符集删除表语法示例 修改表修改表名语法示例 添加字段语法示例 修改字段语法示例 删除字段语法示例 数据完整性实体完整性域完整…...

Qt使用QSettings类来读写ini

在Qt中&#xff0c;可以使用QSettings类来读写ini文件。QSettings提供了一个简单的接口&#xff0c;用于访问和修改ini文件中的键值对。 下面是使用QSettings类来写入ini文件的示例代码&#xff1a; #include <QCoreApplication> #include <QSettings>int main(i…...

嵌入式软件bug从哪里来,到哪里去

摘要&#xff1a;软件从来不是一次就能完美的&#xff0c;需要以包容的眼光看待它的残缺。那问题究竟为何产生&#xff0c;如何去除呢&#xff1f; 1、软件问题从哪来 软件缺陷问题千千万万&#xff0c;主要是需求、实现、和运行环境三方面。 1.1 需求描述偏差 客户角度的描…...

去掉WordPress网页图片默认链接功能

既然是wordpress自动添加的&#xff0c;那么我们在上传图片到wordpress后台多媒体的时候&#xff0c;就可以手动改变链接指向或者删除掉&#xff0c;问题是每次都要这么做很麻烦&#xff0c;更别说有忘记的时候。一次性解决这个问题有两种方法&#xff0c;一种是No Image Link插…...

UE学习笔记--解决滚轮无法放大蓝图、Panel等

我们发现有时候创建蓝图之后&#xff0c;右上角的缩放是1&#xff1a;1 但是有时候我们可能需要放的更大一点。 发现一直用鼠标滚轮像上滚动&#xff0c;都没有效果。 好像最大只能 1&#xff1a;1. 那是因为 UE 做了限制。如果希望继续放大&#xff0c;我们可以按住 Ctrl 再去…...

GO结构体

1. 结构体 Go语言可以通过自定义的方式形成新的类型&#xff0c;结构体就是这些类型中的一种复合类型&#xff0c;结构体是由零个或多个任意类型的值聚合成的实体&#xff0c;每个值都可以称为结构体的成员。 结构体成员也可以称为“字段”&#xff0c;这些字段有以下特性&am…...

芯科科技为全球首批原生支持Matter-over-Thread的智能锁提供强大助力,推动Matter加速成为主流技术

智能锁领域的先锋企业U-tec和Nuki选择芯科科技解决方案&#xff0c;成为Matter-over-Thread应用的领先者 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今…...

面试数据库篇(mysql)- 06覆盖索引

原理 覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。 id name gender createdate 2 Arm...

[伴学笔记]01-操作系统概述 [南京大学2024操作系统]

文章目录 前言jyy:01-操作系统概述 [南京大学2024操作系统]为什么要学操作系统?学习操作系统能得到什么? 什么是操作系统?想要明白什么是操作系统:时间线:1940s1950s-1960s1960-1970s年代. 信息来源: 前言 督促自己,同时分享所得,阅读完本篇大约需要10分钟,希望为朋友的技术…...

c++二叉树

二叉树进阶 1.二叉搜索树(binary search tree) ​ 二叉搜索树天然就适合查找&#xff0c;对于满二叉树或者完全二叉树&#xff0c;最多搜索lgn次(就像是有序数组二分查找&#xff0c;每次搜索都会减少范围)&#xff0c;极端情况简化成单链表就要走n次&#xff0c;即要走高度次…...

第19章-IPv6基础

1. IPv4的缺陷 2. IPv6的优势 3. 地址格式 3.1 格式 3.2 长度 4. 地址书写压缩 4.1 段内前导0压缩 4.2 全0段压缩 4.3 例子1 4.4 例子 5. 网段划分 5.1 前缀 5.2 接口标识符 5.3 前缀长度 5.4 地址规模分类 6. 地址分类 6.1 单播地址 6.2 组播地址 6.3 任播地址 6.4 例子 …...

浅谈人才招聘APP开发的解决方案

随着企业竞争加剧&#xff0c;高效、精准地招聘人才成为企业持续发展的关键。人才招聘系统能够简化招聘流程&#xff0c;提高效率&#xff0c;确保企业快速找到合适人才。同时&#xff0c;通过智能匹配和数据分析&#xff0c;提升招聘质量&#xff0c;优化候选人体验。因此&…...

大语言模型LLM推理加速:Hugging Face Transformers优化LLM推理技术(LLM系列12)

文章目录 大语言模型LLM推理加速:Hugging Face Transformers优化LLM推理技术(LLM系列12)引言Hugging Face Transformers库的推理优化基础模型级别的推理加速策略高级推理技术探索硬件加速与基础设施适配案例研究与性能提升效果展示结论与未来展望大语言模型LLM推理加速:Hug…...

JVM 第四部分—垃圾回收相关概念 2

System.gc() 在默认情况下&#xff0c;通过System.gc()或者Runtime.getRuntime().gc()的调用&#xff0c;会显式触发Full GC&#xff0c;同时对老年代和新生代进行回收&#xff0c;尝试释放被丢弃对象占用的内存 然而System.gc()调用附带一个免责声明&#xff0c;无法保证对垃…...

tritonserver学习之八:redis_caches实践

tritonserver学习之一&#xff1a;triton使用流程 tritonserver学习之二&#xff1a;tritonserver编译 tritonserver学习之三&#xff1a;tritonserver运行流程 tritonserver学习之四&#xff1a;命令行解析 tritonserver学习之五&#xff1a;backend实现机制 tritonserv…...

2024有哪些免费的mac苹果电脑深度清理工具?CleanMyMac X

苹果电脑用户们&#xff0c;你们是否经常感到你们的Mac变得不再像刚拆封时那样迅速、流畅&#xff1f;可能是时候对你的苹果电脑进行一次深度清理了。在这个时刻&#xff0c;拥有一些高效的深度清理工具就显得尤为重要。今天&#xff0c;我将介绍几款优秀的苹果电脑深度清理工具…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...