自动化测试

目录

前言

什么是自动化测试

自动化测试分类

接口自动化测试

特点

UI自动化测试

特点 

移动端自动化测试

Web端自动化测试

selenium工具

优点

selenium编写的自动化脚本是如何打开浏览器的(selenium、Driver、浏览器三者之间的关系)

自动化示例

1、导入selenium包

2、在Java中新建包,在包中新建类

 3、代码实现

Selenium常用方法

1、查找页面元素

2、元素的定位 By类

3、常见的元素操作

4、窗口

5、等待

6、浏览器导航

7、弹窗

8、选择框

9、执行脚本

10、文件的上传

11、浏览器参数的设置

junit

 1、注解

2、断言 Assertions类

3、用例的执行顺序

4、参数化

5、测试套件


前言

本篇博客我们将学习自动化测试以及如何使用工具编写自动化测试

什么是自动化测试

 自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常和异常,最后评估运行结果。将人为驱动的测试行为转化为机器执行的过程

自动化测试分类

接口自动化测试

接口自动化测试其实就是API测试,相对于UI自动化API自动化更加容易实现,执行起来也更稳定

特点

1、可在产品前期,接口完成后介入;

2、用力维护量小;

3、适合接口变动较小,界面变动频繁的项目

常见的测试工具有:RobotFramework,Postman,JMeter等等

UI自动化测试

UI层的自动化测试更加贴近用户的需求和软件系统的实际业务

特点 

1、用例维护量大;

2、页面相关性强,必须后期项目页面开发完成后介入;

3、UI测试适合与界面变动较小的项目

移动端自动化测试

Web端自动化测试

常见的自动化web测试工具:QTP、Selenium、RFT等等

selenium工具

安装教程

优点

1、开源免费;

2、支持多浏览器,如Chrome、Firefox、IE浏览器等等

3、支持多语言

4、支持多系统,如Linux、Windows、MacOS

5、selenium包提供了很多可供测试的使用的API

selenium编写的自动化脚本是如何打开浏览器的(selenium、Driver、浏览器三者之间的关系)

1 、程序发送Selenium命令给浏览器的驱动程序(简单理解为脚本就是命令)

2 、浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令

3 、浏览器驱动程序获取命令执行的结果,返回给自程序

4 、程序对返回结果进行处理

自动化示例

1、导入selenium包

2、在Java中新建包,在包中新建类

 3、代码实现

创建驱动实例,创建会话;访问网站;查找元素;操作元素;结束会话

//查询网址搜索关键词边伯贤
    public void baekhyunTest() throws InterruptedException {
        //创建驱动实例,创建会话(打开浏览器
        ChromeDriver driver = new ChromeDriver();
        Thread.sleep(5000);
        //在浏览器输入百度网址,访问百度首页
        driver.get("https://www.baidu.com");
        Thread.sleep(5000);
        //找到百度首页输入框元素,并输入关键词“边伯贤”
        driver.findElement(By.cssSelector("#kw")).sendKeys("边伯贤");
        Thread.sleep(5000);
        //找到百度首页“百度一下“按钮,并点击一下
        driver.findElement(By.cssSelector("#su")).click();
        Thread.sleep(5000);
        //结束会话(关闭浏览器)
        driver.quit();
    }

Selenium常用方法

1、查找页面元素

findElement()

参数:By类(提供通过什么方式来查找元素)

返回值:webElement

findElements()

参数:By类(提供通过什么方式来查找元素)

返回值:List<webElement>

public void methodTest(){
        ChromeDriver driver=new ChromeDriver();
        driver.get("https://www.baidu.com");
        List<WebElement> eles=driver.findElements(By.className("hotsearch-item"));
        for(WebElement ele:eles){
            System.out.println(ele.getText());
        }
    }

2、元素的定位 By类

selector(基础选择器、复合选择器)

功能:选中页面中指定的标签元素

        //元素的定位
        //选择器selector
        driver.findElement(By.cssSelector(“kw”));

xpath

语法:

                层级:/子级 //跳级

                属性:@

                函数:contains()......

自动化要求元素的定位必须要唯一。但是手动在页面复制selector或者xpath元素不一定是唯一的,需要我们进行手动修改到唯一

3、常见的元素操作

对元素操作的前提:能够找到元素

3.1、输入文本

sendKeys

仅适用于文本字段和内容可编辑的元素

