针对博客项目进行web自动化测试

项目功能

  • 背景:当你在学习的时候,相信你一定有做笔记的经历,这是一个好习惯,方便你在遗忘或是复习的时候回顾知识,而接下来我要讲的这个程序,就可以方便你去写自己的学习笔记,并且可以发表出来,既方便自己学习,同时也可以分享给别人~

测试计划

功能测试

编写测试用例

在这里插入图片描述

使用Selenium+Junit5进行Web自动化测试

创建测试套件类

  • 创建一个类(自定义名为runSuite),通过 @Suite 注解标识该类为测试套件类(不是测试类),然后使用 @SelectClasses 注解来声明我们要指定的类(通过这个类来运行测试用例),这样优点如下:
  1. 相比于一个一个类来实例化,然后调用函数(测试用例)进行测试就大大减少了开销和时间;
  2. 同时指定了类的测试顺序,即在注解@SelectClasses参数中的类测试顺序为从左向右;
@Suite
@SelectClasses({BlogLoginTest.class, DriveQuitTest.class})

public class runSuite {

}

博客登录页

  • 登录页面正常加载(检查元素是否存在)
  • 登录成功(检查跳转页面元素是否存在)
  • 登录失败
  • 使用注解声@TestMethodOrder(MethodOrderer.OrderAnnotation.class)+@Order(1)声明执行顺序
  • @BeforeAll 表示当前方法需要在当前类下所有用例执行之前执行一次,并且被该注解修饰的方法必须是静态方法
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogLoginTest  extends AutotestUtils{

    public static EdgeDriver driver = createDriver();
    //如果要测试登录页面,以下所有的用例都有一个共同的步骤
    //1.要有浏览器对象 2.访问登录页面的url,因此加一个注解
    @BeforeAll
    static void baseControl(){
        driver.get("http://localhost:8080/login.html");
    }

    /**
     * 检查登录页面正常显示
     * 检查点:(主页,注册 )元素是否存在
     */

    @Test
    @Order(1)
    void loginPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));//主页
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));//注册
        getScreenShot(getClass().getName());
    }
    /**
     * 页面登录成功
     * @param username
     * @param password
     */
    @ParameterizedTest
    @CsvSource({"admin,123456"})
    @Order(2)
    void loginSuc(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("#submit")).click();
        //登录成功,页面跳转至博客列表页,然后可以找到博客列表页的特殊元素,说明登录成功
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));//(创作)

        getScreenShot(getClass().getName());
       // driver.navigate().back();//跳转至列表页需要返回才能再次测试登录页面

    }
    /**
     *1.登录失败
     */
    @ParameterizedTest//参数化方法
    @CsvSource({"admin,1234","lisi,123456"})//多参数
    @Order(3)
    void loginFail(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("#submit")).click();
            //登录失败,弹窗提示“用户名或密码错误”
        Thread.sleep(5000);
        Alert alert = driver.switchTo().alert();//切换到弹窗
        alert.accept();//确认
        getScreenShot(getClass().getName());
        driver.navigate().refresh();
        Thread.sleep(5000);

        }
}

博客列表页(主页)

public class BlogListTest extends AutotestUtils {
    public static EdgeDriver driver = createDriver();
    @BeforeAll
    static void baseControl(){
        driver.get("http://127.0.0.1:8080/blog_list.html");
    }
    @Test
    void BlogListLoadRight(){
        driver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(1)"));//首页
    }
}

博客详情页

public class BlogDetailTest extends AutotestUtils {
    public static EdgeDriver driver = createDriver();

    @BeforeAll
    static void baseControl(){
        driver.get("http://localhost:8080/blog_content.html?id=2");
    }
    @Test
    void  editPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("#title"));
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div > div.date"));
        driver.findElement(By.xpath("//*[@id=\"title\"]"));
    }
}

个人博客列表页

public class BlogListTest extends AutotestUtils {
    public static EdgeDriver driver = createDriver();

    @BeforeAll
    static void baseControl(){
        driver.get("http://localhost:8080/myblog_list.html");
    }
    /**
     * 检查列表页面正常显示
     */
    @Test
    void  listPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));//退出登录
        driver.findElement(By.cssSelector("#artlistDiv > div:nth-child(2) > div:nth-child(4) > a:nth-child(2)"));//修改
        getScreenShot(getClass().getName());
    }
}

