目录
1.什么是Seleium
2.Selenium环境引入
3.selenium基本使用
4.框架优化
5.元素其他操作
6.关于获取不到元素
1.什么是Seleium
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。
简单来说,就是可以模拟人工在网页上的操作(如点击、输入等),从而验证网页上的功能,达到自动化测试的效果。
Selenium WebDriver是一个浏览器自动化框架,Selenium 的重要主要部分,它接受命令并将它们发送到浏览器。它是通过特定于浏览器的驱动程序实现的。它直接与浏览器通信并对其进行控制。Selenium WebDriver支持各种编程语言,如Java、C# 、PHP、Python、Perl、Ruby。
下面我们使用的将是java语言下的Selenium。
2.Selenium环境引入
首先,我们需要在springboot项目中导入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>
然后,我们还需要下载对应浏览器的控制器,本次主要是控制谷歌浏览器,使用的是:chromdriver。(ChromeDriver 是 Chrome 驱动,是 selenium 模块用来模拟打开谷歌浏览器所必须的一个文件,能模拟在谷歌浏览器上的操作。)
下载好浏览器版本对应的chromdriver后,解压到文件夹即可。
然后,我们就可以使用selenium了。
3.selenium基本使用
下面是selenium的一个基本使用案例,实现登录gitee首页为目的:
package com.seven.buy;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
public class UpfileDemo{
public static void main(String[] args) {
//你的chromedriver存放地址
System.setProperty("webdriver.chrome.driver", "E:\\java_tools\\chromedriver.exe");
ChromeDriver browser = new ChromeDriver();
//窗口最大化
browser.manage().window().maximize();
//获取gitee网址
browser.get("https://gitee.com/help/articles/4120");
//前往登录页面
browser.findElement(By.linkText("登录")).click();
//输入用户名密码
browser.findElement(By.id("user_login")).sendKeys("your username");
browser.findElement(By.id("user_password")).sendKeys("your password");
//点击登录
browser.findElement(By.xpath("//*[@id=\"new_user\"]/div/div/div/div[4]/input")).click();
}
}
主要逻辑如下:
1.配置Chromedriver程序位置,并获取Chromedriver对象,获得对浏览器操作的能力。
2.获取网址,去玩目的网页进行操作。
3.获取页面上的元素(如通过id,通过xpath获取),从而进行对应的操作(如点击、输入值)等。
4.框架优化
selenium的核心在于获取到对应的元素,进行对应的操作。selenium框架为我们提供了多种获取元素的方式,下面主要讲述4种:
1.通过class获取,即通过标签的class名称获取对应的元素:
WebElement element = browser.findElement(By.className("icon-qrcode"));
2.通过a标签获取,即对应超链接元素,可以通过其标签文字内容来获取:
WebElement element = browser.findElement(By.linkText("亲,请登录"));
3.通过id获取,即通过标签的id名称获取对应的元素:
WebElement user_login = browser.findElement(By.id("user_login"));
4.通过xpatrh获取:
WebElement element = browser.findElement(By.xpath("//*[@id=\"J_Order_s_2214696073021_1\"]/div[1]/div/div/label"));
什么是xpath?
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言,可以通过谷歌浏览器,检查的方式,获取对应元素的xpath:
(1)f12点开开发这么模式,点击左上角这个小箭头,然后点击页面中你需要的那个元素,即可定位到该元素:
(2)然后在选中标签上右键,复制,复制xpath即可。
(3)关于xpath:
xpath一般使用相等路径,一般格式为://标签名称[contains(text(),"文字")]。标签名称可以是a、input、button、span、td等。或者使用//标签名称[contains(@属性名称,'属性值')]
注意:该写法会定位到第一个匹配的元素,如果存在多个,需要注意匹配文字的精确性。
编写之后,我们可以ctrl+f在页面搜索该xpath,来确定其有效性:
(如上图,通过文字描述,编写xpath,此类写法主要用于无法用id、className或是a标签定位到元素的情况,根据元素其内部各种属性来获取)
而除了常规的使用 findElement() 方法来获取元素,我们还可以结合lombok注解,将需要的元素作为一个实体类获取,以实现CSDN首页进行搜索为例:
编写一个基础Page类,获取dirver,否则使用@FindBy注解时,获取的元素会为空:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
public class BasePage {
public WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory
.initElements(new AjaxElementLocatorFactory(driver, 5), this);
}
}
编写一个Page实体类,继承该basePage:
import lombok.Getter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@Getter
public class CSDNPage extends BasePage{
//搜索框
@FindBy(id = "toolbar-search-input")
private WebElement searchInput;
//搜索按钮
@FindBy(xpath = "//*[@id=\"toolbar-search-button\"]")
private WebElement searchBtn;
public CSDNPage(WebDriver driver) {
super(driver);
}
}
然后编写一个业务类,进行业务上的操作:
package com.seven.buy.service;
import com.seven.buy.page.CSDNPage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
@Service
public class CSDNService implements InitializingBean {
private WebDriver driver;
private CSDNPage page;
public void search(String content){
page.getSearchInput().sendKeys(content);
page.getSearchBtn().click();
}
@Override
public void afterPropertiesSet() throws Exception {
System.setProperty("webdriver.chrome.driver", "E:\\java_tools\\chromedriver.exe");
this.driver = new ChromeDriver();
driver.get("https://www.csdn.net/?spm=1001.2101.3001.4476");
driver.manage().window().maximize();
this.page = new CSDNPage(driver);
}
}
然后编写junit测试类,测试方法:
import com.seven.buy.service.CSDNService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class serviceTest {
@Resource
private CSDNService csdnService;
@Test
public void search(){
csdnService.search("java");
}
}
即可实现自动化测试。
5.元素其他操作
除了基础的赋值和点击,我们还可能碰见下拉框等元素,需要进行操作:
Select select = new Select(driver.findElement(By.xpath("//input[contains(text(),\"请输入你的性别\")]")));
select.selectByValue("男");
可以通过select类来获取对应的值,selectByValue中的值为页面中元素对应的value值。
如果需要对一些元素进行处理(如去除disable、去除readonly等),可以通过编写JS语句然后执行的方式进行;
//根据id去除disable元素
public static void removeElementDisable(WebDriver driver,String id) {
JavascriptExecutor executor = (JavascriptExecutor) driver;
String js = "document.getElementById('"+id +"').removeAttribute('disabled', '')";
executor.executeScript(js);
}
//根据xpath去除disable元素
public static void removeByXpath(WebDriver driver,String xpath) {
JavascriptExecutor executor = (JavascriptExecutor) driver;
String js = "document.evaluate(" + "\""+xpath+"\"" + ",document).iterateNext().removeAttribute('disabled', '');";
executor.executeScript(js);
}
6.关于获取不到元素
有时候由于网速,页面等原因,会导致页面未加载完成,就调用了对应的获取方法,从而报无法获取元素的错误,这时,我们需要对线程阻塞等待一下,再进行获取。
或者我们可以通过try catch捕获异常,等待一段时间后再次获取:
public void search(String content){
boolean judgingElement = isJudgingElement(driver, By.xpath("//input[contains(text(),\"请输入你的性别\")]"));
while (!judgingElement){
try {
Thread.sleep(2000);
judgingElement = isJudgingElement(driver, By.xpath("//input[contains(text(),\"请输入你的性别\")]"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//判断某个元素是否存在
public boolean isJudgingElement(WebDriver webDriver, By by) {
try {
webDriver.findElement(by);
return true;
} catch (Exception e) {
return false;
}
}