JavaWeb学习总结

Java语言UI自动化框架学习总结

跟着CSDN的一位前辈搭建了基于Java语言的Web自动化框架,总结一下自己所学

整体架构基于Selenium和TestNG,用到了一些第三方库用来锦上添花,如:

log4j 日志输出

allure 美化测试报告

commons-io 截图支持

前辈主页(https://blog.csdn.net/Keep_Learn2020?type=blog)

不要等改了一大堆才运行程序!

不要等改了一大堆才运行程序!

不要等改了一大堆才运行程序!

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.1.1</version>
    </dependency>
   

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-testng</artifactId>
        <version>2.17.2</version>
    </dependency>

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

</dependencies>

1.封装浏览器工具类

1.1 导入selenium依赖

<!--selenium依赖,必备-->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.1.1</version>
</dependency>

1.2 新建utils包,在包下新建WebDriverUtils工具类

因为我只用chrome浏览器,所以只写了这个,大佬有写别的浏览器,有需要的可以去看

package utils;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebDriverUtils {
    public static WebDriver webDriver;
    public static void openBrowser(String browserName){
        if ("chrome".equals(browserName)){
            System.setProperty("webdriver.chrome.driver","D:\\Python\\chromedriver.exe");
            webDriver = new ChromeDriver();
        }
    }
}

2. 实现登录功能

新建包结构:testcase包,用来保存测试用例

新建一个TestCaseLogin类,线性代码实现单个登录功能,为了方便调试,加入try catch 代码块且每个动作都加了延迟

package testcase;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.WebDriverUtils;

public class TestCaseLogin {
    public static void main(String[] args) throws InterruptedException {
        WebDriverUtils.openBrowser("chrome");
        WebDriver webDriver = WebDriverUtils.webDriver;
        webDriver.get("测试地址");
        webDriver.findElement(By.xpath("xpath")).sendKeys("username");
        Thread.sleep(1000);
        webDriver.findElement(By.xpath("xpath")).sendKeys("password");
        Thread.sleep(1000);
        webDriver.findElement(By.className("login-btn")).click();
        Thread.sleep(3000);

        //显示等待应用
        WebDriverWait wait = new WebDriverWait(webDriver, 5);

        try {
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("layout-logo-sys")));
            System.out.println("测试通过!");
        } catch (Exception e) {
            System.out.println("测试不通过!");
        }finally {
            webDriver.quit();
        }
    }
}

3. TestNG

3.1 导入testng

<!--testng依赖,必备-->
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.5</version>
    <scope>test</scope>
</dependency>

3.2 加入TestNG注解

使用testng注解,修改TestCaseLogin类中的线性代码

package testcase;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import utils.WebDriverUtils;

public class TestCaseLogin {
    public WebDriver webDriver;

    @BeforeMethod
    public void setupMethod() {
        WebDriverUtils.openBrowser("chrome");
        webDriver = WebDriverUtils.webDriver;
        webDriver.get("测试网址");
        webDriver.manage().window().maximize();
    }

    @Test
    public void testCaseLogin() throws InterruptedException {
        webDriver.findElement(By.xpath("xpath")).sendKeys("username");
        Thread.sleep(1000);
        webDriver.findElement(By.xpath("xpath")).sendKeys("password");
        Thread.sleep(1000);
        webDriver.findElement(By.className("login-btn")).click();
        Thread.sleep(3000);

        //显示等待应用
        WebDriverWait wait = new WebDriverWait(webDriver, 5);

        try {
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("layout-logo-sys")));
            Assert.assertTrue(true);
        } catch (Exception e) {
            Assert.fail();
        }
    }

    @AfterMethod
    public void teardownMethod() {
        webDriver.quit();
    }
}

4. PO设计

4.1 封装属性和行为

新建一个page包,编写一个LoginPage类,把元素属性和行为封装起来

package page;

import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.WebDriverUtils;

public class LoginPage {
    /*
    不需要一次性把所有属性都写完,可以一边用一边写
    属性:元素信息(定位方式+定位值)
    */
    By userNameBy = By.xpath("//*[@type='text']");
    By passWordBy = By.xpath("//*[@type='password']");
    By loginBtnBy = By.className("login-btn");

    //行为-->操作
    //输入用户名
    public void inputUserName(String userName) {
        WebDriverWait wait = new WebDriverWait(WebDriverUtils.webDriver, 5);
        wait.until(ExpectedConditions.visibilityOfElementLocated(userNameBy)).sendKeys(userName);
    }

