学生信息管理系统自动化测试

项目地址:

http://82.156.151.156:8080/login.html

一、系统测试用例
在这里插入图片描述

二、测试实现过程

先是根据自己的项目设计了一个 UI 自动化测试用例, 然后根据这个测试用例使用了 selenium4自动化测试工具和 JUnit5单元测试框架结合实现的 web 自动化测试.。
测试模块划分为三个,有三个包, 一个包下的类是工具类, 主要是用来创建驱动对象的, 避免在自动化测试的时候, 每次都要创建驱动对象. 另一个 包是放测试用例的, 一个页面一个测试类, 最后一个包是个测试套件,通过测试套件把测试类全部都加进去。

三、测试亮点

(1) 使用了 JUnit中提供的注解, 避免生成过多的对象, 造成资源和时间的浪费, 提高了自动化的执行效率;
(2)只创建了一次驱动对象, 避免每个用例重复创建驱动对象造成时间和资源的浪费;
(3)用例使用了参数化注解,保持用例的简洁, 提高代码的可读性;
(4)使用了测试套件, 降低了测试人员的工作量, 通过套件既可以指定哪些测试类需要运行, 也可以一次执行所有要运行的测试用例;
(5) 使用了屏幕截图, 方便问题的追溯以及问题的解决;
(6) 使用了等待, 如当页面发生跳转的时候, 或者页面还没来得及渲染的时候, 获取页面元素, 就会出现元素找不到的异常, 而这可能不是一个 bug, 所以需要加上隐式等待,提高了自动化的稳定性。

四、测试前准备工作

1.写好测试用例;
2.准备好测试数据;
3.创建测试环境:

(1)1. 创建一个 Maven 项目;
(2)导入自动化测试需要的相关依赖;

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version> <!-- 替换为你需要的版本号 -->
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>25.0-jre</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>

(3)创建包,管理自己后续要写的代码。

四、写自动化测试代码

在这里插入图片描述

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

public class AutoTestUtils {
    public static EdgeDriver driver;

    // 创建驱动对象
    public static EdgeDriver getDriver() {
        System.setProperty("webdriver.edge.driver", "msedgedriver.exe");
        if(driver == null) {
            driver = new EdgeDriver();
        }
        // 创建隐式等待,作用于driver的整个生命周期 (10秒)
        //Duration.ofSeconds(10) 创建了一个持续时间对象,表示等待时间为10秒。然后,通过调用 toMillis() 方法,将持续时间转换为毫秒数。
        // 最后,使用 TimeUnit.MILLISECONDS 将毫秒作为单位传递给 implicitlyWait() 方法。
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10).toMillis(), TimeUnit.MILLISECONDS);
        return driver;
    }


    // 屏幕截图, 保存文件的格式
    //获取当前时间,并将其格式化为指定的文件名和文件夹名
    public List<String> 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<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }

    // 屏幕截图的方法
    public void getScreenShotAs(String str) throws IOException {
        // 调用 getTime() 方法获取当前日期和时间的列表
        List<String> list = getTime();
        // 构建截图文件的路径
        String filePath = "./src/test/java/com/example/student_manage_test/"+list.get(0)+"/"+str+"_"+list.get(1)+".png";
        // 获取页面截图并保存为文件
        //OutputType.FILE 是一个枚举类型,表示捕获页面截图的输出类型为文件。
        File srcFile = driver.getScreenshotAs(OutputType.FILE);
        //从源文件复制到指定路径下
        FileUtils.copyFile(srcFile, new File(filePath));
    }

}

(5)释放驱动

@SpringBootTest
public class DriverQuitTest extends AutoTestUtils {
    public static EdgeDriver driver;
    //停止 WebDriver 的操作并释放相关资源
    @Test
    public void driverQuit() {
        driver = getDriver();
        driver.quit();
    }
}

