您现在的位置是:首页 >技术教程 >【自动化测试】selenium工具网站首页技术教程

【自动化测试】selenium工具

X_H学Java 2024-06-29 06:01:02
简介【自动化测试】selenium工具

为什么要做自动化测试?

自动化测试就是将手工执行测试转变为使用代码来执行测试,自动化测试能够代替一部分手工测试,提高测试效率,并且随着项目版本的更新,回归测试压力越来越大,可以借助自动化来进行回归测试

为什么选用Selenium?

Selenium是用来做Web自动化的框架

selenium的特点:

  • 支持多浏览器(Chrome,Firefox,Edge…)
  • 支持多系统(Linux,Windows,Mac…)
  • 支持多语言(Python,Java,C#…)
  • 拥有丰富的API

Selenium的工作原理

在这里插入图片描述

总结: 我们的脚本代码会发送一个http请求到驱动,驱动解析请求后操作浏览器执行相对应的操作,待浏览器执行完相应的操作后,会将执行结果返回给驱动,驱动收到结果后,又将结果返回给脚本代码

Selenium+Java环境搭建

这里推荐使用Chrome浏览器

先查看Chrome浏览器的版本
在这里插入图片描述
链接: Chrome驱动下载地址

点击上述链接下载对应的驱动版本,并将驱动放在jdk的bin目录
在这里插入图片描述

创建一个Maven项目,并添加selenium依赖

       <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>

验证环境是否搭建成功:

public class Test {
    public static void main(String[] args) {
        ChromeOptions options = new ChromeOptions();
        //允许所有请求
        options.addArguments("--remote-allow-origins=*");
        WebDriver driver = new ChromeDriver(options);
        driver.get("https://www.baidu.com"); //访问百度网址
        driver.quit(); //退出浏览器
    }
}

启动运行,发现代码会操作浏览器访问百度网址,说明环境搭建成功

在这里插入图片描述

Selenium常用API

浏览器参数配置

ChromeOptions options = new ChromeOptions(); //创建浏览器参数配置对象
options.addArguments("-headless"); //无头模式
options.addArguments("--remote-allow-origins=*");
ChromeDriver driver = new ChromeDriver(options);

无头模式不会在桌面打开浏览器

定位元素

定位元素的方式有以下方式:

  • id
  • name
  • tag name
  • class name
  • css 选择器(#id,.class,input,…)
  • XPath
  • linkText(链接内容)
  • partialLinkText(部分链接内容)
        //获取到页面元素,对应的类型为WebElement
        WebElement element = driver.findElement(By.cssSelector("#kw"));
        driver.findElement(By.id("kw")); //通过id
        driver.findElement(By.name("wd")); //通过name
        driver.findElement(By.tagName("input")); //通过tag name,也就是标签名
        driver.findElement(By.className("s_ipt")); //通过类名
        driver.findElement(By.cssSelector("#kw")); //通过css选择器
        driver.findElement(By.xpath("//*[@id="kw"]")); //通过XPath
        driver.findElement(By.linkText("新闻")); //通过超链接内容
        driver.findElement(By.partialLinkText("123")); //通过超链接部分内容

操作测试对象

  • sendKeys(“str”):向输入框输入内容
  • click():模拟鼠标点击
  • getText():获取元素的文本内容(首标签与尾标签之间的文本)
  • clear():清除输入框输入内容
  • submit():提交(只能用于form标签内的元素)
  • getAttribute(“str”):获取标签属性值
        element.sendKeys("庆余年"); //输入
        element.click(); //点击
        element.getText(); //获取元素的文本信息
        element.clear(); //清除输入框内容
        element.submit(); //提交
        element.getAttribute("type"); //获取标签属性

时间等待

  • 强制等待:Thread.sleep()
  • 隐式等待:driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3))
  • 显示等待:显示指定等待某一个元素的加载时间(只作用于一条查询元素上
sleep(3000); //强制等待
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS); //隐式等待3秒,作用于driver的整个生命周期
//显示等待
new WebDriverWait(driver,Duration.ofSeconds(3)).until(driver1->driver.findElement(By.cssSelector("#id")));

