自动化测试实战-Growing_Notes

下面我们将对之前做过的一个项目进行自动化测试。项目链接:Growing_Notes


一、脑图编写 Web 自动化测试用例

自动化测试实战-Growing_Notes_第1张图片

 二、创建测试项目(Java)

  1. 创建Maven项目
  2. 在test包下管理自己的测试代码
  3. 导入自动化测试需要的相关依赖

pom.xml中 引入测试依赖:


    org.seleniumhq.selenium
    selenium-java
    4.0.0


    commons-io
    commons-io
    2.6


    org.junit.jupiter
    junit-jupiter
    5.8.2
    test


    org.junit.platform
    junit-platform-suite
    1.8.2
    test

三、根据脑图设计Growing_Notes自动化测试用例

1.准备工具类

在common包下创建 AutoTestUtils 类,该类需要提供一下功能:

  1. 创建驱动对象,提供给其他页面使用
  2. 创建隐式等待,作用于软件测试的整个生命周期
  3. 提供屏幕截图方法,以及保存截图的格式
package common;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

/**
 * @author SunYuHang
 * @date 2023-04-07 09:42
 * @ClassName : AutoTestUtils  //类名
 */

public class AutoTestUtils {
    public static EdgeDriver driver;

    // 创建驱动对象
    public static EdgeDriver getDriver() {
        if(driver == null) {
            driver = new EdgeDriver();
        }
        // 创建隐式等待,作用于driver的整个生命周期 (10秒)
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        return driver;
    }

    // 屏幕截图, 保存文件的格式
    public List getTime() {
        // 文件夹按照天数的维度进行保存
        // 文件格式 2023-4-3 20:07
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyy-MM-dd");
        String filename = sim1.format(System.currentTimeMillis());
        String dirname = sim2.format(System.currentTimeMillis());
        List list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }

    // 屏幕截图的方法
    public void getScreenShotAs(String str) throws IOException {
        List list = getTime();
        String filePath = "./src/test/java/com/blogWebAutoTest/"+list.get(0)+"/"+str+"_"+list.get(1)+".png";
        File srcFile = driver.getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(srcFile, new File(filePath));
    }
}

在 Tests 包下创建 DriverQuitTest 类,该类主要是用来释放驱动的。 

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.edge.EdgeDriver;

/**
 * @author SunYuHang
 * @date 2023-04-07 09:47
 * @ClassName : DriverQuitTest  //类名
 */

public class DriverQuitTest extends AutoTestUtils {
    public static EdgeDriver driver;
    @Test
    void driverQuit(){
        driver = getDriver();
        driver.quit();
    }
}

2.测试Growing_Notes注册页

创建 BlogRegTest 类,该类的测试用例主要有四个:

  • 注册页面是否能够正常打开
  • 输入用户名,密码,确认密码,且用户名第一次注册,密码和确认密码一致。【两次弹窗】
  • 输入用户名,密码,确认密码,且用户名第一次注册,密码和确认密码不一致。【一次弹窗】
  • 输入用户名,密码,确认密码,用户名不是第一次注册。【弹窗提示用户名已被使用】
  • 其他情况【用户名为空,密码为空,确认密码为空都是一次弹窗这里就不测了】