2.测试登录界面

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

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

    /**
     * 检查登录页面是否正常打开
     * 检查登录页的登录,用户名,密码等字样是否出现
     */
    @Test
    @Order(1)
    //标记方法在测试执行时的顺序
    public void loginPageLoadRight() throws IOException {
        // 查找登录页面标题元素的 CSS 选择器
        driver.findElement(By.id("loginname"));

        // 查找登录页面的第一个提示信息元素的 XPath
        driver.findElement(By.id("password"));

        // 查找登录页面的第二个提示信息元素的 XPath
        driver.findElement(By.cssSelector("#submit"));

        // 对当前页面进行截图
        getScreenShotAs(getClass().getName());
    }


    /**
     * 检查异常登录的情况 4 种情况
     * (1)账号密码错误
     * 账号密码错误, 会弹窗提示
     */
    @ParameterizedTest
    @CsvSource({"admin,345", "zhangsan,111", "lucy,111"})
    @Order(2)
    public void loginFail(String loginname, String password) throws InterruptedException, IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 登录步骤
        driver.findElement(By.id("loginname")).sendKeys(loginname);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        // 检测登录失败的场景
        // 切换到弹窗, 进行弹窗的处理(隐式等待不生效,不得不加入强制等待)
        //等待时间
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("用户名或密码错误,请重试!"));
        driver.switchTo().alert().accept();
        //截图
        getScreenShotAs(getClass().getName());

    }

    /**
     * (2)未输入密码
     *
     * @param loginname 登录名
     * @throws InterruptedException
     */
    @ParameterizedTest
    @ValueSource(strings = {"张三"})
    @Order(3)
    public void loginFail2(String loginname) throws InterruptedException, IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 登录步骤
        driver.findElement(By.id("loginname")).sendKeys(loginname);
        driver.findElement(By.cssSelector("#submit")).click();
        // 检测登录失败的场景
        // 切换到弹窗, 进行弹窗的处理
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("请先输入密码!"));
        alert.accept();
        getScreenShotAs(getClass().getName());

    }

    /**
     * 未输入用户名
     *
     * @param password 密码
     * @throws InterruptedException
     */
    @ParameterizedTest
    @ValueSource(strings = {"111"})
    @Order(4)
    public void loginFail3(String password) throws InterruptedException, IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 登录步骤
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        // 检测登录失败的场景
        // 切换到弹窗, 进行弹窗的处理
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("请先输入用户名!"));
        alert.accept();
        getScreenShotAs(getClass().getName());

    }

    /**
     * 账号,, 密码都没有输入
     *
     * @throws InterruptedException
     */
    @Test
    @Order(5)
    public void loginFail4() throws InterruptedException, IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        driver.findElement(By.cssSelector("#submit")).click();
        // 检测登录失败的场景
        // 切换到弹窗, 进行弹窗的处理
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("请先输入用户名!"));
        // 警告弹窗
        alert.accept();
        getScreenShotAs(getClass().getName());


    }

    /**
     * 检查正常登录的情况
     * 页面是否显示登录名, 密码, 提交字样
     */
    //@ParameterizedTest指示一个测试方法是参数化测试方法,CsvSource指定参数化测试方法的参数来源为 CSV 格式的数据源。
    @ParameterizedTest
    @CsvSource({"admin,admin"})
    @Order(6)
    public void loginSuccess(String logianname, String password) throws IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 登录步骤
        driver.findElement(By.id("loginname")).sendKeys(logianname);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        //等待时间
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("登录成功"));
        driver.switchTo().alert().accept();
        getScreenShotAs(getClass().getName());
        // 一个用户测试完了,需要进行回退
        driver.navigate().back();
    }
}

3.测试学生列表界面

@SpringBootTest
public class ListTest extends AutoTestUtils {
    public static EdgeDriver driver;

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

    /**
     * 登录后学生列表列表页可以正常显示
     */
    @Test
    public void MyListPageLoadRight() throws IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr[1]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        getScreenShotAs(getClass().getName());
        driver.navigate().back();
    }

}

