selenium自动化测试04

Posted Meng XY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了selenium自动化测试04相关的知识,希望对你有一定的参考价值。

已经写到了第四篇了,也是selenium自动化的最后一篇了。当然了,自动化不止这些,还有很多很多的内容,学无止境。

前情回顾

一、搭建自动化测试环境

        项目>>浏览器+浏览器驱动+selenium(语言)

        php的web项目>>Firefox+geckodriver+selenium-Java(Java+maven+testng)

二、测试代码

WebDriver driver = new FirefoxDriver();打开浏览器,获取驱动driver对象

driver.manage().window().maximize();窗口最大化

driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);隐式等待15s,建议不要太长

driver.get("网址");访问对应页面,自带阻塞效果

driver.findElement(定位方式)定位元素,只能定位符合规则的第一个,必须定位到,否则报错

driver.findElements(定位方式),定位所有符合规则的元素,可以定位0-n个,经常判断定位是不是0判断元素是否存在

By.id\\\\name\\className\\xpath\\linkText\\tagName\\cssSelector\\partialLinkText\\xpath和cssSelector(xpath效率低,元素支持率高;cssSelector效率高,元素支持率低)

click点击

cleaar 清空输入框

Actions类,selenium中各种操作

Select类,操作下拉框:selectByIndex选择;deselectByIndex;不选

driver.switchTo()
.alert().accept();确定
.dismiss();取消
.sendKeys("");输入
.window("新窗口的handle");
.frame(索引);
.frame("frame元素的id或name值");
.frame(frame元素);
.defaultContent();
.parentFrame();

driver.getCurrentUrl();获取网址

driver.getTitle(); 获取标题

driver.getPageSource();获取页面源码

driver.close();关闭当前的窗口,如果是最后一个,会同时关闭浏览器

driver.quit();   关闭驱动,关闭所有窗口,退出浏览器 


搭建环境

testng--自动化测试>>功能自动化

testng实现自动化测试>>用于编写和执行自动化测试用例。主方法中的代码,一条崩溃,都不执行,但是用例希望一条错误,其它不受影响。控制用例的执行顺序,自动化测试报告生成,..... 

搭建testng的编写和运行环境:在项目中导入testng的jar文件,主要用于编写脚本

在pom.xml里面添加依赖,然后保存

        <!--testng依赖 -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.8</version>
            <scope>test</scope>
        </dependency>
        <!--/testng依赖 -->

        <!--feed4testng依赖 -->
        <dependency>
            <groupId>org.databene</groupId>
            <artifactId>feed4testng</artifactId>
            <version>0.6.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.2</version>
            <scope>test</scope>
        </dependency>
        <!--/feed4testng依赖 -->

 然后右边库会出现几个文件

 testng插件呢我们idea自带,不用下载


编写自动化测试用例 

编写的是执行测试用例的步骤,一般编写用例时,不相关的用例不会写到一起

一、一个class中写入1条用例,执行1遍,执行写死的数据

创包autotest04,创建class类 Testng1.class

在类里面声明一个变量,让方法可以共用

public class Testng1 
	// 声明一个变量在类中 作用于类中所有方法  希望3个方法共用一个driver
	WebDriver driver;

使用@Test

    /*
	 * 一个使用@Test修饰的普通方法就是一条测试用例
	 * 用例中没有报错,用例通过
	 * 用例中报错崩溃,用例失败
	 */
	@Test

创建方法a

public void a() 
		//用例的执行步骤 调用driver操作浏览器执行测试
		
		//用例的结果判断--1.用例通过,不能报错; 2.用例失败,必须崩溃---断言
	

创建两个方法

    /*
	 * 为了保证无论用例执行结果如何, 是否报错,浏览器打开必须关闭 
	 * 添加2个方法 无论用例结果如何必定执行
	 */

	// 一个运行于用例前 打开浏览器等一系列前置操作
	@BeforeMethod
	public void beforeMethod() 
		//给driver赋值,设置最大化,隐式等待
		//this.driver  表示类中的变量driver
		this.driver = new FirefoxDriver();
	

	// 一个运行于用例后 关闭浏览器等一系列后置操作
	@AfterMethod
	public void afterMethod() 
		//把driver给关闭
	

代码整合,一个大体框架就出来了