    //输入密码
    public void inputPassWord(String passWord) {
        WebDriverWait wait = new WebDriverWait(WebDriverUtils.webDriver, 5);
        wait.until(ExpectedConditions.visibilityOfElementLocated(passWordBy)).sendKeys(passWord);
    }

    //点击登录按钮
    public void clickLoginBtn() {
        WebDriverWait wait = new WebDriverWait(WebDriverUtils.webDriver, 5);
        wait.until(ExpectedConditions.elementToBeClickable(loginBtnBy)).click();
    }

}

4.2 修改登录流程

把线性代码修改为PO写法

package testcase;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import page.LoginPage;
import utils.WebDriverUtils;

public class TestCaseLogin {
    public WebDriver webDriver;

    @BeforeMethod
    public void setupMethod() {
        //前置动作
        WebDriverUtils.openBrowser("chrome");
        webDriver = WebDriverUtils.webDriver;
        webDriver.get("测试地址");
        webDriver.manage().window().maximize();
    }

    @Test
    public void testCaseLoginSuccess() throws InterruptedException {
        //登录流程
        LoginPage loginPage = new LoginPage();
        loginPage.inputUserName("username");
        loginPage.inputPassWord("password");
        loginPage.clickLoginBtn();

        //显示等待应用
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        try {
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("layout-logo-sys")));
            Assert.assertTrue(true);
        } catch (Exception e) {
            Assert.fail();
        }
    }

    @AfterMethod
    public void teardownMethod() {
        //后置动作
        webDriver.quit();
    }
}

4.3 二次封装

在page包中新建一个BasePage类,把页面共性(元素等待、输入、点击)二次封装

package page;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.WebDriverUtils;

import java.time.Duration;

public class BasePage {

    //等待元素可见
    public WebElement waitElementVisible(By by){
        WebDriverWait wait = new WebDriverWait(WebDriverUtils.webDriver, Duration.ofSeconds(5));
        return wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }

    //等待元素可点击
    public WebElement waitElementClickable(By by){
        WebDriverWait wait = new WebDriverWait(WebDriverUtils.webDriver, Duration.ofSeconds(5));
        return wait.until(ExpectedConditions.elementToBeClickable(by));
    }

    //输入
    public void inputContent(By by,String content){
        waitElementVisible(by).sendKeys(content);
    }

    //点击
    public void click(By by){
        waitElementClickable(by);
    }
}

4.4 修改LoginPage类

简化代码(瞬间舒服了)

package page;

import org.openqa.selenium.By;

public class LoginPage extends BasePage {
    /*
    不需要一次性把所有属性都写完,可以一边用一边写
    属性:元素信息(定位方式+定位值)
    */
    By userNameBy = By.xpath("//*[@type='text']");
    By passWordBy = By.xpath("//*[@type='password']");
    By loginBtnBy = By.className("login-btn");

    //行为-->操作
    //输入用户名
    public void inputUserName(String userName) {
        input(userNameBy, userName);
    }

    //输入密码
    public void inputPassWord(String passWord) {
        input(passWordBy, passWord);
    }

    //点击登录按钮
    public void clickLoginBtn() {
        click(loginBtnBy);
    }

}

5. 数据分离

新建一个testdata包,专门保存测试数据相关的类

5.1 创建常量类

  1. 包里新建Constant类,用于保存类似测试地址之类的常量数据
package testdata;

public class Constant {
    //常量一般大写
    public static final String LOGIN_URL="测试地址";
}

  1. 替换TestCase类中的引用地址

    webDriver.get(Constant.LOGIN_URL);
    

5.2 注入参数

5.2.1 创建一个名称为testng.xml文件,填写配置信息

-------------------------------------------------------从这里开始,以后要在testng.xml文件这里运行程序了!!!-----------------------------------------------------------------

右键xml文件,运行程序

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
    <test name="Test">
        <!-- 统一配置浏览器类型 -->
        <parameter name="browserName" value="chrome"></parameter>
        <classes>
            <class name="testcase.TestCaseLogin"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->
5.2.2 前置方法注入浏览器名称参数
@Parameters("browserName")
@BeforeMethod
public void setupMethod(String browserName) {
    //前置动作
    WebDriverUtils.openBrowser(browserName);
    webDriver = WebDriverUtils.webDriver;
    webDriver.get(Constant.LOGIN_URL);
    webDriver.manage().window().maximize();
}
5.2.3 添加数据源

在testdata包中新建一个TestData类,编写登录成功的数据源

