自动化测试之Selenium

什么是自动化测试

所谓的自动化就是将手工测试转换为代码, 让代码代替人工进行测试.
可以提高测试效率, 提高测试质量

自动化和手工测试哪个好?

没有好坏区别, 只有适合当前业务的测试类型就是一个好的测试方法.

自动化能否完全代替手工测试?

自动化不能完全代替手工测试

测试金字塔

越往上: 越接近用户, 测试方法越简单, 但问题出现之后定位问题的成本更高
自动化测试之Selenium_第1张图片

Selenium(v3)

什么是Selenium

自动化测试框架, 主要针对Web项目进行UI自动化

特点

开源
支持多语言: java,Python,js,ruby,C#
支持跨平台: linux,Mac,Windows
支持多种浏览器: Edge,Chrome,Firefox
丰富的API

工作原理

代码: 通过编译器编写的代码(自动化测试脚本)
浏览器驱动: 代码和驱动交互, 驱动和浏览器交互
自动化测试之Selenium_第2张图片

流程

加入pom依赖


<dependency>
	<groupId>org.seleniumhq.seleniumgroupId>
	<artifactId>selenium-javaartifactId>
	<version>4.8.1version>
dependency>

chromedriver添加到JDK bin目录里

记得把jdk 的bin目录配置环境变量

写代码

一个例子

public static void main(String[] args) {
    //创建了一个options对象,用来给请求设置参数
    ChromeOptions options = new ChromeOptions();
    //允许所有的请求
    options.addArguments("--remote-allow-origins=*");
    //创建了一个驱动
    WebDriver webDriver = new ChromeDriver(options);
    //打开网页
    webDriver.get("https://www.baidu.com");
    //关闭浏览器
    webDriver.quit();
}

定位元素

优缺点

推荐使用css选择器定位, 因为xpath效率低
可以在F12里右键复制而不用自己写

css selenium

id选择器#
类选择器.
标签选择器span: 直接写标签名
后代选择器div form span : 空格隔开

xpath

绝对路径:/html/body/div[1]/...(从1开始数)
相对路径+索引: //form/span[1]/input[1]
相对路径+元素: //form[@id="value"]
相对路径+通配符: //*[start-with(@autocomplete,'of')]
相对路径+部分元素定位
相对路径+文本定位: //a[text()='hao123']

操作

自动化测试之Selenium_第3张图片

打开关闭网页

public static void test01(){
    //创建了一个options对象,用来给请求设置参数
    ChromeOptions options = new ChromeOptions();
    //允许所有的请求
    options.addArguments("--remote-allow-origins=*");
    //创建了一个驱动
    WebDriver webDriver = new ChromeDriver(options);
    //打开网页
    webDriver.get("https://www.baidu.com");
    //关闭浏览器
    webDriver.quit();
}

输入内容/点击控件

public static void test02() throws InterruptedException {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com");
    //输入"软件测试"
    webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
    //搜索
    webDriver.findElement(By.cssSelector("#su")).click();
    //检测结果
    sleep(3000);
    List<WebElement> webElements = webDriver.findElements(By.cssSelector("em"));
    System.out.println("检测到的相关元素个数:"+webElements.size());
    //如果搜索结果不为0,则测试通过
    if (webElements.size()==0){
        System.out.println("测试不通过");
    }else {
        System.out.println("测试通过");
    }
}

获取控件的属性值

public static void test03() throws InterruptedException {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");
    //获取id="#su"控件的value值
    System.out.println(webDriver.findElement(By.cssSelector("#su")).getAttribute("value"));
    sleep(3000);

}

点击控件

表单才可以用.submit()否则会报错, .click()通用

private static void test04() {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");
    
    webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
	//webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).submit();
}

填写内容/清除内容

private static void test05() throws InterruptedException {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");

    webDriver.findElement(By.cssSelector("#kw")).sendKeys("测试");
    webDriver.findElement(By.cssSelector("#su")).click();
    sleep(3000);
    webDriver.findElement(By.cssSelector("#kw")).clear();

}

