Personal blog system project for automated testing (including complete detailed code)

Table of contents

1. Project interface

2. Blog system automation test case

 3. Automated testing

1) Preparation

2) Login interface test

Test the correct login case

There was a problem with the login screen test

 Test for bad login cases

3) Blog list interface test

4) Blog details interface test

 5) Blog editing interface test

1. Write blogs and post blogs for validation

2. Verify the title of the published blog

6) Delete function blog test

7) Logout function test

4. Overall automated testing

 overall code


1. Project interface

login interface

Registration interface

 Blog list interface

Blog details interface

Blog Editing Interface

 Blog modification page

2. Blog system automation test case

 3. Automated testing

Next, we will introduce the above test cases one by one for automated testing.

1) Preparation

1. Prepare the selenium environment to build: https://blog.csdn.net/qq_73471456/article/details/130836494

2. Create a Maven project in IDEA and import pom.xml related dependencies

<dependencies>
        <!-- 导入selenium依赖 -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>

        <!--        保存屏幕截图需要用到的包-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- 导入Junit测试框架 -->
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.2</version>
        </dependency>
        <!--  导入junit 参数化依赖-->
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.2</version>
        </dependency>
    </dependencies>

 Note: If after importing the Junit dependency, if using the @Test annotation fails, you need to click the @Test annotation, select the add Maven option and

3. Initialize the browser driver, because you need to create the driver before running each automated test case, and you need to release the browser driver after running all the test methods, so create a class to initialize the browser driver and release the browser at this time device

package Blog;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class StartAndEnd {
    // 初始化浏览器驱动
    static   WebDriver webDriver;
    @BeforeAll
    static void Start(){
        // 加载浏览器驱动
        webDriver = new ChromeDriver();
    }
    @AfterAll
    static  void End(){
        // 释放浏览器驱动
        webDriver.quit();
    }

}

2) Login interface test

Test the correct login case

 /**
     * 登录成功界面测试用例
     */
    @Order(2)
    @ParameterizedTest
    @CsvSource("是烟花哈,123")
    void LoginSuccess(String username, String password) throws InterruptedException {
        // 打开博客登录界面
        webDriver.get("http://121.43.190.21:8080/login.html");
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入账号:是烟花哈
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入密码:123
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击提交按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 强制等待3秒钟
        sleep(1000);
        webDriver.switchTo().alert().accept();//跳转到弹窗  点击确认,如果有取消按钮就用dismiss()方法


        // 跳转到博客列表页 (判断当前跳转页面url == http://121.43.190.21:8080/myblog_list.html 测试通过  否则测试不通过)
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/myblog_list.html", url);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 博客列表页展示用户信息为“是烟花哈” (判断当前用户名 == 是烟花哈  测试通过 否则测试不通过)
        String name = webDriver.findElement(By.cssSelector("#username")).getText();
        Assertions.assertEquals("是烟花哈", name);
    }

There was a problem with the login screen test

Reasons for analysis: Implicit waiting cannot recognize non-HTML pop-up windows, and pop-up windows cannot wait. At this time, the page has not been loaded and the pop-up window has not appeared, so the program starts to look for the pop-up window. When the program does not find the pop-up window An exception error was reported. At this time, implicit waiting cannot be used to process the pop-up window, and mandatory waiting or display waiting is required.

Implicit waiting has been used in the above code. When explicit waiting and implicit waiting appear in the same program at the same time, errors may occur, so you can only choose mandatory waiting instead of implicit waiting.

 Test for bad login cases