修改密码页

  • 有2个弹窗,必须添加强制等待(目前没有想到更好的办法)
 driver.findElement(By.xpath("/html/body/div[1]/a[4]")).click();//修改密码

        driver.findElement(By.cssSelector("#password")).sendKeys("admin");
        driver.findElement(By.cssSelector("#password1")).sendKeys("123456");
        driver.findElement(By.cssSelector("#password2")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();
        
        Thread.sleep(5000);

        Alert alert  = driver.switchTo().alert();
        Thread.sleep(5000);
        alert.accept();
        Thread.sleep(5000);

        alert.accept();
        Thread.sleep(5000);

        String actual = driver.findElement(By.cssSelector("body > div.login-container > div > h3")).getText();
        String expect = "登录";
        Assertions.assertEquals(expect,actual);

编辑博客页

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

    @BeforeAll
    static void baseControl(){
        driver.get("http://localhost:8080/blog_edit.html");
    }
    /**
     * 检查编辑页面正常显示
     */
    @Test
    @Order(1)
    void  editPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));//我的博客
        driver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button"));//发布文章
        getScreenShot(getClass().getName());
    }

   //这个没通过,因为新添加的文章是往后添加的,不是第一篇
    @ParameterizedTest
    @CsvSource("自动化测试")
    @Order(2)
    void editAndSubmit(String title,String content) throws IOException, InterruptedException {
        String expect = title;
        driver.findElement(By.cssSelector("#title")).sendKeys(expect);
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(17) > a > i")).click();//H6
        driver.findElement(By.xpath("/html/body/div[2]/div[1]/button[1]")).click();//发布文章
        
        getScreenShot(getClass().getName());
        String actual = driver.findElement(By.cssSelector("#artlistDiv > div:nth-child(1) > div.title")).getText();
        Assertions.assertEquals(expect,actual);
    }
}

退出驱动

  • 测试登录,驱动退出,然后创建驱动,测试编辑页,驱动退出
  • 浪费资源和时间,拖慢测试进程
  • 编写一个独立的退出类,在所有测试完成后,退出驱动
public class DriveQuitTest extends AutotestUtils {
    public static EdgeDriver driver = createDriver();
    @Test
    void driveQuit(){
        driver.quit();
    }
}

屏幕截图

  • 有的时候测试用例执行出错了,需要查看当时网页出现的情况,那么就需要使用屏幕截图来排查问题
 public List<String> 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<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }
    public void getScreenShot(String str) throws IOException {
        List<String> list = getTime();
        // ./是当前项目路径下
        String filename = "./src/test/java/com/blog/test/"+list.get(0)+"/"+ str +"/"+list.get(1)+".png";//路径文件名
        File srcfile = driver.getScreenshotAs(OutputType.FILE);//srcfile 是 生成的屏幕截图
        FileUtils.copyFile(srcfile,new File(filename));//将 srcfile 放到指定的文件夹下
    }

测试有什么亮点

  • 使用selinium4自动化测试工具和junit5单元测试框架结合

  • 使用了junit5中提供的注解@Test,避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率

  • 只创建一次驱动,避免每个用例重复创建驱动对象造成时间的浪费

  • 使用注解@ParameterizedTest参数化:保持用例的简洁,提高代码的可读性

  • 注解@Suite测试套件:降低了测试人员的工作量,通过套件一次执行所有的测试用例

  • 使用等待:提高了自动化运行效率,提高了自动化的稳定性

  • 屏幕截图:有的Bug不能复现,方便问题的追溯和解决

自动化测试发现bug的多少

  • 就我的一个小项目来说,发现的bug并不多,因为自动化测试做的是一些相对稳定的功能【回归测试】,在前面的项目版本中,已经将bug修复,所以说,发现的bug并不多~

遇到过哪些异常

  • NoSuchElementException:没有该元素异常
    1.是否 selinium 没有定位到元素
  • TimeoutException : 超时异常
  • ElementNotVisibleException :元素不可见异常
  • 产生弹窗,隐式等待不生效,需添加显示等待
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值