文章目录
Selenium
是一个用于Web应用程序测试的工具
- Selenium IDE,是浏览器的扩展插件,支持用户录制和回放测试
- Selenium WebDrive,提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。
- SeleniumGrid,分布式自动化工具,可以在多个测试环境中以并发的方式执行测试脚本,实现测试脚本的并发执行,缩短大量的测试脚本的执行时间
用于Web应用程序测试的工具,Selenium是开源并且免费的,Selenium测试直接在浏览器中运行,就像真实用户所作的一样
支持多种操作系统、多种浏览器、多种编程语言
特点
- 开源软件:可以根据需求来增加工具的某些功能
- 跨平台:unix、windows
- 核心功能:可以在多个浏览器上进行自动化测试
- 多语言:Java、Python、C#、JS、Ruby等
- 程序稳定:目前已经被google、百度、腾讯广泛使用
- 功能强大:能够实现类似商业工具的大部分功能,因为开源行,可实现定制功能
Maven引入selenium框架/初始化
方法一
<!--selenium依赖-->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.4.0</version>
</dependency>
package com.test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class FirstWebTest{
public static void openChrome(){
//chrome驱动
System.setPropery("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
//打开chrome浏览器
ChromeDriver chromeDriver = new ChromeDriver();
//访问google
chromeDrvier.get("https://www.google.com");
}
public static void openFireFox(){
//firefox安装路径
System.setProperty("webriver.firefox.bin","FireFox_Path");
//firefox驱动
FirefoxDriver firefoxDriver = new FirefoxDriver();
//访问bing
firefoxDriver.get("https://www.bing.com");
}
public static void OpenIE(){
//IE驱动
System.setProperty("webdriver.ie.driver","src/test/resources/IeDriverServer.exe");
//IE保护模式解决方案01
//打开IE浏览器->工具->安全->全部勾选启用保护模式
//不推荐
//IE保护模式解决方案02
//取消IE安全设置(忽略IE的Protexted Mode的设置)
DesiredCapadbilities capabilities = new DesiredCapabilities();
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);
//IE浏览器缩放设置
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING,true);
//1.打开IE浏览器
InternetExplorerDriver ieDriver = new InternetExplorerDriver();
//2.打开baidu
ieDriver.get("https://www.baidu.com");
}
}
方法二
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.6.2</version>
<scope>test</scope>
</dependency>
//Call any of the line based on which browser you are using.
WebDriverManager.chromedriver().setup();
WebDriverManager.firefoxdriver().setup();
WebDriverManager.iedriver().setup();
WebDriverManager.operadriver().setup();
WebDriverManager.phantomjs().setup();
WebDriverManager.edgedriver().setup();
方法三
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.6.0</version>
</dependency>
元素定位
-
id:根据id来获取元素,返回单个元素,id值一般是唯一的
<p id="a" name="b" class="c"></p> #id为a chromeDriver.findElementById("a"); #定位id为a的元素
-
name:根据元素的name属性来获取元素,可能返回元素集合
<p id="a" name="b" class="c"></p> #name为b chromeDriver.findElementByName("b"); #定位到name为b的元素
-
tagName:根据元素的标签名来获取元素,可能返回元素集合
<p id="a" name="b" class="c"></p> #标签名为p chromeDriver.findElementByTagName("p"); #定位到标签名为p的元素
-
className:根据元素的class值来获取元素,可能返回元素集合
<p id="a" name="b" class="c"></p> #class值为c chromeDriver.findElementByClassName("c"); #定位到class值为c的元素
-
linkText:根据超链接的文本值来获取元素
<a href="www.baidu.com">百度</a> #超链接的完整文本值为 百度 chromeDriver.findElementByLinkText("百度").click(); #定位到文本值为百度的超链接并点击
-
partialLinkText:根据超链接的部分文本值来获取元素
<a href="www.baidu.com">百度</a> #超链接的完整文本值为 百度 chromeDriver.findElementByPartialLinkText("百"); #定位到超链接的文本值中含有“百"的元素
-
cssSelector
-
根据tagName
chromeDriver.findElementByCssSelector("input");
-
根据ID
chromeDriver.findElementByCssSelector("#text"); //id为text
-
根据className(样式名)
chromeDriver.findElementByCssSelector(".className"); //class值为className
-
css精确定位
根据元素属性,属性名=属性值,id、class等都可以写成这种形式
chromeDriver.findElementByCssSelector("input[name='xxx']")
多属性
chromeDriver.findElementByCssSelector("input[name='xxx'][class='xxx']")
-
-
xpath
xpath其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标。
xpath基于XML文档树状结构,是XML路径语言,用来查询xml文档中的节点
-
绝对定位
从根目录开始找
/html/body/div[2]/div/form/input
缺点:一旦页面结构发生变化(比如重新设计时,路径少了两节),该路径也随之失效,必须重新写
-
相对路径
//*[@name='phone']
匹配name=‘phone’的所有元素//a[text()='新闻']
匹配文本值为新闻
的超链接//a[contains(text(),'新')]
匹配文本值含有新
的超链接元素路径解释
- //匹配指定节点,不考虑它们的位置
- *通配符,匹配任意元素节点
- @选取属性
- []属性判断条件表达式
相对定位优点:
灵活、方便、耦合性低
-
元素操作API
-
click()
触发当前元素的点击事件
-
clear()
清空内容
-
sendKeys()
往文本框一类元素中写入内容
element.sendKeys(Keys.CONTROL,"a");//ctrl+a element.sendKeys(Keys.CONTROL,"X");//ctrl+x element.sendKeys(Keys.CONTROL,"c");//ctrl+c element.sendKeys(Keys.CONTROL,"v");//ctrl+v element.sendKeys(Keys.ENTER);//回车 element.sendKeys(Keys.BACK_SPACE);//删除 element.sendKeys(Keys.SPACE);//空格
-
getTagName()
获取元素的标签名
-
getAttribute()
根据属性名获取元素属性值
-
getText()
获取当前元素的文本值
-
isDisplayed()
查看元素是否显示
WebDriver相关API
-
get(String url)
访问指定url页面
-
getCurrentUrl()
获取当前页面的url地址
-
getTitle()
获取当前页面的标题
-
getPageSource()
获取当前页面源代码
-
quit()
关闭驱动对象以及所有相关的窗口
-
close()
关闭当前窗口
-
getWindowHandle()
返回当前页面句柄
-
getWindowHandles()
返回所有由驱动对象打开页面所有的句柄,页面不同,句柄不一样
-
manage()
此方法可以获取Options——浏览器菜单操作对象
driver.manage().window()
Options options = chromeDriver.manage(); Dimension dimension=null; options.window().fullscreen();//全屏 Thread.sleep(3000); dimension = options.window().getSize(); System.out.println("窗口的高度\t"+dimension.getHeight()+"\n窗口的宽度\t"+dimension.getWidth()); System.out.println("窗口的坐标\t"+options.window().getPosition().getX()+","+options.window().getPosition().getY()); options.window().maximize();//最大化 Thread.sleep(3000); dimension = options.window().getSize(); System.out.println("窗口的高度\t"+dimension.getHeight()+"\n窗口的宽度\t"+dimension.getWidth()); System.out.println("窗口的坐标\t"+options.window().getPosition().getX()+","+options.window().getPosition().getY());
-
navigate对象
Navigation navigation = driver.navigate(); //获取navigate对象 navigation.to(url); //访问指定的url地址 navigation.refresh(); //刷新当前页面 navigation.back(); //浏览器回退操作 navigation.forward(); //浏览器前进操作
等待
硬性等待
Thread.sleep(long millis)
线程休眠,强制等待
隐式等待
driver.manage.timeouts().implicitlyWait(long time,TimeUnit)
在设置的超时时间范围内不断查找元素,直到找到元素或者超时
优点:相对灵活
缺点:设置时针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待。
private ChromeDriver chromeDriver;
private Navigation navigation;
@Before
public void setUp() {
System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
chromeDriver = new ChromeDriver();
navigation = chromeDriver.navigate();
}
@After
public void tearDown() {
chromeDriver.quit();
navigation = null;
chromeDriver = null;
}
@Test
public void testImplicitlyWait() {
//在driver实例化完成之后设置隐式等待,设置超时时间为3S
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
chromeDriver.get("https://www.google.com");
WebElement input = chromeDriver.findElementByXPath("//input[@class='gLFyf']");
input.sendKeys("selenium");
input.sendKeys(Keys.ENTER);
chromeDriver.findElementByXPath("//h3[text()='Selenium']").click();
}
显示等待
用来等待某个条件发生后再继续执行后续代码(如找到元素、元素可点击、元素已显示等
设置方式
WebDriverWait wait = new WebDriverWait(WebDriver driver, long timeOutInSeconds);
WebElement element = wait.until(expectConaition);
方法 | 等待条件 |
---|---|
visibilityOfElementLocated(By locator) | 页面元素再页面存在并且可见 |
elementToBeClickable(By locator) | 页面元素是否在页面上可用和可被单击 |
elementToBeSelected(WebElement element) | 页面元素处于被选中状态 |
textToBePresentInElement(By locator) | 在页面元素中是否包含特定的文本 |
presenceOfElementLocated(By locator) | 页面元素在页面中存在 |
chromeDriver.get("https://www.google.com");
WebElement input = chromeDriver.findElementByXPath("//input[@class='gLFyf']");
input.sendKeys("selenium");
input.sendKeys(Keys.ENTER);
//显示等待
WebDriverWait webDriverWait = new WebDriverWait(chromeDriver,3);//超时3s
webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//h3[text()='Selenium']")));//元素存在且可见
chromeDriver.findElementByXPath("//h3[text()='Selenium']").click();
特殊元素操作
模态框
Modal Dialogue Box ,又叫做模式对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。
- alert
- confirm
private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setup() {
chromeDriver = new ChromeDriver();
navigation = chromeDriver.navigate();
chromeDriver.get(" C:/Users/lf-27/OneDrive/eclipse/webauto/src/main/resources/alert.html");
chromeDriver.manage().window().maximize();
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
navigation = null;
chromeDriver.quit();
//chromeDriver = null;
}
@AfterClass
public static void dearDownAfterclass() {
//待定
}
@Test
public void testAlert() {
//点击按钮
chromeDriver.findElementById("btn").click();
//switchTo.alert 找到对应的alert弹框
Alert alert = chromeDriver.switchTo().alert();
System.out.println(alert.getText());//获取alert上的value值
alert.accept();//确认
//alert.dismiss();//取消
}
@Test
public void testConfirm() throws InterruptedException {
//点击按钮
chromeDriver.findElementById("confirm").click();
Thread.sleep(2000);
//找到对应的comfirm弹框
Alert alert = chromeDriver.switchTo().alert();
alert.accept();
//alert.dismiss();
System.out.println(alert.getText());
alert.accept();
}
iframe
iframe切换
四种切换方式:
- driver.switchTo().frame(index);
- driver.switchTo().frame(id);
- driver.switchTo().frame(name);
- driver.switchTo().frame(WebElement);
切换之后,回到默认内容页面(否则会找不到元素)
driver.switchTo().defaultcontent();
private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
chromeDriver = new ChromeDriver();
navigation = chromeDriver.navigate();
chromeDriver.get("C:/Users/lf-27/Onedrive/eclipse/webauto/src/main/resources/a.html");
chromeDriver.manage().window().maximize();
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
navigation = null;
chromeDriver.quit();
}
@Test
public void test1001() throws InterruptedException {
//在默认的页面找输入框并输入数据
chromeDriver.findElementById("aa").sendKeys("aaa");
//进入第一个内嵌页面定位元素并输入数据
//切换iframe
chromeDriver.switchTo().frame("bframe");
chromeDriver.findElementById("bb").sendKeys("bbb");
//
chromeDriver.switchTo().frame("cframe");
chromeDriver.findElementById("cc").sendKeys("ccc");
//切换回默认的页面
chromeDriver.switchTo().defaultContent();
chromeDriver.findElementById("aa").clear();
Thread.sleep(3000);
}
window
当你要操作另一个窗口页面的元素时,一定要注意先切换窗口切换方式:传入要操作窗口的name或者句柄handle
driver.switchTo().window(nameOrHandle)
如何获取到窗口的句柄
- driver.getWindowHandle();//获取当前窗口的句柄
- driver.getWindowHandles();//获取测试打开的所有窗口句柄
private ChromeDriver chromeDriver;
private Navigation navigation;
@BeforeClass
public static void setUpBeforeClass() {
System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
chromeDriver = new ChromeDriver();
navigation = chromeDriver.navigate();
chromeDriver.get("C:/Users/lf-27/Onedrive/eclipse/webauto/src/main/resources/window/a.html");
chromeDriver.manage().window().maximize();
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
navigation = null;
chromeDriver.quit();
}
@Test
public void windowTest() throws InterruptedException {
chromeDriver.findElementById("aa").sendKeys("this is first window");
Thread.sleep(3000);
System.out.println("跳转前句柄\t"+chromeDriver.getWindowHandle());
chromeDriver.findElementById("bb").click();
System.out.println("跳转后句柄\t"+chromeDriver.getWindowHandle());
//进入到b窗口后获取所有句柄
Set<String> handles = chromeDriver.getWindowHandles();
for(String handle:handles) {
//切换句柄
chromeDriver.switchTo().window(handle);
//符合条件则break
if(chromeDriver.getTitle().equals("b")) {
//对b窗口元素进行定位
break;
}
}
System.out.println("切换句柄\t"+chromeDriver.getWindowHandle());
chromeDriver.findElementById("bb").sendKeys("this is second window");
Thread.sleep(3000);
}
select下拉框
如果页面元素是一个下拉框,我们可以将此web元素封装为Select对象
- Select select = new Select(WebElement element);
api
select.getOptions();//获取所有选项
select.selectByIndex(index);//根据索引选中对应的元素,从0开始
select.selectByValue(value);//选择指定value值对应的选项
select.selectByVisibleText(text);//选中文本值对应的选项
//select下拉框处理
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
chromeDriver.get("https://www.baidu.com");
//根据父元素找子元素
chromeDriver.findElementByXpath("//div[@id='ul']/a[text()='设置']")).click();
chromeDriver.findElementByXpath("//a[text()='高级搜索']").click();
//定位到时间下拉框
WebElemenet webElement = chromeDriver.findElementByName("gpc");
//把webElement封装成Select对象
Select select = new Select(webElement);
//根据index值选
select.selectByIndex(0);//第一个
Thread.sleep(1000);
//根据value值选择
//select.selectByValue();
//根据文本值选择
select.selectByVisibleText("最近一个月");
日期时间控件
分为两种情况
-
控件没有限制手动输入,则直接调用sendKeys方法写入时间数据
//可以输入的input类型时间日期控件 chromeDriver.findElementByXpath("//form[@id='J_FlightForm']//input[@name='depDate']").sendKeys("2000-01-01");
-
控件有限制输入,则可以执行一段js来改变元素的value属性值
JavascriptExecutor jsExecutor = (JavascriptExecutor)driver; jsExcutor.executeScript("...");
//限制输入的时间日期控件 //javaScript执行对象 JavaScriptExecutor javascriptExecutor = (JavaScriptExecutor)chromeDriver; javascriptExecutor.executeScript("document.getElementById(\"train_date\").reomveAttribute(\"readonly\")"); chromeDriver.findElementById("train_date").clear(); chromeDriver.findElementById("train_date").sendKeys("2000-01-10");
鼠标操作
自动化测试时,有些元素不适合直接点击或者进行某些操作时,可以使用Selenium的Actions类来模拟鼠标键盘操作,通过Actions对象可以发起鼠标左键、右键、移动鼠标等操作。
actions.clickAndHold(onElement).moveToElement(toElement).release).build().perform();
private ChromeDriver chromeDriver;
@BeforeClass
public static void setUpBeforeClass() {
System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe");
}
@Before
public void setUp() {
chromeDriver = new ChromeDriver();
chromeDriver.get("http://www.treejs.cn/v3/demo/cn/exedit/drag.html");
chromeDriver.manage().window().maximize();
chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
}
@After
public void dearDown() {
// chromeDriver.quit();
}
@Test
public void testDrag() {
//鼠标操作
WebElement sourceElement = chromeDriver.findElementById("treeDemo_2_span");
WebElement targetElement = chromeDriver.findElementById("treeDemo_3_span");
//实例化Acitons
Actions actions = new Actions(chromeDriver);
//鼠标相关操作
//clickAndHold() 点击并按住
//moveToElement() 移动到指定元素
//release().build() 释放、构建
//perform() 运行
actions.clickAndHold(sourceElement).moveToElement(targetElement).release().build().perform();
}
文件上传
-
使用sendKeys写入文件的路径
<input type="file" id="fu" value="选择文件">
private ChromeDriver chromeDriver; @BeforeClass public static void setUpBeforeClass() { System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver.exe"); } @Before public void setUp() { chromeDriver = new ChromeDriver(); chromeDriver.get("C:\\Users\\lf-27\\OneDrive\\eclipse\\webauto\\src\\main\\resources\\upload.html"); chromeDriver.manage().window().maximize(); chromeDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS); } @After public void dearDown() { // chromeDriver.quit(); } @Test public void testUpload() { chromeDriver.findElementByXPath("//input[@value='选择文件']").sendKeys("C:\\Users\\lf-27\\OneDrive\\downloads\\HK.pem"); chromeDriver.findElementByXPath("//input[@id='upload']").click(); }
-
如果文件上传不是input元素,而是使用第三方的控件。并且不是input元素,那么这种情况就很棘手了,必须使用一些第三方的工具,比如autoit等来完成。
验证码
-
去除验证码
改代码
-
自动识别
有门槛
-
万能验证码(推荐)
改代码