4.测试查询功能

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class SelectTest extends AutoTestUtils {
    @BeforeAll
    public static void baseController() {
        driver = getDriver();
        driver.get("http://82.156.151.156:8080/login.html");
    }

    /**
     * 查询学生通过姓名
     */
    @Test
    @Order(1)
    public void selectByStuname() throws IOException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        //传入参数
        driver.findElement(By.id("ipt_name")).sendKeys("超级管理员");
        driver.findElement(By.id("submit1")).click();
        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr/th[3]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        //截图
        getScreenShotAs(getClass().getName());
    }

    /**
     * 查询学生通过籍贯
     */
    @Test
    @Order(2)
    public void selectByAddress() throws IOException {

        driver.findElement(By.id("ipt_name")).clear();
        driver.findElement(By.id("ipt_address")).clear();
        driver.findElement(By.id("ipt_stunum")).clear();
        //传入参数
        driver.findElement(By.id("ipt_address")).sendKeys("北京");
        driver.findElement(By.id("submit1")).click();
        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr[1]/th[6]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        //截图
        getScreenShotAs(getClass().getName());
    }

    /**
     * 查询学生通过学号
     */
    @Test
    @Order(3)
    public void selectByStunum() throws IOException {
        driver.findElement(By.id("ipt_name")).clear();
        driver.findElement(By.id("ipt_address")).clear();
        driver.findElement(By.id("ipt_stunum")).clear();

        //传入参数
        driver.findElement(By.id("ipt_stunum")).sendKeys("2002");
        driver.findElement(By.id("submit1")).click();
        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr/th[8]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        //截图
        getScreenShotAs(getClass().getName());
    }

    /**
     * 查询学生通过姓名和籍贯
     */
    @Test
    @Order(4)
    public void selectByStuname_Address() throws IOException {
        driver.findElement(By.id("ipt_name")).clear();
        driver.findElement(By.id("ipt_address")).clear();
        driver.findElement(By.id("ipt_stunum")).clear();

        //传入参数
        driver.findElement(By.id("ipt_name")).sendKeys("超级管理员");
        driver.findElement(By.id("ipt_address")).sendKeys("成都");
        driver.findElement(By.id("submit1")).click();
        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr/th[3]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        //截图
        getScreenShotAs(getClass().getName());
    }

    /**
     * 查询学生通过姓名、籍贯和学号
     */
    @Test
    @Order(5)
    public void selectByStuname_Address_Stunum() throws IOException {
        driver.findElement(By.id("ipt_name")).clear();
        driver.findElement(By.id("ipt_address")).clear();
        driver.findElement(By.id("ipt_stunum")).clear();

        //传入参数
        driver.findElement(By.id("ipt_name")).sendKeys("超级管理员");
        driver.findElement(By.id("ipt_address")).sendKeys("成都");
        driver.findElement(By.id("ipt_stunum")).sendKeys("10000");
        driver.findElement(By.id("submit1")).click();
        // 使用适当的定位器(By)查询目标元素
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"info\"]/tr[1]/th[3]"));
        // 验证查询结果是否为空
        assertTrue(elements.size() > 0);
        //截图
        getScreenShotAs(getClass().getName());
        driver.navigate().back();
    }

}