package testdata;

import org.testng.annotations.DataProvider;

public class LoginData {
    @DataProvider
    public static Object[][] loginDataSuccess(){
        Object[][] dataArray={{"username1","password1"},{"username2","password2"}};
        return dataArray;
    }
}
5.2.4 注入测试用例
@Test(dataProviderClass = LoginData.class,dataProvider = "loginDataSuccess")
public void testCaseLoginSuccess(String userName,String password) throws InterruptedException {
    //登录流程
    LoginPage loginPage = new LoginPage();
    loginPage.inputUserName(userName);
    loginPage.inputPassWord(password);
    loginPage.clickLoginBtn();
    //......省略其他代码

更改断言,测试一下是否能运行(这个时候我已经很久没运行了,不过好在问题不大,报错了马上就改掉了)

//显示等待应用
try {
    loginPage.waitElementVisible(By.className("layout-logo-sys"));
    Assert.assertTrue(true);
} catch (Exception e) {
    Assert.fail();
}

5.3 添加失败测试用例

5.3.1 添加元素

在LoginPage类中添加错误元素的属性和方法

//错误提示语元素属性
By errorNoticeBy = By.xpath("//*[@class='ivu-message-error']/span");

//获取错误提示信息
public String getErrorNotice(){
    return waitElementVisible(errorNoticeBy).getText();
}
5.3.2 添加数据

在LoginData类中添加登录失败错误数据

@DataProvider
public static Object[][] loginDataFail(){
    Object[][] dataArray={{"username1","password1","错误提示1"},{"username2","password2","错误提示2"}};
    return dataArray;
}
5.3.3 添加失败测试用例

在TestCaseLogin中添加失败测试用例

@Test(dataProviderClass = LoginData.class,dataProvider = "loginDataSuccess")
public void testCaseLoginFail(String userName,String passWord,String errorNotice){
    //登录流程
    LoginPage loginPage = new LoginPage();
    loginPage.inputUserName(userName);
    loginPage.inputPassWord(passWord);
    loginPage.clickLoginBtn();
    //断言
    String actualNotice=loginPage.getErrorNotice();
    Assert.assertEquals(errorNotice,actualNotice);

}

运行一下,解决一下报错

6. 日志集成

6.1 导入maven

<!--日志依赖-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

6.2 配置信息

在test目录下新建一个resource包,包下新建一个log4j.properties文件,写入以下内容

log4j.rootLogger = INFO,console,file

log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%p] %d{yyyy-MM-dd HH:mm:ss} method: %l----%m%n

log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
# 日志保存在项目log文件夹下的web_auto.log里,可自定义
log4j.appender.file.File = log/web_auto.log
log4j.appender.file.Append = true
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} method: %l - [ %p ]----%m%n

6.3 日志输出

1.在BasePage中添加日志输出

//实例化日志对象
private Logger logger = Logger.getLogger(BasePage.class);

//省略其他代码......

//输入
public void input(By by, String content){
    waitElementVisible(by).sendKeys(content);
    logger.info("给【"+by+"】元素输入【"+content+"】内容");
}

2.在WebDriverUtils中添加日志输出

package utils;

import org.apache.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebDriverUtils {
    public static WebDriver webDriver;
    //因为openBrowser是静态方法,所以日志对象也需要定义成静态的
    private static final Logger logger = Logger.getLogger(WebDriverUtils.class);

    public static void openBrowser(String browserName){
        if ("chrome".equals(browserName)){
            System.setProperty("webdriver.chrome.driver","D:\\Python\\chromedriver.exe");
            webDriver = new ChromeDriver();
            logger.info("打开【chrome】浏览器");
        }
    }
}

7. 集成Allure

7.1 导入依赖

<!-- allure依赖 -->
<dependency>
    <groupId>io.qameta.allure</groupId>
    <artifactId>allure-testng</artifactId>
    <version>2.17.2</version>
</dependency>

7.2 配置信息

在maven的properties中新增以下信息

<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<aspectj.version>1.9.2</aspectj.version>

在maven中写入以下信息