/**
     * 登录失败界面测试用例
     */
    @Order(1)
    @ParameterizedTest
    @CsvSource({"是烟花哈,123456", "小红,123"})
    // 验证用户名或者密码错误情况
    void LoginFail(String username, String password) throws InterruptedException {
        // 打开博客登录界面
        webDriver.get("http://121.43.190.21:8080/login.html");
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入账号:是烟花哈
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入密码:123
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击提交按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 强制等待3秒钟
        sleep(2000);
        // 获取弹窗内容 == 登录失败!用户名或密码错误,请重新输入 登录失败
        String text = webDriver.switchTo().alert().getText();//跳转到弹窗  点击确认,如果有取消按钮就用dismiss()方法
        Assertions.assertEquals("登录失败!用户名或密码错误,请重新输入", text);
        //点击弹窗确定按钮
        webDriver.switchTo().alert().accept();

        // 判断当前跳转页面url == http://121.43.190.21:8080/login.html 测试通过  否则测试不通过)
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/login.html", url);
    }

3) Blog list interface test

 /**
     * 查看博客列表界面测试
     * 效验博客列表文章数量不为0
     */
    @Order(3)
    @Test
    void BlogList() {
        // 获取博客列表页网址
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 获取博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)

        int num = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();
        System.out.println(num);
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 判断所有文章数量不为0 测试通过
        Assertions.assertNotEquals(0, num);

        // 判断个人信息中的文章数量是否与博客列表文章标题数量是否一致
        String articleNum = webDriver.findElement(By.cssSelector("#artCount")).getText();
        Assertions.assertEquals(articleNum, num + "");
    }

 Note: Get the number of titles of all blog posts on the blog list page, use findElements to get the number of multiple titles , and locate multiple specific div tags #artDiv > div.blog > div.title

4) Blog details interface test

 /**
     * 博客详情界面测试
     * 点击查看全文按钮是否能跳转到文章详情页,效验URL
     * 效验文章详情页的博客文章标题是否与博客标题一致,若一致则测试通过
     */
    @Order(4)
    @Test
    void Blog_content() {
        // 获取博客列表页网址
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击第一篇文章的查看全文按钮
        webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(1) > a:nth-child(4)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 效验跳转页面url == http://121.43.190.21:8080/blog_content.html?id=5
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/blog_content.html?id=5", url);

    }

Points to note: When the CSS selector cannot locate the title in the div element, find the specific path of the title in the div box, and list the div paths separately

Use this positioning method:

body > div.container > div.container-right > div.blog-content > h3

 5) Blog editing interface test

1. Write blogs and post blogs for validation

 /**
     * 博客编辑界面测试
     * 写博客和发布博客测试
     */
    @Order(5)
    @Test
    void BlogEdit() throws InterruptedException {
        // 找到写博客按钮并点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 找到输入框输入标题
        webDriver.findElement(By.cssSelector("#title")).sendKeys("自动化测试");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击发布按钮
        webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
        // 点击发布文章跳出弹窗进行确认
        sleep(2000);
        webDriver.switchTo().alert().accept();
        // 强制等待2秒
        sleep(2000);
        webDriver.switchTo().alert().accept();
        // 强制等待2秒
        sleep(2000);
        webDriver.switchTo().alert().dismiss();

        // 效验发布成功跳转页面url == 博客文章列表页url
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/myblog_list.html", url);
    }

2. Verify the title of the published blog

 /**
     * 效验已发布博客标题
     * 效验已发布博客时间
     */
    @Order(6)
    @Test
    void BlogInfoCheck(){
        // 回到文章列表页
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 获取发布博客标题
        String text = webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(7) > div.title")).getText();
        // 获取发布博客时间
        String blog_time = webDriver.findElement(By.xpath("//*[@id=\"artDiv\"]/div[7]/div[2]")).getText();
        // 效验发布博客标题是否一致
        Assertions.assertEquals("自动化测试",text);
        // 效验博客列表页发布博客时间是否与发布博客时间一致
        Assertions.assertEquals("2023-07-27",blog_time);
    }