智能等待

隐式等待:
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
等待,等到了能找到"#kw"控件时继续,不然最多等3天

private static void test06() {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");

    webDriver.findElement(By.cssSelector("#kw")).sendKeys("测试");
    webDriver.findElement(By.cssSelector("#su")).click();
    //智能等待3单位,单位为天
        
    webDriver.findElement(By.cssSelector("#kw")).clear();
    webDriver.quit();
}

获取URL和Title

private static void test07() {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");
    
    //获取URL
    String url = webDriver.getCurrentUrl();
    System.out.println("url:"+url);
    //获取title
    String title = webDriver.getTitle();
    System.out.println("title:"+title);
    
    if (url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")){
        System.out.println("测试通过");
    }else {
        System.out.println("测试不通过");
    }
    webDriver.quit();
}

设置窗口全屏/最大化/尺寸

private static void test08() {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");
    
	//webDriver.manage().window().fullscreen();
	//webDriver.manage().window().maximize();
    webDriver.manage().window().setSize(new Dimension(500,600));
}

键盘/鼠标/导航操作

private static void test09() throws InterruptedException {
 	ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver webDriver = new ChromeDriver(options);
    webDriver.get("https://www.baidu.com/");

    webDriver.findElement(By.cssSelector("#kw")).sendKeys("测试");
    webDriver.findElement(By.cssSelector("#su")).click();

    //ctrl+A
    webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL+"A");
    sleep(100);
    //ctrl+X
    webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL+"X");
    sleep(100);
    //ctrl+V
    webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL+"V");
    sleep(100);
    //鼠标
    Actions actions = new Actions(webDriver);
    webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.HOURS);

    WebElement target = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));
    actions.moveToElement(target);  //移动鼠标到目标
    actions.contextClick().perform();   //右键

    //后退
    sleep(3000);
    webDriver.navigate().back();
    //前进
    sleep(3000);
    webDriver.navigate().forward();
    //刷新
    sleep(3000);
    webDriver.navigate().refresh();
}

更多操作

定位一组元素

private static void page() {
 	ChromeOptions options = new ChromeOptions();
 	options.addArguments("--remote-allow-origins=*");
 	WebDriver webDriver = new ChromeDriver(options);
 	webDriver.get("D:/Projects/Java/TestClass/src/main/java/org/example/page.html");
        
    //获取input标签下所有元素
 	List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
 	for (int i = 0; i < webElements.size(); i++) {
 		//把多选框全部勾选,单选框不操作
 		if (Objects.equals(webElements.get(i).getAttribute("type"), "radio")){
 			continue;
 		}else {
 			webElements.get(i).click();
 		}
    }
}

html文件:
自动化测试之Selenium_第4张图片

<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>Checkboxtitle>
  head>
  <body>
    <h3>checkboxh3>
    <div class="well">
      <form class="form-horizontal">
        <div class="control-group">
          <label class="control-label" for="c1">checkbox1label>
          <div class="controls">
            <input type="checkbox" id="c1"/>
          div>
        div>
        <div class="control-group">
          <label class="control-label" for="c2">checkbox2label>
          <div class="controls">
            <input type="checkbox" id="c2"/>
          div>
        div>
        <div class="control-group">
          <label class="control-label" for="c3">checkbox3label>
          <div class="controls">
            <input type="checkbox" id="c3"/>
          div>
        div>
        <div class="control-group">
          <label class="control-label" for="r">radiolabel>
          <div class="controls">
            <input type="radio" id="r1"/>
          div>
        div>
        <div class="control-group">
          <label class="control-label" for="r">radiolabel>
          <div class="controls">
            <input type="radio" id="r2"/>
          div>
        div>
      form>
    div>
  body>
html>

多层框架iframe操作

例如网内内嵌别的网页, 直接定位被包裹的元素定位不到