5.测试添加功能

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class AddTest extends AutoTestUtils {

    @BeforeAll
    public static void baseSetup() {
        driver = getDriver();
        driver.get("http://82.156.151.156:8080/login.html");
    }

    /**
     * 添加用户成功测试
     * @throws IOException
     */

    @Order(1)
    @ParameterizedTest
    @CsvSource({"李四,李四,111,111,20,1873234890819,2007"})
    public void addStudentSuccess(String loginname, String stuname, String password, String password2, int age,String phone,String stunum) throws IOException, InterruptedException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        // 点击添加用户按钮
        driver.findElement(By.id("add_student")).click();

        driver.findElement(By.id("loginname")).sendKeys(loginname);
        driver.findElement(By.id("stuname")).sendKeys(stuname);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.id("password2")).sendKeys(password2);
        driver.findElement(By.id("age")).sendKeys(String.valueOf(age));
        driver.findElement(By.id("phone")).sendKeys(phone);
        driver.findElement(By.id("stunum")).sendKeys(stunum);

        driver.findElement(By.id("btn_sub")).click();

        wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("添加成功"));
        driver.switchTo().alert().accept();


        driver.switchTo().alert().dismiss();

        getScreenShotAs(getClass().getName());

    }

    /**
     * 添加用户失败测试-登录名重复
     * @throws IOException
     */

    @Order(2)
    @ParameterizedTest
    @CsvSource({"超级管理员,张三,111,111,20,2011"})
    public void addStudentFail1(String loginname, String stuname, String password, String password2, int age, String stunum) throws IOException, InterruptedException {

        // 点击添加用户按钮
        driver.findElement(By.id("add_student")).click();

        // 检查添加页面是否打开
        driver.findElement(By.id("loginname")).sendKeys(loginname);
        driver.findElement(By.id("stuname")).sendKeys(stuname);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.id("password2")).sendKeys(password2);
        driver.findElement(By.id("age")).sendKeys(String.valueOf(age));
        driver.findElement(By.id("stunum")).sendKeys(stuname);

        driver.findElement(By.id("btn_sub")).click();

        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("添加失败,请重试"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());
        
    }

    /**
     * 添加用户失败测试-学号重复
     * @throws IOException
     */

    @Order(3)
    @ParameterizedTest
    @CsvSource({"小黑,小黑,111,111,20,10000"})
    public void addStudentFail2(String loginname, String stuname, String password, String password2, int age, String stunum) throws IOException, InterruptedException {
        
        // 点击添加用户按钮
        driver.findElement(By.id("add_student")).click();

        // 检查添加页面是否打开
        driver.findElement(By.id("loginname")).sendKeys(loginname);
        driver.findElement(By.id("stuname")).sendKeys(stuname);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.id("password2")).sendKeys(password2);
        driver.findElement(By.id("age")).sendKeys(String.valueOf(age));
        driver.findElement(By.id("stunum")).sendKeys(stunum);

        driver.findElement(By.id("btn_sub")).click();

        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("添加失败,请重试"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());
        driver.navigate().back();
        driver.navigate().back();

    }
}

6.测试修改功能

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UpdateTest extends AutoTestUtils {
    @BeforeAll
    public static void baseSetup() {
        driver = getDriver();
        driver.get("http://82.156.151.156:8080/login.html");
    }

    /**
     * 更新用户成功测试--1.修改姓名
     * @throws IOException
     */
    @Order(1)
    @ParameterizedTest
    @CsvSource({"小红"})
    public void UpdateStudentSuccess1(String stuname ) throws IOException, InterruptedException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        // 找到要修改的行
        WebElement row = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[3]"));
        // 找到修改按钮元素
        WebElement deleteButton = row.findElement(By.xpath("//*[@id=\"info\"]/tr[3]/th[10]/a[1]"));
        // 点击修改按钮
        deleteButton.click();

        driver.findElement(By.id("stuname")).clear();
        driver.findElement(By.id("stuname")).sendKeys(stuname);

        driver.findElement(By.id("btn_sub")).click();

         wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("修改成功"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());

    }

    /**
     * 更新用户成功测试--2.修改密码
     * @throws IOException
     */
    @Order(2)
    @ParameterizedTest
    @CsvSource({"111,111"})
    public void UpdateStudentSuccess2(String password,String password2 ) throws IOException, InterruptedException {

        // 找到要修改的行
        WebElement row = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[3]"));
        // 找到修改按钮元素
        WebElement deleteButton = row.findElement(By.xpath("//*[@id=\"info\"]/tr[3]/th[10]/a[1]"));
        // 点击修改按钮
        deleteButton.click();

        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.id("password2")).sendKeys(password2);

        driver.findElement(By.id("btn_sub")).click();

        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("修改成功"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());

    }



    /**
     * 更新用户失败测试--1.未输姓名
     * @throws IOException
     */
    @Test
    @Order(3)
    public void UpdateStudentFail() throws IOException, InterruptedException {

        // 找到要修改的行
        WebElement row = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[3]"));
        // 找到修改按钮元素
        WebElement deleteButton = row.findElement(By.xpath("//*[@id=\"info\"]/tr[3]/th[10]/a[1]"));
        // 点击修改按钮
        deleteButton.click();

        driver.findElement(By.id("stuname")).clear();

        driver.findElement(By.id("btn_sub")).click();

        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        assertTrue(alertText.contains("请先输入"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());

    }

    //更新用户失败测试--2.登录名和学号是唯一的,在写代码时这两个值不能改,所以不用测试

}