WebElement ele=driver.findElement(By.cssSelector("#kw"));
ele.sendKeys("baekhyun yyds!");
driver.findElement(By.cssSelector("#kw")).sendKeys("baekhyun yyds");

3.2、点击click

driver.findElement(By.cssSelector("#su")).click();

案例:博客系统的自动登录

    public void TestBlogLogin() throws InterruptedException {
        driver.get("http://101.42.46.10:8080/blogSystem/login.html");
        Thread.sleep(3000);
        driver.findElement(By.cssSelector("#username")).sendKeys("啵啵");
        driver.findElement(By.cssSelector("#password")).sendKeys("123");
        driver.findElement(By.cssSelector("#login-btn")).click();
        Thread.sleep(3000);
        driver.quit();
    }

3.3、提交 submit(通过回车键提交)

仅适用于表单元素

        driver.findElement(By.cssSelector("#su")).submit();

3.4、清除 clear

        driver.findElement(By.cssSelector("#kw")).sendKeys("baekhyun yyds");
        Thread.sleep(2000);
        driver.findElement(By.cssSelector("#kw")).clear();
        driver.findElement(By.cssSelector("#kw")).sendKeys("baekhyun");
        driver.findElement(By.cssSelector("#su")).click();

3.5、获取文本 getText()

获取属性的值getAttribute()

        String text=driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(2) > a > span.title-content-title")).getText();
        System.out.println("获取到的文本:"+text);

3.6、获取页面的标题和URL

        System.out.println(driver.getTitle());
        System.out.println(driver.getCurrentUrl());

4、窗口

4.1、窗口大小的设置:最大化、最小化、全屏窗口、手动设置窗口大小

        //窗口最大化
        driver.manage().window().maximize();
        Thread.sleep(3000);
        //窗口最小化
        driver.manage().window().minimize();
        Thread.sleep(3000);
        //全屏
        driver.manage().window().fullscreen();
        Thread.sleep(3000);
        //手动设置窗口大小
        driver.manage().window().setSize(new Dimension(1024,512));
        Thread.sleep(3000);

4.2、窗口的切换

打开百度首页,点击图片超链接进入到百度图片首页,获取百度图片页面的“百度一下”按钮

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

        driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
        //
        String curhandel=driver.getWindowHandle();
        System.out.println(curhandel);
        //先获取所有标签的句柄
        Set<String> handels=driver.getWindowHandles();
        for (String handel:handels){
            if (handel!=curhandel){
                driver.switchTo().window(handel);
            }
        }
        Thread.sleep(3000);
        driver.findElement(By.cssSelector("#homeSearchForm > span.s_btn_wr > input")).click();

4.3、屏幕截图

首先保存屏幕截图文件需要用到的包

        <!--保存屏幕截图文件所要用到的包        -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>
        driver.findElement(By.cssSelector("#kw")).sendKeys("边伯贤");
        driver.findElement(By.cssSelector("#su")).click();
        Thread.sleep(3000);
        //屏幕截图(保存现场)
        File srcfile=driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图好的文件放到指定的路径下
        String filename="my.png";
        FileUtils.copyFile(srcfile,new File(filename));
        driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az

当程序执行时,我们需要在代码里添加等待机制

5、等待

强制等待、隐式等待、显示等待、流畅等待

5.1、强制等待

程序阻塞进行  Thread.sleep()

5.2、隐式等待

会作用于driver的整个生命周期,隐式等待会一直轮询判断元素是否存在,如果不存在就在等待好的时间里不断地进行轮询,直到元素能够被找到

    void implicitlyWait(){
        //添加隐式等待
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        driver.get("https://www.baidu.com");
        driver.findElement(By.cssSelector("#kw")).sendKeys("都暻秀");
        driver.findElement(By.cssSelector("#su")).click();
        driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span"));
        driver.quit();
    }

5.3、显示等待

