目录
Selenium家族
selenium包括:Selenium IDE、web Driver、Selenium Grid
Selenium IDE:是FireFox的扩展插件,支持用户录制和回放测试
Selenium Driver:提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序
Selenium Gird:分布式自动化工具,可以在多个测试环境中以并发的方式执行测试脚本,实现测试脚本,实现测试脚本的并发执行,缩短大量的测试脚本的执行时间
Maven项目构建
优点:
1.可以使用Maven来编译你的代码
2.项目打包也可以使用Maven来完成
3.maven可以实现项目模块化管理
4.maven可以在线管理依赖,项目依赖也很方便获取
5.maven提供了一些丰富的插件,方便项目持续集成
Maven安装和配置环境变量
1.官网下载:Maven – Download Apache Maven
2.配置环境变量
1.解压到本地文件夹
2.配置MAVEN_HOME环境变量,指向Maven文件夹
3.将Maven bin目录更新到PATH:%MAVEN_HOME%\bin
4.验证:mvn -version
5.修改setting.xml
1)指定本地仓库目录
<localRepository>D:\OtherTool\apache-maven-3.8.4\Maven_repository</localRepository>
2)配置镜像,指定下载jar包的地址
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
3)Eclipse配置:
Window->Preference->Maven
修改Installations选项:点击添加指向本地maven根目录,点击Finish;勾选添加的本地Maven
4)修改User Settings选项
1.修改Global Setting指向本地maven 的setting.xml
2.修改User Settings指向用户自定义配置文件
6.Maven选项说明
1)Group Id 分组,一般填写组织机构,如com.lemon
2)Artifact Id—项目打包成jar包的id,或者jar包的名字
3)Version 版本
4)Packaging 打包方式
7.Maven项目结构
1)src/main/java—-一般是开发人员写代码的目录
2)src/main/resources—-开发人员放项目资源文件的目录
3)src/test/java—-放单元测试代码的目录
4)src/test/resources—-放测试资源文件的目录
5)maven Dependencies—通过maven拿下来的项目依赖包放目录
6)target—-存放构建后文件的目录
引入selenium框架
jar包配置搜索官方地址:http://mvnrepository.com/—-搜索selenium
<!-- 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>
把上面的代码复制到maven项目的pom.xml下
可能会有错误,Eclipse可以参考:新系统中导入maven失败出错,Could not calculate build plan_sean-xiao的专栏-CSDN博客
IDEA可以参考:
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
Chromer自动化环境配置问题参考:一文搞定web自动化环境常见问题 - 歪歪欧巴 - 博客园
idea创建Maven项目参考:IntelliJ IDEA 15 创建maven项目 - Tom1997 - 博客园
基本元素定位:
使用findElement(By.xpath)而不是driver.findElementByXPath(),是因为 driver.findElement(By.xpath())利于封装
1.id—-根据id来获取元素,id值一般是唯一的
2.name—-根据name来获取元素,可能会返回元素集合
3.tagname—-根据元素的标签名来获取元素,可能会返回元素集合
4.classname—根据元素的样机class值来获取元素,可能返回元素集合
5.linkText—-根据超链接的文本值来获取元素
6.partialLinkText—根据超链接的部分文本值来获取元素
//定位百度的搜索框元素,并且输入数据---ID定位---唯一
driver.findElement(By.id("kw")).sendKeys("柠檬班");
//定位百度的搜索框元素,并且输入数据---name定位---可能重复,可以ctrl+F先搜索查看
driver.findElement(By.name("wd")).sendKeys("腾讯视频");
//定位百度的搜索框元素,并且输入数据---tagName定位---找到多个元素--不推荐使用
driver.findElement(By.tagName("input")).sendKeys("腾讯视频");
//定位百度的搜索框元素,并且输入数据---className定位
driver.findElement(By.className("s_ipt")).sendKeys("腾讯视频");
//复合问题的解决方法---找其中一个的唯一值
// driver.findElement(By.className("bg s_btn")).click(); ---有问题
driver.findElement(By.className("s_btn")).click(); ---正确
//定位"新闻"元素,并且点击---linkText定位
driver.findElement(By.linkText("新闻")).click();
//定位"新闻"元素,并且点击---partailLinkText定位
driver.findElement(By.partialLinkText("共赴")).click();
//定位百度一下按钮,并点击----name定位
driver.findElement(By.id("su")).click();
元素定位—-CSSSelector
1.根据TagName
By.cssSelector(”input”);
2.根据ID
By.cssSelector("input#id");
By.cssSelector("#id");
3.根据className(类名)
By.cssSelector(".className");
By.cssSelector("input.className");
4.css精确定位
根据元素属性,属性名==属性值,id,class等都可写出这种形式
By.cssSelector(”input[name=’XXX’]”)
5.多属性
By.cssSelector(”标签名[属性值1=’属性值‘][属性值2=’属性值‘]”);
// cssSelector元素定位
// (1)tagName定位---标签定位
driver.findElement(By.cssSelector("input"));
// (2)id定位
driver.findElement(By.cssSelector("#kw")).sendKeys("腾讯课堂");
// (3)className定位
driver.findElement(By.cssSelector(".s_ipt")).sendKeys("腾讯课堂");
// (4)精确定位 根据元素属性,属性名==属性值,id,class等都可写出这种形式
driver.findElement(By.cssSelector("input[maxlength='255']")).sendKeys("腾讯课堂");
//多属性定位
driver.findElement(By.cssSelector("input[maxlength='255'][autocomplete='off']")).sendKeys("软件测试");
Xpath元素定位
一个描述页面位置信息的路径,相当于元素的坐标;Xpath基于xml文档树状结构,是xml路径语言,用来查询xml文档中的节点。
绝对定位:
从根目录开始找——/(根目录)
/html/body/div[2]/div/form/div[5]/button
缺点:一旦页面结构发送变化,该路径也随之失效,必须重新写
相对路径:只要不是/开始的,就是相对路径
//*[@name=’phone’]
路径解释:
1)//匹配指定节点,不考虑它们的位置(/则表示绝对路径,从根下开始)
2)*通配符,匹配任意节点
3)@选取属性
4)[]属性判断条件表达式
相对定位优点:
灵活,方便,耦合性低
元素操作API
1)click():触发当前元素的点击事件
2)clear():清空内容
3)sendkeys:往文本框一类元素中写入元素
4)getTagName():获取元素的标签名
5)getAttribue():根据属性名获取元素属性值
6)getText():获取当前元素的文本值
7)isDisplayed():查看元素是否显示
sendKeys 发送
driver.findElement(By.id("kw")).sendKeys("12345");
//等待3秒//
Thread.sleep(3000);
//clear:清除内容
driver.findElement(By.id("kw")).clear();
WebElement webElement1 = driver.findElement(By.id("kw"));
// 4)getTagName():获取元素的标签名
System.out.println("得到元素的标签名"+webElement1.getTagName());
//5)getAttribue():根据属性名获取元素属性值
System.out.println("得到元素的maxlength属性"+webElement1.getAttribute("maxlength"));
WebElement webElement2 = driver.findElement(By.xpath("//a[text()='hao123']"));
// 6)getText():获取当前元素的文本值
System.out.println("webElement2的文本值"+webElement2.getText());
// 7)isDisplayed():查看元素是否显示
System.out.println("元素的是否显示"+webElement2.isDisplayed());
WebDriver相关API
1)get(String url):访问指定url页面
2)getCurrentUrl():获取当前页面的url地址
3)getTitle:获取当前页面的标题
4)getPageSource():获取当前页面源代码
5)quit():关闭驱动对象以及所有相关的窗口
6)close():关闭当前窗口
7)getWindowHandle():返回当前页面句柄
8)getWindowHandles():返回所有由驱动对象打开页面所有的句柄,页面不同,句柄不一样
9)manage():此方法可以获取Options—-浏览器菜单操作对象 ,driver.manage().window()
//1)get(String url):访问指定url页面
//2)getCurrentUrl():获取当前页面的url地址
System.out.println("当前的url为"+driver.getCurrentUrl());
//3)getTitle:获取当前页面的标题
System.out.println("获取当前页面的标题"+driver.getTitle());
//4)getPageSource():获取当前页面源代码
System.out.println("获取当前页面源代码"+driver.getPageSource());
//5)quit():关闭驱动对象以及所有相关的窗口
driver.quit();
navigate对象:
//获取navigate对象
Navigation navigation = driver.navigate();
//访问京东
navigation.to("https://www.jd.com");
//刷新网页
navigation.refresh();
//回退
navigation.back();
//前进
navigation.forward();
三大等待
1)硬性等待
Thread.sheep();
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class ElementWait {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//访问百度
driver.get("https://baidu.com");
//findElement查找一个元素对象并返回元素对象
driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
driver.findElement(By.id("su")).click();
Thread.sleep(3000);
driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
2)显示等待
1)用来等待某个条件发送后在继承执行后续代码(如找到元素、元素可点击、元素已显示等)
2)设置方法:
WebDriverWait wait = new WebDriverWait(driver,timeout);//driver:浏览器驱动;timeout:最长超时时间,默认以秒为单位
WebElement element = wait.until(expectCondition);
方法 | 等待条件 |
visibilityOfElementLocated(By locator) | 页面元素在页面存在并且可见 |
elememtToBeClickable(By locator) | 页面元素是否在页面上可用和可被点击 |
elementToBeSelected(WebElement element) | 页面元素处于被选中状态 |
TextToBePresentlnElement(By locator) | 在页面元素中是否包含特定的文本 |
presenceOfElementLocated(By locator) | 页面元素在页面中存在 |
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.concurrent.TimeUnit;
public class ElementWait3 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//访问百度
driver.get("https://baidu.com");
//findElement查找一个元素对象并返回元素对象
driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
driver.findElement(By.id("su")).click();
//显示等待
WebDriverWait wait = new WebDriverWait(driver,5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[text()=' —专业在线学习平台']")));
driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
3)隐形等待
a.设置的超时时间范围内不断查找元素,直到找到元素或者超时
b. driver.manage.timeouts().implicityWait(long time,TimeUnit unit);
优点:相对灵活
缺点:设置是针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.concurrent.TimeUnit;
public class ElementWait2 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//在driver实例化完成之后设置隐式等待,设置超时的时间为5S
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
//访问百度
driver.get("https://baidu.com");
//findElement查找一个元素对象并返回元素对象
driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
driver.findElement(By.id("su")).click();
driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作
特殊元素定位与操作---模态框
Modle Dialogue Box,又叫做模拟对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应,如单击[确定]和[取消]按钮等将该对话框关闭
1)alert
2)confirm
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class SpecialElementLocate {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//comfirm弹框处理
//访问本地的HTML文件
driver.get("E:\\test\\HTML\\Untitled-3.html");
driver.findElement(By.id("abn")).click();
Thread.sleep(3000);
//找到对应的comfirm框
Alert alert = driver.switchTo().alert();
alert.accept();
// alert.dismiss();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---iframe切换
四种方式切换
1)driver.switchTo().frame(index);
2)driver.switchTo().frame(id);
3)driver.switchTo().frame(name);
4)driver.switchTo().frame(WebElement);
切换之后,回到默认内容页面(否则会找不到元素)
driver.switchTo().defaultContent();
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
public class SpecialElementLocate2 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//iframe
driver.get("E:\\test\\HTML\\Untitled-3.html");
//在默认的页面去找输入框输入数据
driver.findElement(By.id("aa")).sendKeys("111");
Thread.sleep(3000);
//进入第一个内嵌页面中定位元素,输入数据
driver.switchTo().frame("bframe");
driver.findElement(By.id("bb")).sendKeys("2222");
Thread.sleep(3000);
//进入第二个内嵌页面中定位元素,输入数据
driver.switchTo().frame("cframe");
driver.findElement(By.id("cc")).sendKeys("3333");
Thread.sleep(3000);
//返回默认的内容页面
driver.switchTo().defaultContent().sendKeys("回到默认页面");
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---window
当你要操作另一个窗口页面的元素时,一定要注意先切换窗口
切换方式:传入要操作窗口的name或者句柄handle
driver.switchTo().window(name Or handle);
如何获取到窗口的句柄:
1)driver.getWindowHandle();//获取当前操作窗口的句柄
2)driver.getWindowHandles();//获取测试时打开的所有窗口句柄
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Set;
public class SpecialElementLocate23 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//window处理
driver.get("E:\\test\\HTML\\Untitled-3.html");
driver.findElement(By.id("aa")).sendKeys("这是第一个窗口");
System.out.println("跳转后的窗口句柄"+driver.getWindowHandle());
Thread.sleep(2000);
//切换到B窗口
driver.findElement(By.id("bb")).click();
//虽然页面已经到了B窗口,但是句柄还是在A窗口,所有还是在A窗口上操作
Thread.sleep(2000);
System.out.println("跳转后的窗口句柄"+driver.getWindowHandle());
//句柄的切换
//进入b的窗口之后,获取到所有窗口的句柄
Set<String> handles = driver.getWindowHandles();
//对窗口进行遍历
for (String handle : handles){
//切换句柄
driver.switchTo().window(handle);
//如何知道就是处于B窗口了呢
if (driver.getTitle().equals("b.html")){
//若标题是符合就跳出循环
break;
}
}
driver.findElement(By.id("bb")).sendKeys("这是第二个窗口");
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---select下拉框
如果页面元素是一个下拉框,我们可以将此web元素封装为select对象
Select select = new Select(WebElement element);
Select对象常用API
1)select.getOptions();//获取所有的选项
2)select.selectByIndex(index); //根据索引选中对应的元素
3)select.selectByValue(value);//选择指定value值对应的选项
4)select.selectByVisible(text);//选中文本值对应的选项
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
import java.util.Set;
public class SpecialElementLocate4 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//select下拉框处理
driver.get("https://www.baidu.com");
Thread.sleep(3000);
// driver.findElement(By.xpath("//div[@id='ul']/a[text()='设置']")).click();
driver.findElement(By.xpath("//*[@id=\"s-usersetting-top\"]")).click();
driver.findElement(By.xpath("//a[text()='高级搜索']")).click();
Thread.sleep(3000);
//定位下拉框 ----这是之前的设置
WebElement webElement = driver.findElement(By.name("gpc"));
//把 webElement封装成select对象
Select select = new Select(webElement);
//select下拉框索引值从0开始
select.selectByIndex(1);
Thread.sleep(2000);
select.selectByVisibleText("最近一月");
//这是2022.1月百度的下拉框设置
//定位下拉框--先定位到下拉的箭头后等待几秒
driver.findElement(By.xpath("//*[@id=\"adv-setting-gpc\"]/div/div[1]/i[1]")).click();
Thread.sleep(3000);
driver.findElement(By.xpath("//*[@id=\"adv-setting-gpc\"]/div/div[2]/div[2]/p[4]")).click();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---时间日期控件
分两种情况:
1)控件没有限制手动输入,则直接调用sendKeys方法写入时间数据
2)控件有限制输入,则可以执行一段js来改变元素的value属性值
JavascriptExecutor jsexecutor = (JavascriptExecutor) driver;
jsexecutor.executeScript("...");
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.chrome.ChromeDriver;
public class SpecialElementLocate5 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//时间日期控件(1)
// driver.get("https://www.fliggy.com/?ttid=seo.000000574&seoType=origin");
//sendKeys直接输入
// driver.findElement(By.xpath("//*[@id=\"J_FlightForm\"]/fieldset/div[3]/div/div/input")).sendKeys("2020");
//时间日期控件(2)
driver.get("https://www.12306.cn/index/");
//先清除input内原有的数据,再输入新的数据
driver.findElement(By.xpath("//*[@id=\"train_date\"]")).clear();
Thread.sleep(3000);
driver.findElement(By.xpath("//*[@id=\"train_date\"]")).sendKeys("2022");
// 时间日期控件(3)
//限制输入的时间日期控件
driver.get("https://www.12306.cn/index/");
JavascriptExecutor jsexecutor = (JavascriptExecutor) driver;
jsexecutor.executeScript("document.getElementById(\"train_data\").removeAttribute(\"readonly\")");
Thread.sleep(2000);
driver.findElement(By.id("train_data")).clear();
Thread.sleep(2000);
driver.findElement(By.id("train_data")).sendKeys("2020-01-01");
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---鼠标操作
由于一些元素不适合直接点击或者进行某些操作时,可以使用Selenium的Actions类来模拟鼠标键盘操作,通过Actions对象可以发起鼠标左键,右键,移动鼠标等操作,最后使用perform方法执行操作
actions.clickAndHold(onElement).moveToElement(toElement).relrese().build().perform();
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
public class SpecialElementLocate6 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//鼠标操作
driver.get("http://www.treejs.cn/v3/demo/cn/exedit/drag.html");
WebElement sourceElement = driver.findElement(By.id("treeDemo_2_span"));
WebElement targetElement = driver.findElement(By.id("treeDemo_3_span"));
Actions actions = new Actions(driver);
actions.clickAndHold(sourceElement).moveToElement(targetElement).release().build().perform();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---文件操作
分为两种情况
1)类似下面,使用sendKeys写入文件的路径
<input type=”file” id=”du” value=”选择文件”>
2)如果文件上传不是input元素,而是使用的第三方的控件,并且不是input元素,那么这种情况就很棘手了,必须使用第三方的工具,比如autoit等来完成。
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
public class SpecialElementLocate7 {
private static ChromeDriver driver;
public static void main(String[] args) throws InterruptedException {
openChrome();
//文件上传
driver.get("E:\\test\\HTML\\Untitled-1.html");
//选择文件
driver.findElement(By.xpath("//input[@value='选择文件']")).sendKeys("D:\\1.png");
Thread.sleep(3000);
//点击上传按钮
driver.findElement(By.xpath("//input[@value='上传']")).click();
}
public static void openChrome() {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
//打开浏览器
driver = new ChromeDriver();
}
}
特殊元素定位与操作---验证码
1)去除验证码
2)自动识别
3)万能验证码(推荐)--参考CSDNhttps://mp.csdn.net/mp_blog/creation/editor/122598469