7.测试删除功能
(1)删除单条

@SpringBootTest
public class DeleteOneTest extends AutoTestUtils {
    @BeforeAll
    public static void baseSetup() {
        driver = getDriver();
        driver.get("http://82.156.151.156:8080/login.html");
    }

    /**
     * 删除单个用户测试
     * @throws IOException
     */
    @Test
    public void deleteStudentOne() throws IOException, InterruptedException {
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        // 随便找一行删除
        // 找到要删除的行
        WebElement row = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[3]"));
        // 找到删除按钮元素
        WebElement deleteButton = row.findElement(By.xpath("//*[@id=\"info\"]/tr[3]/th[10]/a[2]"));
        // 点击删除按钮
        deleteButton.click();

        //处理确认删除的弹框
        wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        //处理删除成功的弹窗
        wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("删除成功!"));
        driver.switchTo().alert().accept();

        getScreenShotAs(getClass().getName());

    }
}

(2)删除选中

public class DeleteMoreTest extends AutoTestUtils {
    @BeforeAll
    public static void baseSetup() {
        driver = getDriver();
        driver.get("http://82.156.151.156:8080/login.html");
    }

    @Test
    public void deleteMoreStudent(){
        // 登录之前先清空用户名和密码
        driver.findElement(By.id("loginname")).clear();
        driver.findElement(By.id("password")).clear();
        // 先登录
        driver.findElement(By.id("loginname")).sendKeys("admin");
        driver.findElement(By.id("password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#submit")).click();

        // 接收弹窗
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        // 找到要删除的行
        WebElement row1 = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[2]"));
        // 找到这行选中框
        WebElement deleteButton1= row1.findElement(By.xpath("//*[@id=\"info\"]/tr[2]/th[1]"));
        // 点击删除按钮
        deleteButton1.click();

        // 找到要删除的行
        WebElement row2 = driver.findElement(By.xpath("//*[@id=\"info\"]/tr[3]"));
        // 找到这行选中框
        WebElement deleteButton2 = row2.findElement(By.xpath("//*[@id=\"info\"]/tr[3]/th[1]"));
        // 点击删除按钮
        deleteButton2.click();

        driver.findElement(By.xpath("//*[@id=\"delete\"]")).click(); // 点击批量删除按钮

        //处理确认删除的弹框
        wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        driver.switchTo().alert().accept();

        //处理删除成功的弹窗
        wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        // 获取提示框的文本
        String alertText = driver.switchTo().alert().getText();
        // 验证文本是否包含了"添加成功"
        assertTrue(alertText.contains("选中删除成功!"));
        driver.switchTo().alert().accept();
    }
}

8.测试套件

//测试登录、列表页、查询功能、添加功能、修改功能、删除单条和删除选中功能
@Suite
@SelectClasses({LoginTest.class, ListTest.class, SelectTest.class, AddTest.class, UpdateTest.class,
        DeleteOneTest.class, DeleteMoreTest.class,DriverQuitTest.class })
public class RunSuite1 {
}