6) Delete function blog test

 /**
     * 删除已发布的博客文章
     * 效验删除之前文章数量与删除之后文章数量不相同
     */
    @Order(7)
    @Test
    void Delete() throws InterruptedException {
        // 打开博客列表页
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 查询删除之前文章数量
        // 获取删除之前博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)
        int  BeforNum = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();

        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击删除按钮
        webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(7) > a:nth-child(6)")).click();
        // 强制等待3秒
       sleep(2000);
        // 进行删除弹窗确认
        webDriver.switchTo().alert().accept();
        // 强制等待3秒
        sleep(2000);
        // 进行删除弹窗二次确认
        webDriver.switchTo().alert().accept();

        // 效验删除之后文章数量与删除之前文章数量是否不一致 ,若不一致则删除测试成功
        // 获取删除之后的博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)

        int AfterNum = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();
        Assertions.assertNotEquals(BeforNum,AfterNum);
    }

7) Logout function test

 /**
     * 注销功能测试
     * 点击注销按钮,页面跳转到登录界面,判断当前页面是否为登录界面,测试通过
     */
    @Order(8)
    @Test
    void logout() throws InterruptedException {
        // 找到注销按钮并点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        // 强制等待3秒 等待注销弹窗
        sleep(2000);

        // 定位到弹窗并确认
        webDriver.switchTo().alert().accept();
        sleep(2000);
        // 获取当前跳转页面url
        String url = webDriver.getCurrentUrl();
        // 效验当前页面 == 登录界面url
        Assertions.assertEquals("http://121.43.190.21:8080/login.html",url);
       
    }

4. Overall automated testing

Automated testing of blog system

 overall code

package Blog;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

