实战:博客系统的 Web 自动化测试

06-01 1551阅读

目录

一.引言

二.项目介绍

(一)项目功能

(二)页面展示 

1.注册页面

2.登录页面

3.列表页面

4.详情页面

5.编辑页面

三.测试用例设计

 四.自动化测试准备

(一)工具选择

(二)环境搭建及项目创建

五.编写测试脚本

(一)实现工具类

(二)登录功能测试

 (三)列表页面功能测试

(四)详情页面功能测试 

(五)写博客功能测试

(六)驱动退出和测试套件类 实现

 六、测试执行与结果分析

七.测试总结及亮点

(一)总结

(二) 亮点

 一.引言

项目自动化测试源码:BlogAutoTest: 我的博客系统——Web自动化测试实战

在软件开发的世界里,质量是生命线。对于博客系统这样的应用而言,确保其功能的稳定性和可靠性至关重要。自动化测试作为一种高效的质量保障手段,能够帮助我们快速、准确地发现系统中的问题。本篇文章将围绕 [个人博客系统] 展开,详细介绍如何进行自动化测试。

二.项目介绍

(一)项目功能

本项目围绕博客系统展开,涉及注册、登录、博客列表展示、博客详情查看、博客编写等功能:

  1. 注册页面:提供用户名、密码及确认密码输入框,用户可在此完成注册操作,点击提交后跳转至登录页面。
  2. 登录页面:设有用户名和密码输入框,用户输入已在后端数据库存储的账号信息,点击提交后,若验证通过,将跳转至列表页面。
  3. 博客列表页面:展示已发布博客的标题、发布时间和内容概要,每篇博客旁有查看全文、修改、删除操作按钮。左侧呈现登录用户信息及文章数、分类数。右上角有主页(即当前列表页)、写博客、注销功能,可进行相应页面跳转。
  4. 博客详情页面:显示单篇博客完整内容,以及发布时间、阅读量等信息。
  5. 博客编辑页面:具备富文本编辑功能,用户可输入文章标题,在编辑区域撰写博客内容,完成后点击提交可发布博客,发布成功后跳转至列表页面

(二)页面展示 

1.注册页面

实战:博客系统的 Web 自动化测试

2.登录页面

实战:博客系统的 Web 自动化测试

3.列表页面

实战:博客系统的 Web 自动化测试

4.详情页面

实战:博客系统的 Web 自动化测试

5.编辑页面

实战:博客系统的 Web 自动化测试

三.测试用例设计

这里使用的软件是Xmind

 实战:博客系统的 Web 自动化测试

 四.自动化测试准备

(一)工具选择

本次自动化测试选用了 Selenium 作为主要工具。Selenium 是一个强大的 Web 自动化测试框架,能够模拟用户在浏览器中的各种操作,支持多种编程语言,如 Java、Python 等。配合 JUnit 作为测试框架,方便组织和运行测试用例,以及查看测试结果。

(二)环境搭建及项目创建

  1. 安装浏览器驱动:这里使用的浏览器是Edge。根据所使用的浏览器(如 Chrome、Edge 等),下载并配置对应的驱动程序,确保 Selenium 能够与浏览器进行交互。
  2. 项目创建:在IDEA中创建Maven项目——BlogAutoTest
  3. 引入依赖:在 pom.xml 文件中添加如下依赖:

    4.0.0
    org.example
    MyTest
    1.0-SNAPSHOT
    
        17
        17
    
    
        
            org.junit.jupiter
            junit-jupiter
            5.8.2
            test
        
        
            org.junit.platform
            junit-platform-suite
            1.8.2
            test
        
        
            org.seleniumhq.selenium
            selenium-java
            4.0.0
        
        
            io.github.bonigarcia
            webdrivermanager
            5.9.0
        
    

    4. 包的模块化设计 :依据系统功能特性,将相关类放置在同一个包中,实现代码的组织和管理。比如在本次项目里,创建 Tests 包放测试用例类,common包放工具类,这样做能提高代码可读性、可维护性和可复用性。结构如下图所示:

实战:博客系统的 Web 自动化测试

五.编写测试脚本

所有测试功能类的代码均已标注注释,方便理解与问题排查

(一)实现工具类

在common包内创建一个AutotestUtils类,用来存放在测试过程中常用的重复代码。主要方法有:

  1. createDriver():创建 Edge 浏览器驱动(配置跨域选项和隐式等待)
  2. getTime():生成时间戳字符串(用于截图文件名和目录名)
  3. getScreenShot():基于当前时间戳保存屏幕截图,支持问题追溯