区别:

  • 强制等待会一直等待设置的时间,程序阻塞执行,直到时间结束
  • 隐式等待(等待页面的所有元素都加载好,),在等待的时间内,如果页面元素加载好了,就会提前结束等待(上述代码最多只等待3秒)

信息打印

  • 打印title:getTitle()
  • 打印url:getCurrentUrl()
String url = driver.getCurrentUrl(); //获取url
System.out.println(url);
String title = driver.getTitle(); //获取title
System.out.println(title);

对浏览器操作

关闭浏览器

driver.quit();
driver.close();

区别:

  • quit关闭整个浏览器,close关闭当前页面
  • quit会清除浏览器缓存,close不会清除缓存

浏览器窗口大小设置

  • maximize():浏览器最大化
  • minimize():浏览器最小化
  • fullscreen():浏览器全屏
  • setSize(new Dimension(int width,int height)):手动设置浏览器窗口大小
driver.manage().window().maximize(); //窗口最大化
driver.manage().window().minimize(); //窗口最小化
driver.manage().window().fullscreen(); //全屏
driver.manage().window().setSize(new Dimension(1024,600)); //手动设置大小,第一个参数为宽,第二个参数为高

浏览器窗口切换操作

浏览器打开新的标签页的时候,浏览器此时操作元素的时候,还是操作的是跳转之前的页面,如果想操作新打开的标签页面的元素,可进行如下操作

浏览器每次打开一个标签页的时候,会自动的给每个标签页进行标识(句柄

Set<String> handles = driver.getWindowHandles(); //获取所有标签的句柄
String curHandle = driver.getWindowHandle(); //获取当前页面(get打开)的句柄
for(String handle : handles){
    if(!curHandle.equals(handle)){ //如果当前句柄与遍历的不相等
        driver.switchTo().window(handle); //跳转过去
    }
}

浏览器的前进后退

  • back:浏览器后退
  • forward:浏览器前进
  • refresh:浏览器刷新
//浏览器的前进后退及刷新
driver.navigate().back(); //后退
driver.navigate().forward(); //前进
driver.navigate().refresh(); //刷新

//访问url除get外的别种写法
driver.navigate().to("https://www.baidu.com");

借助js代码操作浏览器滚动条

String js = "document.documentElement.scrollTop=10000"; //scrollTop为距浏览器顶部的距离
((JavascriptExecutor)driver).executeScript(js); //将driver强转为JavascriptExecutor

键盘与鼠标操作

键盘操作

driver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A"); //ctrl+a
driver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"C"); //ctrl+c
driver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V"); //ctrl+v
driver.findElement(By.cssSelector("#kw")).sendKeys(Keys.ENTER); //回车

鼠标操作

WebElement element = driver.findElement(By.cssSelector("#kw")); //定位元素
Actions actions = new Actions(driver); //需要借助Actions,参数据传递浏览器驱动
actions.moveToElement(element).contextClick().perform(); //鼠标移动到元素上,右击
actions.moveToElement(element).doubleClick().perform(); //鼠标移动到元素上,双击

屏幕截图

先在pom.xml中添加依赖

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

截图保存

File file = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); //截图赋值给file
FileUtils.copyFile(file,new File("./0522.png")); //保存在硬盘

弹窗处理

弹窗的类型:

  • 警告弹窗

在这里插入图片描述

  • 确认弹窗

在这里插入图片描述

  • 提示弹窗

在这里插入图片描述

弹窗不能使用定位元素的方式定位

操作弹窗的步骤:

  1. 将driver对象切换到弹窗上:driver.switchTo().alert()
  2. 进行确定,取消,输入,获取弹窗文本内容操作:acceptdismisssendKeys("xxx")getText
//弹窗的处理
Alert alert = driver.switchTo().alert(); //定位到弹窗
alert.accept(); //确定
alert.dismiss(); //取消
alert.sendKeys("zs"); //输入
alert.accept(); //输入内容后需要确认
String alertText = alert.getText(); //获取弹窗文本内容

说明:

  • 虽然警告弹窗只有确定按钮,但是accept和dismiss操作都可关闭弹窗
  • 虽然警告和确认弹窗没有输入框,但是执行alert.sendkeys操作也不会报错