主类代码:

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:35
 * @ClassName : BlogRegTest  //类名
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogRegTest extends AutoTestUtils {
    public static EdgeDriver driver;
    @BeforeAll
    static void baseController(){
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/login.html");
    }
    /**
     * 检查注册成页面是否能够正常打开
     * 检查登陆页面的登录按钮,以及确认密码是否出现
     */
    @Test
    @Order(1)
    void regPageLoadRight() throws IOException {
        //点击注册按钮
        driver.findElement(By.cssSelector("#sign-up-btn")).click();
        //确认密码
        driver.findElement(By.cssSelector("#password2"));
        //登录按钮
        driver.findElement(By.cssSelector("#sign-in-btn"));
        //截图
        getScreenShotAs(getClass().getName());
    }
    /**
     * 检查正常注册情况
     * 两次弹窗
     */
    @ParameterizedTest
    @CsvSource({"孙宇航,123,123"})
    @Order(2)
    void regSuccess(String username,String password1,String password2) throws IOException,InterruptedException{
        //注册之前先清空用户名,密码和确认密码
        driver.findElement(By.cssSelector("#username1")).clear();
        driver.findElement(By.cssSelector("#password1")).clear();
        driver.findElement(By.cssSelector("#password2")).clear();
        //注册步骤
        driver.findElement(By.cssSelector("#username1")).sendKeys(username);
        driver.findElement(By.cssSelector("#password1")).sendKeys(password1);
        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
        driver.findElement(By.cssSelector("body > div.containers.sign-up-mode > div.forms-container > div > div.sign-up-form > input")).click();
        //检查注册结果,第一个弹窗显示注册成功,第二个弹窗显示是否要去登陆页面
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        //确认弹窗
        Thread.sleep(100);
        alert.dismiss();
        getScreenShotAs(getClass().getName());
    }
    /**
     * 检查注册失败情况 1
     * 账号已存在
     */
    @ParameterizedTest
    @CsvSource({"admin,admin,admin"})
    @Order(3)
    void regFail1(String username,String password1,String password2) throws IOException,InterruptedException{
        //注册之前先清空用户名,密码和确认密码
        driver.findElement(By.cssSelector("#username1")).clear();
        driver.findElement(By.cssSelector("#password1")).clear();
        driver.findElement(By.cssSelector("#password2")).clear();
        //注册步骤
        driver.findElement(By.cssSelector("#username1")).sendKeys(username);
        driver.findElement(By.cssSelector("#password1")).sendKeys(password1);
        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
        driver.findElement(By.cssSelector("body > div.containers.sign-up-mode > div.forms-container > div > div.sign-up-form > input")).click();
        //检查注册失败场景
        //切换弹窗,进行弹窗的处理 (隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }

    /**
     * 检查注册失败情况 2
     * 密码和确认密码不一致
     * @param username
     * @param password1
     * @param password2
     * @throws IOException
     * @throws InterruptedException
     */
    @ParameterizedTest
    @CsvSource({"孙宇航,123,456"})
    @Order(4)
    void regFail2(String username,String password1,String password2) throws IOException,InterruptedException{
        //注册之前先清空用户名,密码和确认密码
        driver.findElement(By.cssSelector("#username1")).clear();
        driver.findElement(By.cssSelector("#password1")).clear();
        driver.findElement(By.cssSelector("#password2")).clear();
        //注册步骤
        driver.findElement(By.cssSelector("#username1")).sendKeys(username);
        driver.findElement(By.cssSelector("#password1")).sendKeys(password1);
        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
        driver.findElement(By.cssSelector("body > div.containers.sign-up-mode > div.forms-container > div > div.sign-up-form > input")).click();

        //检查注册失败场景
        //切换弹窗,进行弹窗的处理 (隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }
}

3.测试Growing_Notes登录页

创建 BlogLoginTest 类,该类的测试用例主要有六个:

  • 登录页面是否能够正常打开
  • 用户名,密码都不输入,点击提交
  • 不输入用户名,输入密码,点击提交
  • 输入用户名,不输入密码,点击提交
  • 输入错误的用户名,密码,点击提交
  • 输入正确的用户名,密码,点击提交

主类代码:

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:35
 * @ClassName : BlogLoginTest  //登录测试用例
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogLoginTest extends AutoTestUtils {
    public static EdgeDriver driver;

    @BeforeAll
    static void baseController() {
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/login.html");
    }

    /**
     * 检查登录页面是否正常打开
     * 检查登录页的登录,用户名,密码字样是否出现
     */
    @Test
    @Order(1)
    void loginPageLoadRight() throws IOException {
        //登录按钮
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input"));
        //用户名
        driver.findElement(By.xpath("/html/body/div[2]/div[1]/div/div[1]/div[1]/input"));
        //密码
        driver.findElement(By.xpath("/html/body/div[2]/div[1]/div/div[1]/div[2]/input"));
        //截图
        getScreenShotAs(getClass().getName());
    }

    /**
     * 检查异常登录的情况 4 种情况
     * 账号密码错误,会有弹窗提示
     * 4.未输入用户名和密码
     */
    @ParameterizedTest
    @CsvSource({"admin"})
    @Order(2)
    void loginFail1() throws IOException, InterruptedException {
        //登录之前先清空用户名和密码
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //登录步骤
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input")).click();
        //检查登录失败的场景
        // 切换到弹窗,进行弹窗处理(隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }

    /**
     * 检查异常登录的情况 4 种情况
     * 账号密码错误,会有弹窗提示
     * 3.未输入用户名
     */
    @ParameterizedTest
    @CsvSource({"admin"})
    @Order(3)
    void loginFail2(String password) throws IOException, InterruptedException {
        //登录之前先清空用户名和密码
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //登录步骤
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input")).click();
        //检查登录失败的场景
        // 切换到弹窗,进行弹窗处理(隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }

    /**
     * 检查异常登录的情况 4 种情况
     * 账号密码错误,会有弹窗提示
     * 2.未输入密码
     */
    @ParameterizedTest
    @CsvSource({"admin"})
    @Order(4)
    void loginFail3(String username) throws IOException, InterruptedException {
        //登录之前先清空用户名和密码
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //登录步骤
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input")).click();
        //检查登录失败的场景
        // 切换到弹窗,进行弹窗处理(隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }

    /**
     * 检查异常登录的情况 4 种情况
     * 账号密码错误,会有弹窗提示
     * 1.账号密码错误
     */
    @ParameterizedTest
    @CsvSource({"admin456,123", "孙宇航123,456"})
    @Order(5)
    void loginFail4(String username, String password) throws IOException, InterruptedException {
        //登录之前先清空用户名和密码
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //登录步骤
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input")).click();
        //检查登录失败的场景
        // 切换到弹窗,进行弹窗处理(隐式等待不生效,不得不加入强制等待)
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());
    }


    /**
     * 检查正常登录情况
     * 页面是否显示用户名,密码,登录字样
     */
    @ParameterizedTest
    @CsvSource({"admin,admin", "孙宇航,123"})
    @Order(6)
    void loginSuccess(String username, String password) throws IOException {
        //登录之前先清空用户名和密码
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //登录步骤
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("body > div.containers > div.forms-container > div > div.sign-in-form > input")).click();
        //检查登录结果(检查我的列表页的查看详情按钮)
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.mydetail > a:nth-child(1) > b"));
        getScreenShotAs(getClass().getName());
        //一个用户测试完了,需要进行回退
        driver.navigate().back();
    }

}

4.测试个人博客列表页

创建 MyBlogListTest 类,该类的测试用例主要有一个:

  • 我的博客列表页能否可以正常显示

主类代码:

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:36
 * @ClassName : MyBlogListTest  //类名
 */

public class MyBlogListTest extends AutoTestUtils {
    public static EdgeDriver driver;
    //创建驱动对象
    @BeforeAll
    static void baseController(){
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/myblog_list.html");
    }
    /**
     * 个人博客列表页可以正常显示
     */
    @Test
    void MyListPageLoadRight() throws IOException{
        //查看是否有修改、删除按钮

        driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.mydetail > a:nth-child(2) > b"));
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.mydetail > a:nth-child(3)"));
        getScreenShotAs(getClass().getName());

    }
}

5.测试博客列表主页

创建 EveryBlogListTest 类,该类的测试用例只有一个:

  • 博客列表主页能否正常显示

主类代码:

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:36
 * @ClassName : EveryBlogTest  //类名
 */

public class EveryBlogListTest extends AutoTestUtils {
    public static EdgeDriver driver;

    @BeforeAll
    static void baseController() {
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/blog_list.html");
    }

    /**
     * 大家的列表页能否正常显示
     * @throws IOException
     */
    @Test
    void everyListPageLoadRight() throws IOException {
        //个人中心
        driver.findElement(By.cssSelector("body > div.nav > a"));
        //查看详情
        driver.findElement(By.cssSelector("#listDiv > div:nth-child(1) > a"));
        getScreenShotAs(getClass().getName());
    }
}

6.测试博客编辑页

创建 BlogEditTest 类,该类有两个测试用例:

  • 检查编辑页是否可以正常打开
  • 测试填写博客标题和正文,是否可以正常发布博客

主类代码:

package Tests;
import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;
/**
 * @author SunYuHang
 * @date 2023-04-07 10:36
 * @ClassName : BlogEditTest  //类名
 */

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogEditTest extends AutoTestUtils {
    public static EdgeDriver driver;

    @BeforeAll
    static void baseController() {
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/blog_edit.html");
    }
    /**
     * 检查博客编辑页可以正常打开
     */
    @Test
    @Order(1)
    void editPageLoadRight() throws IOException {
        // 检查正文中 "在这里写下一篇博客"
        driver.findElement(By.cssSelector("#editorDiv > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));
        // 检查编辑器上的 H5 标题
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(17) > a > i"));
        getScreenShotAs(getClass().getName());
    }

    /**
     * 测试填写博客标题, 博客正文, 是否能够正常发布博客
     * @throws InterruptedException
     * @throws IOException
     */
    @Test
    @Order(2)
    void editAndSubmitBlog() throws InterruptedException, IOException {
        String expect = "孙宇航 vs Java";
        driver.findElement(By.cssSelector("#title")).sendKeys(expect);
        // 因博客系统使用到的编辑器是第三方插件, 所以不能直接使用 sendKeys 向编辑器发送文本,使用下划线,斜线代替
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(6) > a > i")).click();
        driver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
        // 获取我的列表页第一条博客的标题文本, 检查是否符合预期
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        alert.accept();
        getScreenShotAs(getClass().getName());
        String actual = driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.title")).getText();
        Assertions.assertEquals(expect,actual);
    }
}

7.测试博客详情页

创建 BlogDetailTest 类,该类的测试用例只有一个:

  • 测试博客详情页显示是否符合预期

主类代码:

package Tests;

import common.AutoTestUtils;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:37
 * @ClassName : BlogDetailTest  //类名
 */

public class BlogDetailTest extends AutoTestUtils {
    public static EdgeDriver driver;

    @BeforeAll
    static void baseController() {
        driver = getDriver();
        driver.get("http://43.140.252.242:9090/blog_content.html?id=3");
    }
    /**
     * 测试博客详情页显示是否符合预期
     * @throws IOException
     */
    @Test
    void detailPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("#title"));
        driver.findElement(By.cssSelector("#date"));
        getScreenShotAs(getClass().getName());
    }
}

8.创建测试套件

创建 RunSuite 类,该类式用来指定那些测试类需要运行,以及运行顺序的。

package Tests;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

/**
 * @author SunYuHang
 * @date 2023-04-07 10:37
 * @ClassName : RunSuite  //测试套件
 */
@Suite
@SelectClasses({BlogRegTest.class,BlogLoginTest.class,MyBlogListTest.class,EveryBlogListTest.class,
        BlogEditTest.class,BlogDetailTest.class,DriverQuitTest.class})
public class RunSuite {
}

你可能感兴趣的:(单元测试)