五、测试结果

(1)测试通过率
在这里插入图片描述
在这里插入图片描述
(2)测试截图
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/58460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频爬虫:解析m3u8文件 python m3u8库,m3u8文件中.ts视频流的解密下载

一、引用的库 这里需要引用的库是&#xff1a;from Crypto.Cipher import AES 有坑哈&#xff0c;python3.0之后直接安装crypto你会发现不管怎么着都会报错。 经过查找资料找到了原因&#xff0c;原来是20年之后crypto已经被pycryptohome替换掉啦&#xff0c; 如果之前安装过…

Spring Cloud实战案例 │ Apollo和Zuul的整合开发

Apollo是携程研发的开源配置管理中心&#xff0c;能够集中管理应用于不同环境、不同集群的配置&#xff0c;配置修改后能够实时推送到应用端&#xff0c;并且具备规范的权限、流程治理等特性。 本案例结合一个案例介绍Apollo和Zuul的整合开发。整个应用分为4个微服务项目&…

Nacos 下载安装教程

文章目录 事先准备下载并启动 Nacos设置 Nacos 开机自启动开放 Linux 外部访问权限访问 Nacos 管理界面附录 笔者的运行环境&#xff1a; 安装成功过的 Nacos&#xff1a; Nacos 2.2.3 安装成功过的 Java&#xff1a; Java 17.0.7 安装成功过的 Linux&#xff1a; RedHat Ent…

Windows 安装Tensorflow2.1、Pycharm开发环境

文章目录 1、安装anaconda2、安装Tensoflow2.1、创建虚拟环境2.2、安装Tensorflow依赖2.3、验证Tensorflow是否成功 3、配置pycharm环境4、错误记录 1、安装anaconda https://www.anaconda.com/download 打开命令行工具&#xff0c;出现base就表示安装成功了&#xff0c;表示当…

Vue2 第十一节 Vue的生命周期

1.生命周期的概念 2.生命周期流程图 3.生命周期分析 一.生命周期概念 生命周期又称为生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根…

如祺出行冲刺自动驾驶商业化,人少的地方机会多?

网约车&#xff0c;正在迎来让人“不明觉厉”的新一轮竞赛。 网约车监管信息交互系统的数据显示&#xff0c;截至今年6月30日&#xff0c;全国共有318家网约车平台公司取得网约车平台经营许可&#xff0c;环比增加5家&#xff1b;网约车监管信息交互系统6月份共收到订单信息7.…

【数据结构】二叉树、二叉搜索树、平衡二叉树、红黑树、B树、B+树

概述 二叉树&#xff08;Binary Tree&#xff09;&#xff1a;每个节点最多有两个子节点&#xff08;左子节点和右子节点&#xff09;&#xff0c;没有限制节点的顺序。特点是简单直观&#xff0c;易于实现&#xff0c;但查找效率较低。 二叉搜索树&#xff08;Binary Search…

【网络基础进阶之路】设计网络划分的实战详解

PS&#xff1a;本要求基于华为的eNSP模拟软件进行 具体要求&#xff1a; 完成步骤&#xff1a; 1、对192.168.1.0/24进行子网划分 2、对每一个路由器进行IP的配置 3、开始静态路由的书写&#xff0c;在写之前&#xff0c;我们可以先对每一个路由器写一条通向右边的缺省路由&…

父类B为抽象类,继承接口A,子类C必须实现B和A中的抽象方法

1. 子类C必须实现A中的抽象方法。 2. 子类C必须实现B中的抽象方法 3 在1中&#xff0c;我们知道&#xff0c;C不显示实现A&#xff0c;依旧要实现A的所有方法。 然而代码设计中&#xff0c;C可能会依旧显示实现A&#xff0c;然后实现A的所有方法。&#xff08;这样做的好处还…

本科专科毕业论文如何选题-附1000多论文题目-论文选题--【毕业论文】