选择框的处理

在这里插入图片描述

  • 根据文本选择selectByVisibleText
  • 根据属性值选择selectByValue
  • 根据序号选择selectByIndex
WebElement element = driver.findElement(By.cssSelector("body > select"));
Select select = new Select(element); //创建选择框对象
select.selectByVisibleText("深圳"); //根据文本选择
select.selectByValue("02"); //根据属性值选择
select.selectByIndex(1); //下标从0开始,1代表第二个

上传文件

//上传文件
WebElement element1 = driver.findElement(By.cssSelector("body > input[type=file]:nth-child(5)"));
element1.sendKeys("文件路径");

JUnit单元测试

JUnit是Java的单元测试框架,此处的版本是JUnit5

在pom.xml中添加JUnit的依赖

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>

注解

  • @Test:加在方法上,表示该方法是一个测试用例
  • @Disabled:加在方法上,表示当前方法不参与测试用例的执行
  • @BeforeEach:表示当前方法在每个用例执行前都会执行一次
  • @BeforeAll:表示当前方法(方法需用static修饰)在所有用例执行前执行一次
  • @AfterEach:表示当前方法在每个用例执行后都会执行一次
  • @AfterAll:表示当前方法(方法需用static修饰)在所有用例执行完执行一次

在做UI自动化的时候,一般将驱动的创建,打开的url信息放到@BeforeAll方法里,将浏览器关闭的信息放到@AfterAll方法里

参数化

使用@ParameterizedTest@ValueSource注解进行参数化的设置

单个参数

    @ParameterizedTest
    @ValueSource(ints = {1,2,3})
    void method2(int i){
        System.out.println(i);
    }

在这里插入图片描述

    @ParameterizedTest
    @ValueSource(strings = {"zs","ls","ww"})
    void method2(String s){
        System.out.println(s);
    }

在这里插入图片描述

多个参数

使用@CsvSource,可以给多个参数类型传递参数

    @ParameterizedTest
    @CsvSource(value = {"zs,5","li,6","wu,7"})
    void method4(String name,int id){
        System.out.println(id+":"+name);
    }

在这里插入图片描述

CSV获取参数

如果参数的用例非常多,则可以将测试的参数放进csv文件中,然后通过csv文件获取参数(每个参数类型对应文件的一列数据,列与列之间用 分割)

    @ParameterizedTest
    @CsvFileSource(files = "./dir/test01.csv") //文件路径
    void method3(String name,int i){
        System.out.println(name+":"+i);
    }

在这里插入图片描述

打印结果:

在这里插入图片描述

方法获取参数

public class Test {
    @ParameterizedTest
    @MethodSource("test111")
    void method1(String name,int id){
        System.out.println(id+":"+name);
    }
    static Stream<Arguments> test111(){
        return Stream.of(Arguments.arguments("zs",2),
                Arguments.arguments("ls",3),
                Arguments.arguments("wu",4));
    }
}

在这里插入图片描述

用例的执行顺序

使用@TestMethodOrder与@Order注解进行排序

//该注解表示当前类下所有的用例需要使用order注解来进行排序
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class Test04 {

    @Order(1)
    @Test
    void test_m1(){
        System.out.println("m1");
    }
    @Order(2)
    @Test
    void test_m2(){
        System.out.println("m2");
    }
    @Order(3)
    @Test
    void test_m3(){
        System.out.println("m3");
    }
}

断言

  • Assertions.assertEquals(s1,s2):匹配才通过

  • Assertions.assertNotEquals(s1,s2):不匹配才通过

  • Assertions.assertTrue(条件):条件为真通过

  • Assertions.assertFalse(条件):条件为假才通过

  • Assertions.assertNull(xxx):xxx为null才通过

  • Assertions.assertNotNull(xxx):xxx不为null才通过

测试套件

通过class运行测试用例

@Suite
//先跑01.class,接着02.class,最后03.class
@SelectClasses({Test01.class, Test02.class, Test03.class})
public class RunSuit {

}

通过包运行测试用例

@Suite
//先跑autotest1包,再跑autotest2包
@SelectPackages(value = {"autotest1","autotest2"})
public class RunSuit1 {
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。