private static void page02() throws InterruptedException {
 	WebDriver webDriver = new ChromeDriver(options);
 	webDriver.get("D:/Projects/Java/TestClass/src/main/java/Page/test02.html");
  
	//目标元素在iframe不可直接获取,找到click元素点击
 	//切换到id="f1"框架
 	webDriver.switchTo().frame("f1");
 	webDriver.findElement(By.cssSelector("body > div > div > a")).click();
  
 	//目标元素不在iframe,可以直接获取
	//String h3_text = webDriver.findElement(By.cssSelector("body > div > div > h3")).getText();
	//System.out.println(h3_text);
 	sleep(3000);
 	webDriver.quit();
}

操作下拉框

private static void page03() throws InterruptedException {
	WebDriver webDriver = new ChromeDriver();
 	webDriver.get("D:/Projects/Java/TestClass/src/main/java/Page/test03.html");

 	//操作下拉框
 	Select select = new Select(webDriver.findElement(By.cssSelector("#ShippingMethod")));
 	//按value选择
 	select.selectByValue("12.51");
	//按索引选择
 	select.selectByIndex(2);
}

操作alert()

private static void page04() throws InterruptedException {
	WebDriver webDriver = new ChromeDriver();
	webDriver.get("D:/Projects/Java/TestClass/src/main/java/Page/test04.html");

	//点击按钮使之弹出alert
	webDriver.findElement(By.cssSelector("button")).click();
	sleep(1000);
  
	/在弹窗里插入内容
	webDriver.switchTo().alert().sendKeys("Hello World");
	//alert弹窗确定
	webDriver.switchTo().alert().accept();
	//alert弹窗取消
	//webDriver.switchTo().alert().dismiss();
}

选择文件

private static void page05() {
	WebDriver webDriver = new ChromeDriver();
	webDriver.get("D:/Projects/Java/TestClass/src/main/java/Page/test05.html");
    	
	//找到对应按钮触发选择文件,输入字符串(文件的位置)
	webDriver.findElement(By.cssSelector("input")).sendKeys("D:/Files/Pictures/background01.jpg");
}

显式等待

WebDriverWait wait = new WebDriverWait(webDriver,30);
//知道等到em元素值为"软件"的时候
wait.until(ExpectedConditions.textToBe(By.cssSelector("em"), "软件"));

特点

相同: 显式等待和隐式等待都属于智能等待
不同: 隐式等待等待页面所有元素, 显式等待等待条件满足即可

滚动页面(基于js)

#将页面滚动条拖到底部
js="var q=document.documentElement.scrollTop=10000"	//参数10000代表从左上角往下几像素

#将滚动条移动到页面的顶部
js="var q=document.documentElement.scrollTop=0"

截图

private static void test15() throws IOException, InterruptedException {
	WebDriver webDriver = new ChromeDriver();
	webDriver.get("D:/Projects/Java/TestClass/src/main/java/Page/test02.html");
  
	sleep(1000);
	//截图
	File src_file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
	//把图保存起来
	FileUtils.copyFile(src_file, new File("D:/Projects/Java/TestClass/src/main/resources/截图.png"));
}

关闭

webDriver.quit()

关闭浏览器, cookie也会删掉

webDriver.close()

关闭的是当前页面(当前标签页), 不会清除cookie

窗口切换

如果点击了按钮,弹出了新的页面想在新的页面继续操作, 要切换窗口才能找到, 不然还是在旧的页面找

private static void test16() {
	WebDriver webDriver = new ChromeDriver();
	webDriver.get("https://www.baidu.com/");
	webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
	//获取浏览器所有窗口句柄
	Set<String> handles = webDriver.getWindowHandles();
	String target_handle = "";
	for (String handle : handles) {
		target_handle = handle;
		//结束之后target_handle就是最后一个窗口的位置参数
	}
	webDriver.switchTo().window(target_handle);
	webDriver.findElement(By.cssSelector("#header-link-wrapper > li:nth-child(3)")).click();
}

你可能感兴趣的:(测试,selenium,测试工具)