文章目录 本系列校训毕设的技术铺垫论文选题选题目的和意义&#xff1a;选题举例参考文献 配套资源 本系列校训 互相伤害互相卷&#xff0c;玩命学习要你管&#xff0c;天生我才必有用&#xff0c;我命由我不由天&#xff01; 毕业论文不怕难&#xff0c;毕业设计来铺垫&#…

【LeetCode】对称二叉树 平衡二叉树

对称二叉树 即先判断根节点的左右子树相不相同&#xff0c;相同时&#xff0c;再判断左孩子的左子树和右孩子的右子树比较&#xff0c;左孩子的右子树和右孩子的左子树&#xff08;当两个都相同时才是对称的&#xff09;.....依次递推&#xff0c;过程中并设置一些不满足相同的…

Java生成二维码

使用google的开发工具包ZXing生成二维码 一、导入jar包 <!-- zxing生成二维码 --> <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version> </dependency><depen…

FFmpeg常见命令行(一):FFmpeg工具使用基础

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》。本文是Android音视频任务列表的其中一个&#xff0c; 对应的要学习的内容是&#xff1a;FFmpe…

【分布式系统】聊聊系统监控

对于分布式系统来说&#xff0c;出现故障的是常有的事情&#xff0c;如何在短时间内找到故障的原因&#xff0c;排除故障是非常重要的&#xff0c;而监控系统是就像系统的眼睛可以通过分析相关数据&#xff0c;进一步管理和运维整个分布式系统。 监控系统的的基本功能包含 全…

C++初阶函数重载

目录 函数重载函数名修饰规则 函数重载 C语言不允许同名函数 CPP可以&#xff0c;但是要求构成函数重载 函数名相同&#xff0c;参数不同(参数类型、参数个数、参数类型的顺序)&#xff0c;返回值不同不能构成重载 int Add(int left, int right) {cout << "int Ad…

【机器学习】Gradient Descent for Logistic Regression

Gradient Descent for Logistic Regression 1. 数据集&#xff08;多变量&#xff09;2. 逻辑梯度下降3. 梯度下降的实现及代码描述3.1 计算梯度3.2 梯度下降 4. 数据集&#xff08;单变量&#xff09;附录 导入所需的库 import copy, math import numpy as np %matplotlib wi…

深入了解PostgreSQL:高级查询和性能优化技巧

在当今数据驱动的世界中&#xff0c;数据库的性能和查询优化变得尤为重要。 POSTGRESQL作为一种开源的关系型数据库管理系统&#xff0c;在处理大规模数据和复杂查询时表现出色。 但随着数据量和查询复杂性的增加&#xff0c;性能问题可能会显现出来。 本文将深入探讨POSTGR…

【蓝桥杯备考资料】如何进入国赛?

目录 写在前面注意事项数组、字符串处理BigInteger日期问题DFS 2013年真题Java B组世纪末的星期马虎的算式振兴中华黄金连分数有理数类&#xff08;填空题&#xff09;三部排序&#xff08;填空题&#xff09;错误票据幸运数字带分数连号区间数 2014年真题蓝桥杯Java B组03猜字…

App Cleaner Uninstaller for Mac 苹果电脑软件卸载工具

App Cleaner & Uninstaller 是一款非常有用的 Mac 应用程序清理和卸载工具。它可以彻底地清理系统中的应用程序、扩展和残留文件&#xff0c;以释放磁盘空间并优化系统性能。 此外&#xff0c;它还提供了磁盘空间监控和智能清理建议等功能&#xff0c;使用户可以轻松地管理…

GD32F103VE侵入事件

GD32F103VE的TAMPER引脚(PC13)&#xff0c;当PC13输入低电平时&#xff0c;会产生一个侵入检测事件。它会将所有“数据备份寄存器”内容清除。 这个功能有什么用&#xff1f; 一是防止被人开壳&#xff0c;抄袭。二是自毁功能。 直奔主题&#xff0c;多一句就是浪费时间。测试…