public class AutotestUtils {
    public static EdgeDriver driver;
    /**
     * 创建驱动对象
     */
    public static EdgeDriver createDriver() {
        if (driver == null) {
            WebDriverManager.edgedriver().setup();
            EdgeOptions options = new EdgeOptions();
            options.addArguments("--remote-allow-origins=*");
            // options.addArguments("-headless");
            driver = new EdgeDriver(options);
            //创建隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }
   /**
    * 获取时间戳
    */
    public List getTime() {
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd");
        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 getScreenShot(String str) throws IOException {
        List list = this.getTime();
        String filename = "./src/test/java/com/blogWebAutoTest/" + list.get(0) + "/" + str + "_" + list.get(1) + ".png";
        File srcfile = (File)driver.getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(srcfile, new File(filename));
    }
}

(二)登录功能测试

在Tests包内创建一个BlogLoginTest类。主要测试方法有:

  • loginPageLoadRight():验证登录页面加载正常(检查主页、写博客、注册元素)
  • loginSuc():参数化测试正常登录场景(验证登录后跳转至博客列表页)
  • loginFail():参数化测试异常登录场景(验证错误提示弹窗内容)
    @TestMethodOrder(OrderAnnotation.class)
    class BlogLoginTest extends AutotestUtils {
        //1.驱动对象
        public static EdgeDriver driver = createDriver();
        //被BeforeAll修饰的方法必须为静态的
        //在当前测试类中所有测试方法执行之前只执行一次
        @BeforeAll
        /**
        访问登录页面的URL
        */
        static void baseControl() {
            driver.get("http://127.0.0.1:7070/login.html");
        }
        @Test
        @Order(1)
        /**
        检查登录页面是否正常打开
        检查点:主页 写博客 注册 元素是否存在
        */
        void loginPageLoadRight() throws IOException {
            driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));
            driver.findElement(By.xpath("/html/body/div[1]/a[2]"));
            driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));
            getScreenShot(getClass().getName());
        }
        @ParameterizedTest
        @CsvSource({"Wukong.Sun,111111","w_o.ogason,123456"})
        @Order(2)
        /**
        检查正常登录的情况
        */
        void loginSuc(String name, String passwd) throws InterruptedException, IOException {
            //这三步只是登录的步骤,能不能保证登录是成功的呢?
            //clear 先清空
            driver.findElement(By.cssSelector("#username")).clear();
            driver.findElement(By.cssSelector("#password")).clear();
            driver.findElement(By.cssSelector("#username")).sendKeys(name);
            driver.findElement(By.cssSelector("#password")).sendKeys(passwd);
            driver.findElement(By.cssSelector("#submit")).click();
            //对登录结果进行检验——跳转到博客列表页才算是登录成功
            //检查“查看全文”元素是否存在
            //driver.findElement(By.cssSelector("#artDiv > div:nth-child(1) > a:nth-child(4)"));
            //检查“文章”元素是否存在
            driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(4) > span:nth-child(1)"));
            getScreenShot(getClass().getName());
            //页面返回——防止执行第二个测试用例时候因为页面跳转而导致元素查找失败
           driver.navigate().back();
        }
        @ParameterizedTest
        @CsvSource({"Wukong.Sun,11111"})
        @Order(3)
        /**
         检查异常登录的情况
         */
        void loginFail(String name, String passwd) throws IOException {
            driver.findElement(By.cssSelector("#username")).clear();
            driver.findElement(By.cssSelector("#password")).clear();
            driver.findElement(By.cssSelector("#username")).sendKeys(name);
            driver.findElement(By.cssSelector("#password")).sendKeys(passwd);
            driver.findElement(By.cssSelector("#submit")).click();
            
            //对登录失败的结果进行检验
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
            wait.until(ExpectedConditions.alertIsPresent());
            Alert alert = driver.switchTo().alert();
            String res = alert.getText();
            alert.accept();
            getScreenShot(getClass().getName());
           // System.out.println(res);
            assert res.equals("抱歉登录失败,用户名或密码输入错误,请重试!");
        }
    }

     (三)列表页面功能测试

    在common包内创建BlogListTest类,主要测试方法有:

    • listPageLoadRight():验证登录状态下列表页加载正常(检查 "文章" 和 "分类" 元素是否存在)
      public class BlogListTest extends AutotestUtils {
          public static EdgeDriver driver = createDriver();
          @BeforeAll
          static void baseControl() {
              driver.get("http://127.0.0.1:7070/myblog_list.html");
          }
          /**
           * 博客列表页正常显示-登录状态下
           */
          @Test
          void listPageLoadRight() throws IOException {
              //文章 分类元素是否存在
              driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(4) > span:nth-child(1)"));
              driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(4) > span:nth-child(2)"));
               getScreenShot(getClass().getName());
          }
      }
      

      (四)详情页面功能测试 

      在Tests包内创建BlogDeatailTest类,主要测试方法有:

      • blogDeailLoadRight():验证登录状态下博客详情页加载正常(检查标题和时间元素是否存在)
        public class BlogDetailTest extends AutotestUtils {
            public static EdgeDriver driver = createDriver();
            @BeforeAll
            static void baseControl() {
                driver.get("http://127.0.0.1:7070/blog_content.html?id=26");
            }
            @Test
            /**
             * 检查博客详情页是否正常打开-登录状态下
             */
            void blogDeailLoadRight() throws IOException {
                //标题元素
                driver.findElement(By.cssSelector("#title"));
                //时间元素
                driver.findElement(By.cssSelector("#updatetime"));
                getScreenShot(getClass().getName());
            }
        }
        

        (五)写博客功能测试

         在common包内创建BlogEditTest类,主要测试方法有:

        • editPageLoadRight():验证博客编辑页面是否能正常加载(检查标题框和提交按钮是否存在)
        • editAndSubmitBlog():验证博客文章是否可以正常发布
          @TestMethodOrder(OrderAnnotation.class)
          public class BlogEditTest extends AutotestUtils {
              public static EdgeDriver driver = createDriver();
              @BeforeAll
              static void baseControl() {
                  driver.get("http://127.0.0.1:7070/blog_add.html");
              }
              @Test
              @Order(1)
              /**
               * 检查博客编辑页可以正常打开
               */
              void editPageLoadRight() throws IOException {
                  //检查标题框和提交按钮是否存在
                  driver.findElement(By.cssSelector("#title"));
                  driver.findElement(By.cssSelector("#submit"));
                  getScreenShot(getClass().getName());
              }
              @Test
              @Order(2)
              /**
               * 检查博客可以正常发布文章
               */
              void editAndSubimitBlog() throws IOException, InterruptedException {
                  String expect = "java104&105 Autotest";
                  driver.findElement(By.cssSelector("#title")).sendKeys(expect);
                  //因博客系统使用到的编辑是第三方软件,所以不能直接使用sendkeys向编辑模块发送文本
                  //横线
                  Thread.sleep(10);
                  driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
                 //删除线
                  Thread.sleep(10);
                  driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(5) > a > i")).click();
                  Thread.sleep(10);
                  driver.findElement(By.cssSelector("#submit")).click();
                 //处理第一个弹窗——确认发布文章吗?
                  Thread.sleep(10);
                  WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
                  wait.until(ExpectedConditions.alertIsPresent());
                  Alert alert = driver.switchTo().alert();
                  alert.accept();
                 //处理第二个弹窗——是否继续发布文章
                  Thread.sleep(10);
                  WebDriverWait wait2 = new WebDriverWait(driver, Duration.ofSeconds(3));
                  wait2.until(ExpectedConditions.alertIsPresent());
                  Alert alert2 = driver.switchTo().alert();
                  alert2.dismiss();
                  Thread.sleep(10);
                 //获取列表页博客标题文本,检查是否跟预期相符
                  getScreenShot(getClass().getName());
                  String actual = driver.findElement(By.cssSelector("#artDiv > div > div.title")).getText();
                  Assertions.assertEquals(expect, actual);
              }
          }

          (六)驱动退出和测试套件类 实现

          1. 在Tests包内创建 driverQuitTest类:使浏览器驱动退出
          2. 在Tests包内创建 runSuite类:组合多个测试类为一个执行单元,提升测试效率和可维护性。通过注解@SelectClasses可指定测试类的执行顺序。
          3. 两者配合实现了从功能测试到资源释放的全流程自动化管理。
          public class driverQuitTest extends AutotestUtils {
              public static EdgeDriver driver = createDriver();
              @Test
              void driverQuit() {
                  driver.quit();
              }
          }
          
          @Suite//创建测试套件
          // 指定要执行的测试类
          @SelectClasses({BlogLoginTest.class,BlogListTest.class,BlogEditTest.class,BlogDetailTest.class,driverQuitTest.class})
          public class runSuite {
          }
          

           六、测试执行与结果分析

          可以看到所有测试用例均执行通过。

          说明我们的博客系统在当前测试场景下功能正常,能够满足基本的业务需求。但这并不意味着系统完全没有问题,后续还需要不断扩展测试用例,覆盖更多的边界情况和复杂场景。

          实战:博客系统的 Web 自动化测试

          实战:博客系统的 Web 自动化测试

          七.测试总结及亮点

          (一)总结

           通过对博客系统进行自动化测试,我们能够在开发过程中及时发现并解决问题,有效提高系统的质量和稳定性。在未来,我们可以进一步扩展测试用例,增加对不同浏览器兼容性的测试,以及性能测试等。同时,将自动化测试集成到持续集成 / 持续交付(CI/CD)流程中,实现每次代码提交都自动触发测试,确保新的代码变更不会引入新的问题,为博客系统的持续迭代和优化提供有力保障。

          (二) 亮点

          1. 使用了 junit5 中提供的注解:避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率。
          2. 只创建一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。
          3. 使用参数化:保持用例的简洁,提高代码的可读性。
          4. 测试套件:降低了测试人员的工作量,通过套件一次执行所有要运行的测试用例。
          5. 使用了等待:提高了自动化运行效率,提高了自动化的稳定性。
          6. 屏幕截图:方便问题的追溯以及问题的解决。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码