package org.example.autotest04;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Testng1 

    // 声明一个变量在类中 作用于类中所有方法  希望3个方法共用一个driver
    WebDriver driver;

    /*
     * 一个使用@Test修饰的普通方法就是一条测试用例
     * 用例中没有报错,用例通过
     * 用例中报错崩溃,用例失败
     */
    @Test
    public void a()
        //用例的执行步骤 调用driver操作浏览器执行测试

        //用例的结果判断--1.用例通过,不能报错; 2.用例失败,必须崩溃---断言
    

    /*
     * 为了保证无论用例执行结果如何, 是否报错,浏览器打开必须关闭
     * 添加2个方法 无论用例结果如何必定执行
     */

    // 一个运行于用例前 打开浏览器等一系列前置操作
    @BeforeMethod
    public void beforeMethod()
        //给driver赋值,设置最大化,隐式等待
        //this.driver  表示类中的变量driver
        this.driver = new FirefoxDriver();
    

    // 一个运行于用例后 关闭浏览器等一系列后置操作
    @AfterMethod
    public void afterMethod()
        //把driver给关闭
    


接下来开始实操,以登录功能进行测试

创包autotest04.case,创建class LoginTest.java,登录测试用例

把之前testng1里面的代码复制过来,然后在上面进行补充

首先,先编写用例执行前和用例执行后的操作,前置+后置操作

在@BeforeMethod处开始写前置操作

    @BeforeMethod
    public void beforeMethod()
        //给driver赋值,设置最大化,隐式等待
        //this.driver  表示类中的变量driver
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    

在@AfterMethod处写后置操作

    @AfterMethod
    public void afterMethod()
        //把driver给关闭
        driver.quit();
    

 中间的@Test开始写用例执行步骤

    @Test
    public void login() throws InterruptedException 
        //用例的执行步骤 调用driver操作浏览器执行测试
        driver.get("http://localhost:8088/index.php?m=user&c=public&a=login");
        driver.findElement(By.id("username")).sendKeys("test111");
        driver.findElement(By.id("password")).sendKeys("123456");
        driver.findElement(By.className("login_btn")).click();
        //用例的结果判断--1.用例通过,不能报错; 2.用例失败,必须崩溃---断言
        Thread.sleep(5000);
        Assert.assertEquals(driver.getCurrentUrl(),"http://localhost:8088/index.php?m=user&c=index&a=index");
    

这里面assert引用的testng,不是junit 

最后代码整合,开始执行测试用例

package org.example.autotest04.cases;


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

public class LoginTest 

    // 声明一个变量在类中 作用于类中所有方法  希望3个方法共用一个driver
    WebDriver driver;

    /*
     * 一个使用@Test修饰的普通方法就是一条测试用例
     * 用例中没有报错,用例通过
     * 用例中报错崩溃,用例失败
     */
    @Test
    public void login() throws InterruptedException 
        //用例的执行步骤 调用driver操作浏览器执行测试
        driver.get("http://localhost:8088/index.php?m=user&c=public&a=login");
        driver.findElement(By.id("username")).sendKeys("test111");
        driver.findElement(By.id("password")).sendKeys("123456");
        driver.findElement(By.className("login_btn")).click();
        //用例的结果判断--1.用例通过,不能报错; 2.用例失败,必须崩溃---断言
        Thread.sleep(5000);
        Assert.assertEquals(driver.getCurrentUrl(),"http://localhost:8088/index.php?m=user&c=index&a=index");
    

    /*
     * 为了保证无论用例执行结果如何, 是否报错,浏览器打开必须关闭
     * 添加2个方法 无论用例结果如何必定执行
     */

    // 一个运行于用例前 打开浏览器等一系列前置操作
    @BeforeMethod
    public void beforeMethod()
        //给driver赋值,设置最大化,隐式等待
        //this.driver  表示类中的变量driver
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    

    // 一个运行于用例后 关闭浏览器等一系列后置操作
    @AfterMethod
    public void afterMethod()
        //把driver给关闭
        driver.quit();
    




我这里编写的是错误用例,输出结果是测试失败,用例不通过

 执行正确的用例,通过


 二、一个class中写入多条用例,执行1遍,执行写死的数据

在autotest04创建class Testng2.java

和Testng1里面大体相似

类里面声明变量

public class Testng2 
    WebDriver driver;

@Test

因为要写多条用例,可以写多条@Test。为了让用例之间有顺序的去执行,在@Test后添加dependsOnMethods="依赖的用例方法名"

    @Test
    public void a()

    

    @Test(dependsOnMethods = "a") // a是方法名 也是用例名
    // a成功b执行 a失败b跳过
    public void b()

    

