Java自动化测试-Selenium方法封装+TestNG注解介绍使用

275 阅读4分钟

在此之前默认你已经掌握 封装 继承 多态,熟练掌握 数组 集合 I/O流等Java基础

本章将介绍Selenium公共方法的封装和TestNG生成测试报告

我的环境:JDK21+IDEA2024.1.4+Springboot3.3.7

首先我们来认识一下TestNG常用注解

TestNG的常用注解
@Test标记一个类或方法作为测试类/测试方法
@BeforeMethod在每个测试方法运行之前运行。
@AfterMethod在每个测试方法运行之后运行。
@BeforeClass在当前类中所有方法运行之前调用,只运行一次。
@AfterClass在当前类中所有方法运行之后调用,只运行一次。
@BeforeSuite带有此注解的方法会在一个测试套件执行之前执行一次。
@AfterSuite带有此注解的方法会在一个测试套件执行之后执行一次。
@DataProvider用于为测试方法提供数据,支持参数化测试。
@Test(dataProvider = "XXX")指定使用哪个数据提供器。

其他不常用的注解
@Test(groups = "XXX"):将测试方法分组,以便可以按组运行测试。
@BeforeGroups("XXX")@AfterGroups("XXX"):在指定组的第一个和最后一个测试方法之前/之后运行。
@BeforeTest@AfterTest:在XML文件中的每个<test>标签执行前/后运行。这些注解通常与测试套件配置相关。

了解Spring的童鞋是不是想到了前置通知,后置通知,环绕通知,(狗头狗头狗头狗头狗头狗头) 接下来我们用简单的代码来演示这些注解怎么用的

package asia.springcloud;

import org.testng.annotations.*;

/**
 * @author lizheng
 * @version 1.0
 * @description: TODO
 * @CreateTime 2025/1/6 21:35
 */
public class TestAnno {
    @Test
    public void testCase1(){
        System.out.println("测试用例1");
    }
    @Test
    public void testCase2(){
        System.out.println("测试用例2");
    }

    @BeforeMethod
    public void beforeMethod(){
        System.out.println("BeforeMethod=====测试用例执行前");
    }

    @AfterMethod
    public void afterMethod(){
        System.out.println("AfterMethod=====测试用例执行后");
    }

    @BeforeClass
    public void beforeClass(){
        System.out.println("BeforeClass=====测试类执行前");
    }
    @AfterClass
    public void afterClass(){
        System.out.println("AfterClass=====测试类执行后");
    }

    @BeforeSuite
    public void beforeSuite(){
        System.out.println("BeforeSuite=====测试套件执行前");
    }

    @AfterSuite
    public void afterSuite(){
        System.out.println("AfterSuite=====测试套件执行后");
    }

    @DataProvider(name = "测试数据")
    public Object[][] data(){
        return new Object[][]{{"张三","富二代",1},{"李四","代码仔",2}};
    }

    @Test(dataProvider = "测试数据")
    public void testCase3(String name,String sex,int age){
        System.out.println(name+sex+age);
    }
}

以上代码运行结果

image.png 可以明显看到,添加了TestNG注解的方法并不是按照编写方法的顺序执行的 方法的执行顺序: @BeforeSuite > @BeforeClass > @BeforeMethod > @Test > @AfterMethod > @BeforeMethod > @Test > @AfterMethod > @BeforeMethod > @Test > @AfterMethod > @AfterClass > @AfterSuite
以上就是对TestNG注解使用方法的简单介绍,接下来我们开始封装Selenium公共方法

在这之前我们的脚本是没有经过任何封装处理的,比如浏览器的初始化配置,脚本执行完对资源的释放,导致我们每写一个测试脚本这些方法都要重复编写,像这种重复使用的方法我们可以封装起来较少代码量,提高复用性,也可以体现我们对Java的理解

第一步,新建script和util的包,用于存放我们的自动化脚本和公共方法

image.png

在util包中创建一个类,我这里叫SeleniumUtil

image.png

现在我们可以在这个类中封装我们的浏览器初始化和浏览器退出方法
因为我项目使用的是Springboot,所以我习惯性的使用了@Autowired依赖注入,没有使用Springboot的童鞋也可以使用protected WebDriver webDriver;
其核心目的都是为了方便调用和管理 WebDriver,以确保测试或自动化脚本能够高效、灵活地与浏览器进行交互

package asia.springcloud.util;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.AfterClass;

/**
 * @author lizheng
 * @version 1.0
 * @description: 用于封装Selenium公共方法
 * @CreateTime 2025/1/6 20:47
 */
public class SeleniumUtil {

    //浏览器驱动
    @Autowired
    private WebDriver webDriver;

    /**
     * @description: 初始化方法
     * @author: lizheng
     * @date: 2025/1/6 20:48
     * @param:
     * @return:
     */
    public void setWebDriver(){
        //chrome驱动
        System.setProperty("webdriver.chrome.driver","C:\Program Files\Google\Chrome\Application\chromedriver.exe");
        ChromeOptions options = new ChromeOptions();//创建ChromeOptions对象

        options.addArguments("--remote-allow-origins=*");
        webDriver = new ChromeDriver(options);

        webDriver.manage().window().maximize();
    }

    /**
     * @description: 退出浏览器
     * @author: lizheng
     * @date: 2025/1/6 20:51
     * @param:
     * @return:
     */
    @AfterClass
    public void quitBrowser(){
        if (webDriver != null){
            webDriver.quit();
        }
    }


}

封装了初始化和退出方法,我们再写测试脚本的时候就不用重复编写这两个方法了,以下是封装之后的案例

package asia.springcloud.script;

import asia.springcloud.util.SeleniumBase;
import io.qameta.allure.*;
import io.qameta.allure.testng.AllureTestNg;
import org.openqa.selenium.By;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.time.Duration;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author lizheng
 * @version 1.0
 * @description: 
 * @CreateTime 2025/1/1 16:40
 */
@Listeners({AllureTestNg.class})
public class TestReadBookPage extends SeleniumBase {

    private static final Logger log = LoggerFactory.getLogger(SeleniumBase.class);

    @BeforeClass
    @Description("测试豆瓣读书-浏览器初始化")
    public void setUpClass(){
        setWebDriver();//浏览器初始化
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        webDriver.get("https://www.douban.com/");
    }

    @AfterClass
    public void tearDownClass() throws InterruptedException {
        TimeUnit.SECONDS.sleep(2);
        tearDown();//浏览器关闭
    }
    @Test(priority = 1)//优先级为1
    @Description("用例描述")
    @Step("操作步骤")
    @Feature("功能模块")
    //@Link("http://www.douban.com")
    public void getHomePageTitle(){
        Allure.step("打开豆瓣网,测试页面标题是否有”豆瓣“");
        String title = webDriver.getTitle();
        //log.info("当前页面标题为:" + title);
        System.out.println("当前页面标题为:" + title);
        Assert.assertTrue(title.contains("豆瓣"),"标题不含豆瓣");
    }

代码逻辑非常简单,至此Selenium方法封装和TestNG注解使用基本介绍完毕,
本来写之前想了很多细节,但是今天太晚了,昨天熬了个大夜,写不下去了,
我知道这篇比较粗糙,有啥问题可以在评论区交流,我尽量解答