<build>
    <plugins>
        <plugin>
            <!-- maven-surefire-plugin 配合testng/junit执行测试用例的maven插件 -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.1</version>
            <configuration>
                <!-- 测试失败后,是否忽略并继续测试 -->
                <testFailureIgnore>true</testFailureIgnore>
                <suiteXmlFiles>
                    <!-- testng配置文件名称 -->
                    <suiteXmlFile>testng.xml</suiteXmlFile>
                </suiteXmlFiles>
                <!--设置参数命令行 -->
                <argLine>
                    <!-- UTF-8编码 -->
                    -Dfile.encoding=UTF-8
                    <!-- 配置拦截器 -->
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
                <systemProperties>
                    <property>
                        <!-- 配置 allure 结果存储路径 -->
                        <name>allure.results.directory</name>
                        <value>${project.build.directory}/allure-results</value>
                    </property>
                </systemProperties>
            </configuration>
            <dependencies>
                <!-- aspectjweaver maven坐标 -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

进入项目文件夹,运行黑窗口,输入以下命令

//需要每个脚本都执行完提示成功再接着执行下一个,第三个命令执行完后会自动打开浏览器,可以看到allure报表

mvn clean//如果运行成功是只有绿色和蓝色的
mvn test //如果运行成功是只有绿色和蓝色的
mvn io.qameta.allure:allure-maven:serve//运行成功自动打开浏览器,显示allure报告

8. 失败截图

8.1 导入依赖

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

8.2 编写截图方法

1.在WebDriverUtils中编写截图方法

//截图方法
public static void takeScreenShots(){
    //WebDriver extents RemoteWebDriver,而RemoteWebDriver implements TakesScreenshot
    TakesScreenshot screenshot = (TakesScreenshot) webDriver;
    //截图保存成file
    File srcFile = screenshot.getScreenshotAs(OutputType.FILE);
    File destFile = new File("D:screenShot/webAutoScreenShot/001.png");//截图保存位置
    try {
        FileUtils.copyFile(srcFile,destFile);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.在测试用例中调用截图方法,然后测试是否可用,没问题的话是可以在我们设置的路径下找到截图的

//截图
WebDriverUtils.takeScreenShots();

8.3 监听器

1.新建一个listener包,新建一个TestResultListener类,继承TestListenerAdapter类,重写onTestSuccess、onTestFailure这两个方法

@Override
public void onTestFailure(ITestResult tr) {
    super.onTestFailure(tr);
    String filePath = System.getProperty("user.dir") + "/target/screenShot/";
    String fileName = System.currentTimeMillis()+".png";
    WebDriverUtils.takeScreenShots();
}

2.修改WebDriverUtils包下的截图方法,加入参数,测试用例中的截图方法可以删掉了

//截图方法
public static void takeScreenShots(String filePath){
    //WebDriver extents RemoteWebDriver,而RemoteWebDriver implements TakesScreenshot
    TakesScreenshot screenshot = (TakesScreenshot) webDriver;
    //截图保存成file
    File srcFile = screenshot.getScreenshotAs(OutputType.FILE);
    File destFile = new File(filePath);
    //省略其他代码......

3.testng.xml文件中添加监听器配置

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
    <test name="Test">
        <!-- 统一配置浏览器类型 -->
        <parameter name="browserName" value="chrome"/>
        <classes>
            <class name="testcase.TestCaseLogin"/>
        </classes>
    </test> <!-- Test -->
    <listeners>
        <listener class-name="listener.TestResultListener"/>
    </listeners>
</suite> <!-- Suite -->

8.4 截图加入Allure报告

1.在WebDriverUtils类中新增一个截图方法,后面截图嵌入allure需要用到

//新建一个截图方法返回byte数组供allure报表使用
public static byte[] takeScreenShots(){
    TakesScreenshot screenshot = (TakesScreenshot) webDriver;
    //截图保存成BYTES
    byte[] arr= screenshot.getScreenshotAs(OutputType.BYTES);
    return arr;
}

在listener中添加一个AllureReportListener 实现了IHookable类,并编写一个嵌入allure报表的截图方法

package listener;

import io.qameta.allure.Attachment;
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import utils.WebDriverUtils;

public class AllureReportListener implements IHookable {
    @Override
    public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {
        //执行testng的test注解
        iHookCallBack.runTestMethod(iTestResult);
        //如果@test测试案例出现异常就截图
        if (iTestResult.getThrowable()!=null){
            //调用截图方法截图
            saveScreenShots();
        }
    }

    //编写截图方法 通过@Attachment附件功能,嵌入allure报表  可参考allure官网
    @Attachment(value = "Page screenshot",type = "image/png")
    public byte[] saveScreenShots(){
        return WebDriverUtils.takeScreenShots();
    }
}

在testng中加入allure监听器,不再重复了

每加一个监听器都要在testng中配置!

每加一个监听器都要在testng中配置!

每加一个监听器都要在testng中配置!

修改一下断言,使用例失败,测试一下功能,可以在allure报告的TestBody中成功看到截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3ARvpyP-1644916673901)(javaWeb学习总结.assets/image-20220122112429999.png)]

8.5 失败重试

1.utils包下新建一个TestRetry类,实现IRetryAnalyzer类,然后重写方法

package utils;

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class TestRetry implements IRetryAnalyzer {

    @Override
    public boolean retry(ITestResult iTestResult) {
        // testng框架自带,默认失败不会重试,把返回值改为true,则会重试
        return true;
    }
}

这样是有问题的,如果一直失败就会一直重试,这不是我们想要的,所以要加入一些逻辑

package utils;

import org.apache.log4j.Logger;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class TestRetry implements IRetryAnalyzer {

    private final Logger logger = Logger.getLogger(TestRetry.class);
    private int currentRetryCount = 1;

    @Override
    public boolean retry(ITestResult iTestResult) {

        if (currentRetryCount <=2) {
            
            logger.info("----------------------这是第【" + currentRetryCount + "】次重试!");
            currentRetryCount++;
            return true;
        }else {
            return false;
        }

    }
}

在测试用例的test注解中加入

retryAnalyzer = TestRetry.class

运行一下程序,看看已经配置的功能有没有生效,现在黑窗口运行会有日志输出,失败会截图,并且会重试,失败的截图和重试次数allure报告中都可以看到

8.6 设置全局监听

如果要我们一个一个的去给每一个测试用例加入重试,那太浪费时间了,设置全局监听就可以让所有的测试用例全部拥有重试功能

新建一个TestRetryListener类,实现IAnnotationTransformer 并重写他的方法(这里可能会有一个问题,如果以后遇到了自行解决吧)

package listener;

import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
import utils.TestRetry;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class TestRetryListener implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
        //给所有的@Test注解的测试用例加入重试
        annotation.setRetryAnalyzer(TestRetry.class);
    }
}