用例执行前和执行后方法

    // 2条用例执行在同一浏览器
    @BeforeClass
    public void beforeClass()
        // 类中所有方法执行前运行1次
    

    @AfterClass
    public void afterClass()
        // 类中所有方法执行后运行1次
    

有关于beforeclass,beforemethod,afterclass,aftermethod的区别可以查看这位大佬的文章TestNG 基本注解@BeforeMethod、@AfterMethod 和@BeforeClass、@AfterClass 的区别以及实际问题的解决 - 别动让左佐来 - 博客园

代码整合,一个测试多条用例的大体框架完成了

package org.example.autotest04;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class Testng2 
    WebDriver driver;

    @Test
    public void a()

    

    @Test(dependsOnMethods = "a") // a是方法名 也是用例名
    // a成功b执行 a失败b跳过
    public void b()

    

    // 2条用例执行在同一浏览器
    @BeforeClass
    public void beforeClass()
        // 类中所有方法执行前运行1次
    

    @AfterClass
    public void afterClass()
        // 类中所有方法执行后运行1次
    


接下来实操,用添加会员编写测试用例,执行测试用例。添加会员有两步:登录+添加

在包autotest04创建class AddVip.java

编写前置和后置操作

    @BeforeClass
    public void beforeClass()
        // 类中所有方法执行前运行1次
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    

    @AfterClass
    public void afterClass()
        // 类中所有方法执行后运行1次
        driver.quit();// 方法中没有声明 driver this可以省略
    

编写测试用例

    @Test
    public void login() throws InterruptedException 
        String url="http://localhost:8088/index.php?&m=admin&c=public&a=login";
        driver.get(url);
        driver.findElement(By.name("username")).sendKeys("admin");
        driver.findElement(By.name("userpass")).sendKeys("password");
        driver.findElement(By.name("userverify")).sendKeys("1234");
        driver.findElement(By.className("Btn")).click();
        //断言
        Thread.sleep(5000);
        Assert.assertNotEquals(driver.getCurrentUrl(), url);
    

    @Test(dependsOnMethods = "login")// login是方法名 也是用例名
    public void addVip() throws InterruptedException 
        driver.findElement(By.linkText("会员管理")).click();
        driver.findElement(By.linkText("添加会员")).click();

        Thread.sleep(2000);
        driver.switchTo().frame("mainFrame");
        //会员用户名
        driver.findElement(By.name("username")).sendKeys("Tony");
        //手机号
        driver.findElement(By.name("mobile_phone")).sendKeys("15123564689");
        //会员性别
        driver.findElement(By.xpath("//input[@value = '1']")).click();
        //会员邮箱
        driver.findElement(By.name("email")).sendKeys("110122119@163.com");
        //会员QQ
        driver.findElement(By.name("qq")).sendKeys("110120119");
        //提交
        driver.findElement(By.className("button_search")).click();
        //判断
        Thread.sleep(5000);
        Assert.assertTrue(driver.getPageSource().contains("注册时间"));
        // 字符串1.contains(字符串2) 1包含2 true  反之false
    

代码整合,执行测试

package org.example.autotest04.cases;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

public class AddVip 
    WebDriver driver;

    @Test
    public void login() throws InterruptedException 
        String url="http://localhost:8088/index.php?&m=admin&c=public&a=login";
        driver.get(url);
        driver.findElement(By.name("username")).sendKeys("admin");
        driver.findElement(By.name("userpass")).sendKeys("password");
        driver.findElement(By.name("userverify")).sendKeys("1234");
        driver.findElement(By.className("Btn")).click();
        //断言
        Thread.sleep(5000);
        Assert.assertNotEquals(driver.getCurrentUrl(), url);
    

    @Test(dependsOnMethods = "login")// login是方法名 也是用例名
    public void addVip() throws InterruptedException 
        driver.findElement(By.linkText("会员管理")).click();
        driver.findElement(By.linkText("添加会员")).click();

        Thread.sleep(2000);
        driver.switchTo().frame("mainFrame");
        //会员用户名
        driver.findElement(By.name("username")).sendKeys("Tony");
        //手机号
        driver.findElement(By.name("mobile_phone")).sendKeys("15123564689");
        //会员性别
        driver.findElement(By.xpath("//input[@value = '1']")).click();
        //会员邮箱
        driver.findElement(By.name("email")).sendKeys("110122119@163.com");
        //会员QQ
        driver.findElement(By.name("qq")).sendKeys("110120119");
        //提交
        driver.findElement(By.className("button_search")).click();
        //判断
        Thread.sleep(5000);
        Assert.assertTrue(driver.getPageSource().contains("注册时间"));
        // 字符串1.contains(字符串2) 1包含2 true  反之false
    

    @BeforeClass
    public void beforeClass()
        // 类中所有方法执行前运行1次
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    

    @AfterClass
    public void afterClass()
        // 类中所有方法执行后运行1次
        driver.quit();// 方法中没有声明 driver this可以省略
    

