Bootstrap

Maven+Junit5 + Allure +Jenkins 搭建 UI 自动化测试实战

效果展示

本 chat 介绍 UI 自动化测试框架的搭建: 运用 page factory 模式实现页面元素获取与业务操作分离;所用的测试框架为 junit5,并用其参数化测试用例;利用 maven profile 实现环境切换;利用 jenkins 实现持续集成并生成漂亮的 allure 报告。下面先给大家看下步骤。

  1. 在 jenkins 中点击【build with paremters】,选择环境

环境是自定义的,可以根据需要设定更多的环境(图没了,在网上搜的其他图,将就看看):
在这里插入图片描述在这里插入图片描述

  1. 选择 test,点击【build】,开始在测试环境运行测试用例(选择 Online 则在生产环境运行测试用例)

  2. 运行后查看 allure 测试报告

可以看到测试步骤及输入的参数,还可以看到页面截图,下面介绍下是怎么实现的。在这里插入图片描述

(抱歉,有些图没了,之前文章写在gitchat上,图片忘了备份)

Junit 5

Junit 5 介绍

JUnit 5 是 java 程序中应用最广泛的测试框架,很长一段时间以来,JUnit 一直在完美地完成它的工作,其间,JDK 8 带来了 java 中非常令人兴奋的特性,尤其是 lambda 表达式。JUnit5 的目标是适应 Java8 的编码风格和其他一些特性,这就是为什么需要 Java8 在 JUnit5 中创建和执行测试(尽管为了向后兼容,可以执行用 JUnit3 或 JUnit4 编写的测试)。

与 JUnit 4 相比,JUnit 5 由来自三个不同子项目的几个不同模块组成:

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Platform 定义了 test engine API,用于开发在平台上运行新测试框架,结构如下:

在这里插入图片描述

如何标记测试用例

Junit 5 标记测试用例用 @Test:

	@Test
    public void login() throws InterruptedException, IOException {
        common = PageFactory.initElements(threadDriver.get(), Common.class);
        common.login("aaa", "111111");
    }

引入:org.junit.jupiter.api.Test

  1. JUnit Jupiter:包含所有注解,有 TestEngine 实现来运行用这些注解编写的测试用例,结构如下:

img

  1. JUnit Vintage

用 JUnit 3 和 JUnit 4 写的测试用例可以在 JUnit 5 Platform 上运行。

Junit 5 与 Junit 4 对比

JDK

Junit 4 Junit 5
需要 Java 5 或以上版本 需要 Java 8 或以上版本

注解

说明 Junit 4 Junit 5
定义测试方法即用例 @Test @Test
在当前类中的所有测试方法之前执行 @BeforeClass @BeforeAll
在当前类中的所有测试方法之后执行 @AfterClass @AfterAll
在每个测试用例前执行 @Before @BeforeEach
在每个测试用例后执行 @After @AfterEach
禁用测试方法或类 @Ignore @Disabled
Tagging 和 filtering @Category @Tag

测试套件

Junit 4 用 @RunWith 和 @Suite 注解来实现测试套件:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
 
@RunWith(Suite.class)
@Suite.SuiteClasses({
        ExceptionTest.class, 
        TimeoutTest.class
})
public class JUnit4Example 
{
}

Junit 5 用 @RunWith、@SelectPackages 和 @SelectClasses 来实现测试套件,如下:

import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;
 
@RunWith(JUnitPlatform.class)
@SelectPackages("junit5.examples")
@SelectClasses({LoginTest.class, SearchTest.class, ResourcePathTest.class})
public class JUnit5Example 
{
}

注意:测试用例类必须以 Test 开头或结尾,否则按测试套件跑的时候会略过不跑该类里面的测试用例(识别不出来)。

断言

  • Junit 4:org.junit.Assert
  • Junit 5:org.junit.jupiter.Assertions

还有其他的一些差别,就不再一一列举。

PageFactory 模式编写自动化代码

最原始的模式大家都知道,就是打开页面 -> 查找元素 -> 操作 -> 等待加载完成 -> 验证,这样一步一步往下走,没有分层的概念。页面元素与逻辑代码混在一起,不利于维护和重用:

String url = "xxx";
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
ChromeOptions chromeOptions = new ChromeOptions();
driver = new ChromeDriver(chromeOptions);
driver.manage().window().maximize();
driver.get(url);

// 以下代码查找页面元素与业务操作混在了一起
driver.findElement(By.id("xx")).sendKeys("xx");
driver.findElement(By.id("xx")).click();

如何将元素定位与操作分离呢,利用 PageFactory,每个页面的元素定位封闭成一个类,操作封装成另一个类,页面元素类 LoginPage.java(只列出关键代码):

  package pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class LoginPage {
    /**********************************以下为登录页面元素***********************************/
    // 用户名输入框
    @FindBy(xpath="//form[@class='el-form ruleForm']/div[1]//input")
    public WebElement inputUserName;

    // 密码输入框
    @FindBy(xpath="//input[@type='password']")
    public WebElement inputUserPwd;

    // 验证码输入框
    @FindBy(xpath="//form[@class=\\'el-form ruleForm\\']/div[3]//input")
    public WebElement inputCode;

    // 登录按钮
    @FindBy(xpath = "//button[@class='el-button loginbtn el-button--primary']")
    public WebElement btnSubmit;

  	// 搜索框
   @FindBy(id="search")
   public  WebElement inputSearch;

}

  

操作(因为登录操作常用,所以我把它放在了 Common.java 中):

		// 引入相关类
		import org.openqa.selenium.support.PageFactory;

		// 关键代码如下:
        LoginPage loginPage = PageFactory.initElements(threadDriver.get(), LoginPage.class);

        // 进入到登录页面
        openUrl("login");
        // 等待某元素出现
        waitForElementExist(loginPage.inputUserName);
        loginPage.inputUserName.sendKeys(account);
        loginPage.inputUserPwd.sendKeys(pwd);

项目结构如下:

在这里插入图片描述

公共方法提取

在 UI 自动化测试过程中,有一些方法会反复用到,如启动浏览器、等待某元素出出、等待页面加载完成、打开链接等,这些方法可提取到一个公共

;