这个时候我们可以去掉测试用例注解中的重试了,然后运行一下看看有没有重试(Oh,Shit,我忘了加监听器了)

好的,加入监听器后,运行成功了,但是有一个新问题,我们的重试次数是累计的,我们需要每次运行测试用例后初始化他的值

在TestResultListener中加入重置次数的代码(注意!我们之前私有化的当前运行次数,所以需要先把他改成公共的)

package listener;

import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import utils.TestRetry;
import utils.WebDriverUtils;

public class TestResultListener extends TestListenerAdapter {
    @Override
    public void onTestSuccess(ITestResult tr) {
        super.onTestSuccess(tr);
        //重置重试次数
        TestRetry.currentRetryCount=1;
    }

    @Override
    public void onTestFailure(ITestResult tr) {
        super.onTestFailure(tr);
        String filePath = System.getProperty("user.dir") + "/target/screenShot/";
        String fileName = System.currentTimeMillis()+".png";
        WebDriverUtils.takeScreenShots(filePath+fileName);
        //重置重试次数
        TestRetry.currentRetryCount=1;
    }
}

好了,到这里就结束了,前辈最后一章说遗留了一个问题,不过我还没遇到,有兴趣的可以去看看https://blog.csdn.net/Keep_Learn2020/article/details/109209333

最后再次感谢前辈的分享!
入监听器后,运行成功了,但是有一个新问题,我们的重试次数是累计的,我们需要每次运行测试用例后初始化他的值

在TestResultListener中加入重置次数的代码(注意!我们之前私有化的当前运行次数,所以需要先把他改成公共的)

package listener;

import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import utils.TestRetry;
import utils.WebDriverUtils;

public class TestResultListener extends TestListenerAdapter {
    @Override
    public void onTestSuccess(ITestResult tr) {
        super.onTestSuccess(tr);
        //重置重试次数
        TestRetry.currentRetryCount=1;
    }

    @Override
    public void onTestFailure(ITestResult tr) {
        super.onTestFailure(tr);
        String filePath = System.getProperty("user.dir") + "/target/screenShot/";
        String fileName = System.currentTimeMillis()+".png";
        WebDriverUtils.takeScreenShots(filePath+fileName);
        //重置重试次数
        TestRetry.currentRetryCount=1;
    }
}

好了,到这里就结束了,前辈最后一章说遗留了一个问题,不过我还没遇到,有兴趣的可以去看看https://blog.csdn.net/Keep_Learn2020/article/details/109209333

最后再次感谢前辈的分享!

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值