/**
 * 自动化测试用例
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogCases extends StartAndEnd { // 继承初始化浏览器驱动和释放驱动
    /**
     * 登录成功界面测试用例
     */
    @Order(2)
    @ParameterizedTest
    @CsvSource("是烟花哈,123")
    void LoginSuccess(String username, String password) throws InterruptedException {
        // 打开博客登录界面
        webDriver.get("http://121.43.190.21:8080/login.html");
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入账号:是烟花哈
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入密码:123
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击提交按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 强制等待3秒钟
        sleep(1000);
        webDriver.switchTo().alert().accept();//跳转到弹窗  点击确认,如果有取消按钮就用dismiss()方法


        // 跳转到博客列表页 (判断当前跳转页面url == http://121.43.190.21:8080/myblog_list.html 测试通过  否则测试不通过)
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/myblog_list.html", url);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 博客列表页展示用户信息为“是烟花哈” (判断当前用户名 == 是烟花哈  测试通过 否则测试不通过)
        String name = webDriver.findElement(By.cssSelector("#username")).getText();
        Assertions.assertEquals("是烟花哈", name);
    }

    /**
     * 登录失败界面测试用例
     */

    @Order(1)
    @ParameterizedTest
    @CsvSource({"是烟花哈,123456", "小红,123"})
    // 验证用户名或者密码错误情况
    void LoginFail(String username, String password) throws InterruptedException {
        // 打开博客登录界面
        webDriver.get("http://121.43.190.21:8080/login.html");
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入账号:是烟花哈
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 输入密码:123
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        // 隐式等待3秒钟
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击提交按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 强制等待3秒钟
        sleep(2000);
        // 获取弹窗内容 == 登录失败!用户名或密码错误,请重新输入 登录失败
        String text = webDriver.switchTo().alert().getText();//跳转到弹窗  点击确认,如果有取消按钮就用dismiss()方法
        Assertions.assertEquals("登录失败!用户名或密码错误,请重新输入", text);
        //点击弹窗确定按钮
        webDriver.switchTo().alert().accept();

        // 判断当前跳转页面url == http://121.43.190.21:8080/login.html 测试通过  否则测试不通过)
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/login.html", url);
    }

    /**
     * 查看博客列表界面测试
     * 效验博客列表文章数量不为0
     */
    @Order(3)
    @Test
    void BlogList() {
        // 获取博客列表页网址
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 获取博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)

        int num = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();
        System.out.println(num);
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 判断所有文章数量不为0 测试通过
        Assertions.assertNotEquals(0, num);

        // 判断个人信息中的文章数量是否与博客列表文章标题数量是否一致
        String articleNum = webDriver.findElement(By.cssSelector("#artCount")).getText();
        Assertions.assertEquals(articleNum, num + "");
    }

    /**
     * 博客详情界面测试
     * 点击查看全文按钮是否能跳转到文章详情页,效验URL
     * 效验文章详情页的博客文章标题是否与博客标题一致,若一致则测试通过
     */
    @Order(4)
    @Test
    void Blog_content() {
        // 获取博客列表页网址
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 点击第一篇文章的查看全文按钮
        webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(1) > a:nth-child(4)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 效验跳转页面url == http://121.43.190.21:8080/blog_content.html?id=5
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/blog_content.html?id=5", url);

    }

    /**
     * 博客编辑界面测试
     * 写博客和发布博客测试
     */
    @Order(5)
    @Test
    void BlogEdit() throws InterruptedException {
        // 找到写博客按钮并点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 找到输入框输入标题
        webDriver.findElement(By.cssSelector("#title")).sendKeys("自动化测试");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击发布按钮
        webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
        // 点击发布文章跳出弹窗进行确认
        sleep(2000);
        webDriver.switchTo().alert().accept();
        // 强制等待2秒
        sleep(2000);
        webDriver.switchTo().alert().accept();
        // 强制等待2秒
        sleep(2000);
        webDriver.switchTo().alert().dismiss();

        // 效验发布成功跳转页面url == 博客文章列表页url
        String url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.43.190.21:8080/myblog_list.html", url);
    }
    /**
     * 效验已发布博客标题
     * 效验已发布博客时间
     */
    @Order(6)
    @Test
    void BlogInfoCheck(){
        // 回到文章列表页
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 获取发布博客标题
        String text = webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(7) > div.title")).getText();
        // 获取发布博客时间
        String blog_time = webDriver.findElement(By.xpath("//*[@id=\"artDiv\"]/div[7]/div[2]")).getText();
        // 效验发布博客标题是否一致
        Assertions.assertEquals("自动化测试",text);
        // 效验博客列表页发布博客时间是否与发布博客时间一致
        Assertions.assertEquals("2023-07-27",blog_time);
    }
    /**
     * 删除已发布的博客文章
     * 效验删除之前文章数量与删除之后文章数量不相同
     */
    @Order(7)
    @Test
    void Delete() throws InterruptedException {
        // 打开博客列表页
        webDriver.get("http://121.43.190.21:8080/myblog_list.html");
        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 查询删除之前文章数量
        // 获取删除之前博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)
        int  BeforNum = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();

        // 隐式等待3秒
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击删除按钮
        webDriver.findElement(By.cssSelector("#artDiv > div:nth-child(7) > a:nth-child(6)")).click();
        // 强制等待3秒
       sleep(2000);
        // 进行删除弹窗确认
        webDriver.switchTo().alert().accept();
        // 强制等待3秒
        sleep(2000);
        // 进行删除弹窗二次确认
        webDriver.switchTo().alert().accept();

        // 效验删除之后文章数量与删除之前文章数量是否不一致 ,若不一致则删除测试成功
        // 获取删除之后的博客列表页所有博客文章标题数量
        // (注意点:获取多个标题数量 使用findElements ,定位具体的div标签 #artDiv > div.blog > div.title)

        int AfterNum = webDriver.findElements(By.cssSelector("#artDiv > div.blog > div.title")).size();
        Assertions.assertNotEquals(BeforNum,AfterNum);
    }
    /**
     * 注销功能测试
     * 点击注销按钮,页面跳转到登录界面,判断当前页面是否为登录界面,测试通过
     */
    @Order(8)
    @Test
    void logout() throws InterruptedException {
        // 找到注销按钮并点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        // 强制等待3秒 等待注销弹窗
        sleep(2000);

        // 定位到弹窗并确认
        webDriver.switchTo().alert().accept();
        sleep(2000);
        // 获取当前跳转页面url
        String url = webDriver.getCurrentUrl();
        // 效验当前页面 == 登录界面url
        Assertions.assertEquals("http://121.43.190.21:8080/login.html",url);

    }
}


Guess you like

Origin blog.csdn.net/qq_73471456/article/details/131932994