软件测试之自动化测试Selenium-java入门
Selenium在Java下的安装与使用
- 环境:JDK1.8
- IDE:IntelliJ IDEA 2021.2/Eclispe
- 浏览器:Chrome
第一步:下载Selenium,下载链接 第二步:通过maven对jar进行管理,引入Selenium坐标。
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
第三步:编写脚本。注意的是,如果浏览器如Chrome,Firefox等浏览器未装在其默认安装位置,需手动下载对应版本的驱动,并自行进行加载。否则会报The path to the driver executable must be set by the webdriver.chrome.driver system property; 的错误。
public class baidu {
public static void main(String[] args) throws InterruptedException {
System.out.println("srart selenium");
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("http://www.baidu.com/");
driver.findElement(By.id("kw")).sendKeys("selenium java");
driver.findElement(By.id("su")).click();
Thread.sleep(3000);
driver.close();
}
}
常见的定位元素
- id:
findElement(By.id("kw")) - name:
findElement(By.name("wd")) - class name:
findElement(By.className("s_ipt")) - link text:
findElement(By.linkText("新闻")) - cssSelector:
findElement(By.cssSelector()) - XPath:可以通过谷歌浏览器的插件ChroPath自动帮我们获取XPath路径
Selenium的一些基本用法
-
控制浏览器窗口大小:driver.manage().window(). -
控制浏览器前进后退:driver.navigate() -
控制浏览器刷新:driver.navigate().refresh()
public interface WebElement extends SearchContext, TakesScreenshot {
void click();
void submit();
void sendKeys(CharSequence... keysToSend);
void clear();
String getTagName();
String getAttribute(String name);
boolean isSelected();
boolean isEnabled();
String getText();
List<WebElement> findElements(By by);
WebElement findElement(By by);
boolean isDisplayed();
Point getLocation();
Dimension getSize();
Rectangle getRect();
String getCssValue(String propertyName);
}
鼠标事件
- contextClick() 右击
- clickAndHold() 鼠标点击并控制
- doubleClick() 双击
- dragAndDrop() 拖动
- release() 释放鼠标
- perform() 执行所有 Actions 中存储的行为
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import java.util.concurrent.TimeUnit;
public class actions {
public static final String DRIVER_NAME = "webdriver.chrome.driver";
public static final String DRIVER_LOCATION = "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe";
public static void main(String[] args) throws InterruptedException {
System.setProperty(DRIVER_NAME, DRIVER_LOCATION);
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("http://www.baidu.com/");
Actions actions = new Actions(driver);
actions.clickAndHold(driver.findElement(By.xpath("//span[@id='s-usersetting-top']"))).perform();
Thread.sleep(1000);
}
}
键盘事件keys
public class keyboard {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com");
WebElement input = driver.findElement(By.id("kw"));
input.sendKeys("seleniumm");
Thread.sleep(500);
input.sendKeys(Keys.BACK_SPACE);
Thread.sleep(500);
input.sendKeys(Keys.SPACE);
Thread.sleep(500);
input.sendKeys("教程");
Thread.sleep(500);
input.sendKeys(Keys.CONTROL,"a");
Thread.sleep(500);
input.sendKeys(Keys.CONTROL,"x");
Thread.sleep(500);
input.sendKeys(Keys.CONTROL,"v");
Thread.sleep(500);
input.sendKeys(Keys.ENTER);
Thread.sleep(500);
driver.quit();
}
}
设置元素等待
如今大多数 Web 应用程序使用 AJAX 技术。当浏览器在加载页面时,页面上的元素可能并不是同时被加载完成的,这给元素的定位增加了困难。如果因为在加载某个元素时延迟而造成元素定位失败的况,那么就会降低自动化脚本的稳定性。我们可以通过设置元素等待提高这种问题而造成的不稳定。
定位一组元素
- 区别于找到某一个元素findElement,定位一组元素只是在其后面多加了个s,用于定位一组元素:findElements
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Checkbox</title>
<link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></script>
</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>
</form>
</div>
</body>
</html>
public class checkbox {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
File file = new File("D:/Workspace/IdeaWorkSpace/Selenium/src/main/resources/checkbox.html");
String absolutePath = file.getAbsolutePath();
WebDriver driver = new ChromeDriver();
driver.get(absolutePath);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
List<WebElement> elements = driver.findElements(By.xpath("//input[@type='checkbox']"));
for (WebElement element : elements) {
System.out.println("这是"+element+"checkbox");
element.click();
Thread.sleep(1000);
}
elements.get(elements.size()-1).click();
Thread.sleep(1000);
driver.close();
}
}
frame切换
- 对于通过iframe表单嵌入页面的,我们无法直接通过findElement定位找到该元素。我们必须通过
driver.switchTo().frame(); 切换到该iframe后,方可继续定位并测试,如:
<html>
<head>
<link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.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="if" name="nf" src="http://www.baidu.com" width="800" height="300">
</iframe>
</div>
</div>
</body>
<script
src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></script>
</html>
public class Frame {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
File file = new File("E:/jase/frame.html");
String filePath = file.getAbsolutePath();
driver.get(filePath);
driver.switchTo().frame("if");
driver.findElement(By.id("kw")).sendKeys("webdriver");
driver.findElement(By.id("su")).click();
Thread.sleep(5000);
driver.quit();
}
}
多窗口切换
- 在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。WebDriver 提供了 switchTo().window()方法可以实现在不同的窗口之间切换。
class Windows {
public static void main(String[] arge) throws InterruptedException{
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com");
String sreach_handle = driver.getWindowHandle();
System.out.println(sreach_handle);
driver.findElement(By.linkText("登录")).click();
Thread.sleep(3000);
driver.findElement(By.linkText("立即注册")).click();
Set<String> handles = driver.getWindowHandles();
for(String handle : handles){
if (handle.equals(sreach_handle)==false){
driver.switchTo().window(handle);
System.out.println("now register window!");
Thread.sleep(2000);
driver.findElement(By.xpath("//input[@id='TANGRAM__PSP_4__userName']")).clear();
driver.findElement(By.xpath("//input[@id='TANGRAM__PSP_4__userName']")).sendKeys("username");
driver.findElement(By.xpath("//input[@id='TANGRAM__PSP_4__password']")).clear();
driver.findElement(By.xpath("//input[@id='TANGRAM__PSP_4__password']")).sendKeys("password");
Thread.sleep(2000);
driver.close();
}
}
for(String handle : handles){
if (handle.equals(sreach_handle)){
driver.switchTo().window(handle);
Thread.sleep(2000);
driver.findElement(By.className("close-btn")).click();
System.out.println("now baidu sreach page!");
driver.findElement(By.id("kw")).sendKeys("webdriver");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
}
}
driver.quit();
}
}
提示框的处理
- 一些网页、系统的一些操作提示框是无法被定位的,我们可以通过
switch_to_alert() 方法去操作提示框。 - getText():返回 alert/confirm/prompt 中的文字信息。
- accept(): 接受现有警告框。
- dismiss():解散现有警告框。
- sendKeys(keysToSend): 发送文本至警告框。keysToSend:将文本发送至警告框。
class Alert {
public static void main(String[] args) throws InterruptedException{
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com");
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Actions action = new Actions(driver);
action.clickAndHold(driver.findElement(By.id("s-usersetting-top"))).perform();
driver.findElement(By.xpath("//a[contains(text(),'搜索设置')]")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//a[contains(text(),'保存设置')]")).click();
Thread.sleep(2000);
System.out.println("弹窗为:"+driver.switchTo().alert().getText());
driver.switchTo().alert().accept();
driver.quit();
}
}
操作cookie
public class CookieOpe {
public static void main(String[] args){
WebDriver driver = new ChromeDriver();
driver.get("http://www.youdao.com");
Cookie c1 = new Cookie("name", "key-aaaaaaa");
Cookie c2 = new Cookie("value", "value-bbbbbb");
driver.manage().addCookie(c1);
driver.manage().addCookie(c2);
Set<Cookie> coo = driver.manage().getCookies();
System.out.println(coo);
driver.quit();
}
}
操作JavaScript
- 通过
((JavascriptExecutor)driver).executeScript(“your JavaScript code”) 执行JavaScript代码。
class JS {
public static void main(String[] args) throws InterruptedException{
WebDriver driver = new ChromeDriver();
driver.manage().window().setSize(new Dimension(700, 600));
driver.get("http://www.baidu.com");
driver.findElement(By.id("kw")).sendKeys("webdriver api");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
((JavascriptExecutor)driver).executeScript("window.scrollTo(100,450);");
Thread.sleep(3000);
System.out.println("end");
driver.quit();
}
}
截图
public class Baidu {
public static void main(String[] args){
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com");
try {
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile,new File("d:\\screenshot.png"));
} catch (Exception e) {
e.printStackTrace();
}
driver.quit();
}
}
Selenium Chrome IDE下载
Selenium Chrome IDE
Selenium Chrome IDE入门案例
- 基本界面展示
- 简单说明:type用于设置字段输入的值,target表明找到id=kw的这个标签,value是输入的值。pause用于暂停,相当于java中的Thread.sleep。assert 为断言,只有符合条件的时候才为true。否则log日志输出错误。更多详细的api文档请参考:Selenium IDE API
testNg的安装与使用
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>compile</scope>
</dependency>
- 通过xml方式/直接启动的方式,启动测试
- 直接启动的方式:
public class testNg {
private WebDriver driver;
private String baseUrl;
@BeforeClass
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
driver = new ChromeDriver();
baseUrl = "https://www.baidu.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
@Test
public void testCase() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.id("kw")).sendKeys("testNG");
driver.findElement(By.id("su")).click();
Thread.sleep(2000);
String title =driver.getTitle();
assertEquals(title,"testNG_百度搜索");
}
@AfterClass
public void tearDown() throws Exception {
driver.quit();
}
}
按类名类进行测试
<suite name="suite1">
<test verbose="2" name="test1">
<classes>
<class name="ng.testNg"></class>
</classes>
</test>
<test verbose="2" name="test2">
<classes>
<class name="ng.testNg3">
</class>
<class name="ng.testNg2"></class>
</classes>
</test>
</suite>
按包名来进行测试
<suite name="suite1">
<test name="Regression1" >
<packages>
<package name="ng" />
</packages>
</test>
</suite>
自定义分组进行测试
testNg依赖测试
public class testMail {
public static WebDriver driver;
public static void login(WebDriver driver, String username, String pwd) throws InterruptedException {
String first_handle = driver.getWindowHandle();
System.out.println("登陆的窗口为"+first_handle);
driver.findElement(By.id("u")).clear();
driver.findElement(By.id("u")).sendKeys(username);
Thread.sleep(1000);
driver.findElement(By.xpath("//input[@id='p']")).clear();
driver.findElement(By.xpath("//input[@id='p']")).sendKeys(pwd);
driver.findElement(By.id("login_button")).click();
Thread.sleep(3000);
String second_handle = driver.getWindowHandle();
System.out.println("登陆后的窗口为:"+second_handle);
String uname = driver.findElement(By.xpath("//span[@id='useraddr']")).getText();
System.out.println("登陆的用户为:"+uname);
}
public static void logout(WebDriver driver){
driver.findElement(By.xpath("//a[contains(text(),'退出')]")).click();
}
@Test
public void verifyLogin() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://wx.mail.qq.com/");
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
String username = "你的qq号";
String password = "你的qq密码";
driver.findElement(By.xpath("//div[contains(text(),'QQ登录')]")).click();
driver.switchTo().frame(driver.findElement(By.xpath("//body/div[1]/div[2]/div[1]/div[1]/div[1]/div[2]/div[2]/iframe[1]")));
login(driver,username,password);
String text = driver.findElement(By.id("useraddr")).getText();
assertEquals(text,"你的qq号@qq.com");
}
@Test(dependsOnMethods = {"verifyLogin"})
public void search() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
System.out.println("search:");
driver.findElement(By.xpath("//a[contains(text(),'通讯录')]")).click();
driver.switchTo().frame(driver.findElement(By.xpath(" //iframe[@id='mainFrame']")));
Thread.sleep(1000);
driver.findElement(By.xpath("//input[@id='keyword']")).sendKeys("b");
driver.findElement(By.xpath("//body/div[@id='out']/div[@id='bar']/div[1]/div[1]/div[1]/form[1]/a[1]")).click();
}
}
- 在这个案例里面,通过dependsOnMethods实现第二个测试依赖于第一个测试,第一个测试如果不通过则不会进行第二个测试。并且通过static的方式使得webdriver全局唯一,保证了两个测试在同一个窗口进行。但是真实的情况下默认一个自动测试用例使用一个driver,即一个测试用例都是一个闭合的业务操作,用例与用例之间相互独立。
testNg忽略测试
- 对于还没准备好的测试用例,但是由于进度要求不得不对其他用例进行测试。可以通过在对应的方法上添加注解
@Test(enabled = false) 来暂时忽略该用例测试。
testNg参数化测试(DataProvider)
- 在testNg中通过
Object[][] 二维数组存放数据,并用@DataProvider(name="") 声明该自定义参数的名字,key和value。具体的示例如下:
public class paramMail {
public static WebDriver driver;
@DataProvider(name="user")
public Object[][] Users(){
return new Object[][]{
{"qq号","密码"},
};
}
public static void login(WebDriver driver, String username, String pwd) throws InterruptedException {
String first_handle = driver.getWindowHandle();
System.out.println("登陆的窗口为"+first_handle);
driver.findElement(By.id("u")).clear();
driver.findElement(By.id("u")).sendKeys(username);
Thread.sleep(1000);
driver.findElement(By.xpath("//input[@id='p']")).clear();
driver.findElement(By.xpath("//input[@id='p']")).sendKeys(pwd);
driver.findElement(By.id("login_button")).click();
Thread.sleep(3000);
String second_handle = driver.getWindowHandle();
System.out.println("登陆后的窗口为:"+second_handle);
String uname = driver.findElement(By.xpath("//span[@id='useraddr']")).getText();
System.out.println("登陆的用户为:"+uname);
}
@Test(dataProvider = "user")
public void verifyLogin(String username,String password) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://wx.mail.qq.com/");
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
driver.findElement(By.xpath("//div[contains(text(),'QQ登录')]")).click();
driver.switchTo().frame(driver.findElement(By.xpath("//body/div[1]/div[2]/div[1]/div[1]/div[1]/div[2]/div[2]/iframe[1]")));
login(driver,username,password);
String text = driver.findElement(By.id("useraddr")).getText();
assertEquals(text,"qq号@qq.com");
}
}
testNg参数化测试(xml)
- 通过在xml中配置参数的方式,提供给测试方法使用。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="mail">
<parameter name="param1" value="param1"></parameter>
<test verbose="5" name="testMail">
<parameter name="param2" value="param2"></parameter>
<parameter name="param3" value="param3"></parameter>
<classes>
<class name="testParam.paramXml"/>
</classes>
</test>
</suite>
public class paramXml {
public static WebDriver webDriver;
@BeforeTest
public void setUp(){
System.setProperty("webdriver.chrome.driver", "D:/Solfware/Selenium/ChromeDriver/chromedriver.exe");
webDriver = new ChromeDriver();
webDriver.manage().window().maximize();
}
@Test
@Parameters({"param3","param2"})
public void test(String param2,String param3) throws InterruptedException {
webDriver.get("http://www.baidu.com");
webDriver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
webDriver.findElement(By.id("kw")).sendKeys(param2);
webDriver.findElement(By.id("su")).click();
Thread.sleep(3000);
System.out.println("param3:"+param3);
}
}
1 .变量的取值是按照testng.xml中定义的顺序来取值的 2.<parameter> 可以声明在<suite> 或者<test> 级别,在<test> 下的<parameter> 会覆盖在<suite> 下声明的同名变量
testNg超时测试
class Timeout {
@Test(timeOut = 5000)
public void ok() throws InterruptedException {
Thread.sleep(4000);
System.out.println("ok");
}
@Test(timeOut = 1000)
public void fail() throws InterruptedException {
Thread.sleep(3000);
}
}
Selenium Grid安装及使用
- 第一步,下载selenium server,下载地址
- 第二步,解压jar到指定目录
- 第三步,在该目录的文件路径输入cmd,启动命令符
- 第四步,配置-hub主节点以及-node子节点
踩坑注意! 如果不是将chrome/firefox浏览器默认安装在其安装盘的,需要在启动selenium grid server的时候,把对应的浏览器驱动加上,不然就会报错,详细错误为: Error forwarding the new session Empty pool of VM for setup Capabilities Caused by: org.openqa.selenium.SessionNotCreatedException: Unable to create new service: ChromeDriverService
java -Dwebdriver.chrome.driver="D:\Solfware\Selenium\ChromeDriver\chromedriver.exe" -jar selenium-server-standalone-3.141.59.jar -role node -port 5555 -hub http://你的主节点ip:4444/grid/register/
java -jar selenium-server-standalone-3.141.59.jar -role hub -port 4444
- 第五步,在IDEA中导入selenium grid的坐标
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.141.59</version>
</dependency>
public class seRc {
public static void main(String[] args) throws Exception {
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setPlatform(Platform.WINDOWS);
capabilities.setBrowserName("chrome");
capabilities.setJavascriptEnabled(true);
WebDriver driver;
try {
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilities);
driver.get("https://www.baidu.com");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
|