两条正确用例,两条全通过 

错误的login用例,第一条用例不通过,第二条不执行,直接跳过

 正确的login用例,错误的addvip用例


 三、一个class中写入用例,执行n遍,执行配置的数据

就是说把用例中所有写死的数据变成变量--参数化。测试用例执行的次数由提供的测试数据多少决定--数据驱动测试

在包autotest04创建class LoginTest2.java

把LoginTest里面代码复制到LoginTest2里面

第一步,构建测试用例,设计用例,把用例中写死数据都变成变量, 声明在用例的方法的小括号中,成为用例的参数

修改两处

第二步,构建测试数据,设计数据文件,测试数据和测试用例分离管理。

打开项目目录

 

在项目目录下创建文本文档a.txt,然后修改后缀,a.csv。(一定要纯文本文件,其他文件转换会乱码)

 

选中a.csv右键记事本打开,每一行不同的数据用逗号隔开,一行一组测试数据,用例需要几个写几个,位置要对应,每一行结尾直接回车换行,第一行是标题--不读

我这边写了一个正确的用例,四个错误用例

 点击文件--另存为选择编码为UTF-8,点击确定提示是否替换--是

第三步,测试用例和测试数据关联到一起 

指定读取的文件所在的位置:用例方法上加@Source("文件路径")

指定读取文件的方法:方式是feeder 写法 @Test(dataProvider="feeder"),feeder属于FeedTest类,当前用例所在类需要继承FeedTest

代码整合,进行测试

package org.example.autotest04.cases;


import org.databene.benerator.anno.Source;
import org.databene.feed4testng.FeedTest;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

public class LoginTest2 extends FeedTest 
    // 声明一个变量在类中 作用于类中所有方法  希望3个方法共用一个driver
    WebDriver driver;
    /*
     * 一个使用@Test修饰的普通方法就是一条测试用例
     * 用例中没有报错,用例通过
     * 用例中报错崩溃,用例失败
     */
    @Test(dataProvider = "feeder")// 测试用例
    @Source("a.csv")//只能读取项目目录
    public void login(String username,String password) throws InterruptedException 
        //用例的执行步骤 调用driver操作浏览器执行测试
        driver.get("http://localhost:8088/index.php?m=user&c=public&a=login");
        driver.findElement(By.id("username")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.className("login_btn")).click();
        //用例的结果判断--1.用例通过,不能报错; 2.用例失败,必须崩溃---断言
        Thread.sleep(5000);
        Assert.assertEquals(driver.getCurrentUrl(),"http://localhost:8088/index.php?m=user&c=index&a=index");
    

    /*
     * 为了保证无论用例执行结果如何, 是否报错,浏览器打开必须关闭
     * 添加2个方法 无论用例结果如何必定执行
     */

    // 一个运行于用例前 打开浏览器等一系列前置操作
    @BeforeMethod
    public void beforeMethod()
        //给driver赋值,设置最大化,隐式等待
        //this.driver  表示类中的变量driver
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    

    // 一个运行于用例后 关闭浏览器等一系列后置操作
    @AfterMethod
    public void afterMethod()
        //把driver给关闭
        driver.quit();
    




执行结果 


OK了,selenium自动化测试就告一段落了,接下来还会继续学习其他软件测试的内容,例如Java、Linux、appnium等其他学习内容,会在后续更新。

感谢您看到这里,GOOD LUCK

以上是关于selenium自动化测试04的主要内容,如果未能解决你的问题,请参考以下文章

web自动化测试入门篇04——selenium+python基础方法封装

selenium结合docker构建分布式测试环境

Selenium自动化:代码测试与无代码测试

2018-04-13web自动化学习心得

Ubuntu 18.04测试环境搭建-自动化测试

selenium-51job自动化测试(css选择器选择元素)