WebDriverWait(WebDirver,Duration)

    void webDriverWait(){
        driver.get("https://www.baidu.com");
        driver.findElement(By.cssSelector("#kw")).sendKeys("都暻秀");
        driver.findElement(By.cssSelector("#su")).click();
        //显示等待
        new WebDriverWait(driver,Duration.ofSeconds(5)).until(driver->driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span")));
        driver.quit();
    }

6、浏览器导航

浏览器的前进、后退、刷新

    void navigateControl() throws InterruptedException {
        //driver.get("https://www.baidu.com");
        driver.navigate().to("https://www.baidu.com");
        Thread.sleep(3000);
        //想要回退到访问百度网址之前的状态
        driver.navigate().back();
        Thread.sleep(3000);
        //前进,又进入到了百度首页
        driver.navigate().forward();
        Thread.sleep(3000);
        //刷新百度首页
        driver.navigate().refresh();
        Thread.sleep(3000);
        driver.quit();
    }

7、弹窗

弹窗的类型:警告弹窗、确认弹窗、提示弹窗

处理弹窗的步骤:

1、将driver对象作用到弹窗上(切换到弹窗);

dirver.switchTo.alert()

2、选择确认或取消(提示弹窗输入文本)

    void AlertControl(){
        //弹窗
        //get参数为url,而不是文件路径
        //在本地打开html文件之后,需要复制浏览器里的链接放到get里,而不是复制html本地的文件路径
        driver.get("xxx");
        //打开弹窗
        driver.findElement(By.cssSelector("xxx")).click();
        //切换到弹窗进行弹窗的处理
        Alert alert=driver.switchTo().alert();
        //1、点击确认
        alert.accept();
        //2、点击取消
        alert.dismiss();
        //3、输入关键词
        alert.sendKeys("xxx");
        driver.quit();
    }

警告弹窗只有确认按钮,但是accept和dismiss都能处理;

警告弹窗和确认弹窗都没有输入文本的地方,但是如果要执行alert.sendKeys代码也不会报错

8、选择框

选项的选择方式:1、根据文本来选择;2、根据属性框来选择;3、根据序号来选择

    void selectControl() throws InterruptedException {
        //选择框
        driver.get("xxx");
        Thread.sleep(3000);
        WebElement ele=driver.findElement(By.cssSelector("xxx"));
        //先创建选择框对象
        Select select=new Select(ele);
        Thread.sleep(3000);
        //根据文本来选择
        select.selectByVisibleText("");
        //根据属性值来选择
        select.selectByValue("");
        //根据序号来选择
        select.selectByIndex(x);
        Thread.sleep(3000);
        driver.quit();
    }

9、执行脚本

executeScript()其中的参数是js代码

    void scriptControl() throws InterruptedException {
        //执行脚本
        driver.get("https://image.baidu.com/");
        Thread.sleep(3000);
        //执行js命令:让页面置顶/置底
        driver.executeScript("document.documentElement.scrollTop=300");
        Thread.sleep(300);
        driver.executeScript("document.documentElement.scrollTop=0");
        Thread.sleep(300);
        driver.quit();
    }
        driver.get("https://www.baidu.com");
        Thread.sleep(3000);
        driver.executeScript("var d=document.querySelector('#kw');d.value='边伯贤'");
        Thread.sleep(3000);
        driver.quit();

10、文件的上传

sendKeys(“文件路径+文件”)

    void fileUploadControl() throws InterruptedException {
        driver.get("xxx");
        Thread.sleep(3000);
        driver.findElement(By.cssSelector("xxx")).sendKeys("文件路径+文件");
        Thread.sleep(3000);
        driver.quit();
    }

11、浏览器参数的设置

实际在工作中,测试人员将自动化部署在机器上自动地执行,测试人员不会关注过程,而是直接查看自动化执行的结果

无头模式

    void paramControl(){
        //百度搜索边伯贤
        //先创建选项对象,在设置浏览器参数
        ChromeOptions options=new ChromeOptions();
        options.addArguments("-headless");
        ChromeDriver driver=new ChromeDriver(options);
        driver.get("https://www.baidu.com");
        driver.findElement(By.cssSelector("#kw")).sendKeys("边伯贤");
        driver.findElement(By.cssSelector("#su")).click();
        driver.quit();
    }

浏览器的参数设置需要在创建浏览器对象之前

junit

junit是Java的单元测试工具,我们在实现自动化的时候需要借助一下junit库里面提供的一些方法

 1、注解

@Test

表示方法是测试方法,执行当前这个类时,会自动的执行该类下所有带@Test注解的用例

@BeforeEach

表示当前的方法需要在每个用例执行之前都执行一次

@BeforeAll

表示当前的方法需要在当前类下所有用例之前执行一次,被该注解修饰的方法必须为静态方法

@AfterEach

表示当前的方法需要在每个用例执行之后都执行一次

@AfterAll

表示当前的方法需要在当前类下所有用例之后执行一次,被该注解修饰的方法必须为静态方法

public class junitTest {
//    @BeforeEach
//    void baseAnnotate(){
//        System.out.println("beakhyun");
//    }

//    @BeforeAll
//    static void cy(){
//        System.out.println("chanyeol");
//    }
    //    @AfterEach
//    void baseAnnotate(){
//        System.out.println("beakhyun");
//    }
    @AfterAll
    static void cy(){
        System.out.println("chanyeol");
    }
    @Test
    void dd(){
        System.out.println("do");
    }
    @Test
    void sh(){
        System.out.println("sehun");
    }
}

2、断言 Assertions类

断言匹配/不匹配

assertEquals/assertNotEquals

    @Test
    void assertTest(){
        ChromeDriver driver=new ChromeDriver();
        driver.get("https://www.baidu.com");
        String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");
        System.out.println(text);
        //Assertions.assertEquals("百度两下",text);
        Assertions.assertNotEquals("百度两下",text);
        driver.quit();
    }

断言为真/断言为假

assertTrue/assertFalse

    @Test
    void assertTest1(){
        //Assertions.assertTrue(4==12);
        Assertions.assertFalse(4==12);
    }

断言结果为空/不为空

assertNull/assertNotNull

    @Test
    void assertTest2(){
        //Assertions.assertNull("beakhyun");
        Assertions.assertNotNull("beakhyun");
    }

3、用例的执行顺序

测试用例的执行与编写测试用例的顺序无关

3.1、通过order注解来排序

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class junitTest {
    @Test
    @Order(2)
    void loginTest(){
        System.out.println("loginTest");
    }
    @Test
    @Order(3)
    void indexTest(){
        System.out.println("indexTest");
    }
    @Test
    @Order(1)
    void editTest(){
        System.out.println("editTest");
    }
}

先要使用注解说明当前类下所有的用例需要使用order注解来进行排序(注意:该注解必须使用到类上);然后通过order来指定用例的具体顺序 

4、参数化

尽可能的通过一个用例,多组参数来模拟用户的行为

在使用参数化注解之前需要声明该方法为参数化方法 @ParameterizedTest

4.1、单参数

要通过注解提供数据来源

    @ParameterizedTest
    @ValueSource(strings={"beakhyun","do","sehun"})
    void SparamsTest(String name){
        System.out.println(name);
    }

@ValueSource(数据类型方法={参数1,参数2,参数3...}) 

4.2、多参数

从注解里手动编写数据源(每个双引号就是一组参数/测试用例)

    @ParameterizedTest
    @CsvSource({"baekhyun,30","do,29","sehun,28"})
    void muchParamsTest(String name,int age){
        System.out.println("name:"+name+",age:"+age);
    }

 从第三方csv文件读取数据源

    @ParameterizedTest
    @CsvFileSource(files="C:\\Users\\admin\\Desktop\\mycsv.csv")
    void csvfileParamsTest(String name,int age){
        System.out.println("name:"+name+",age:"+age);
    }

4.3、动态参数

如果要返回的数据类型不统一,就需要使用组合类型Arguments 

    @ParameterizedTest
    @MethodSource("methodParams")
    void dynamicmethodParmsTest(String name,int age){
        System.out.println("name:"+name+",age:"+age);
    }
    static Stream<Arguments> methodParams() throws InterruptedException {
        //构造动态参数
        String[] arr=new String[5];
        for (int i=0;i<arr.length;i++){
            Thread.sleep(500);
            arr[i]=System.currentTimeMillis()+"";
        }
        return Stream.of(
                Arguments.arguments(arr[0],20),
                Arguments.arguments(arr[1],20),
                Arguments.arguments(arr[2],20),
                Arguments.arguments(arr[3],20),
                Arguments.arguments(arr[4],20)
        );
    }

 使用了参数化注解的方法不能再使用@Test注解(@Test只能作用到非参数化的用例上)

5、测试套件

先创建一个类,通过@Suite注解标识该类为测试套件类(而不是测试类)

@Suite
public class runSuite {
}

5.1、指定类来运行用例

@Suite
@SelectClasses({aaa.class,bbb.class})
public class runSuite {
}

想要运行的用例必须被@Test注解(除参数化的用例外)

5.2、指定包名来运行包下的所有用例

@Suite
@SelectPackages("com.autotest0212")
public class runSuite {
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值