测试用例+自动化测试 —— 博客系统

目录

一、设计测试用例

二、自动化测试

1、导入依赖

1、登录页面

3、列表页面

4、详情页面

5、写博客页面

6、完善

三、总结


一、设计测试用例

二、自动化测试

        使用selenium4 + Junit5单元测试框架,来进行简单的自动化测试。

1、导入依赖

        创建Maven项目,并在pom.xml中导入如下依赖:

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</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-commons</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-reporting</artifactId>
            <version>1.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>
    </dependencies>

公共类:

public class CommonDriver {
    //使用单例模式创建驱动
    private static ChromeOptions options = new ChromeOptions();
    public static ChromeDriver driver = null;
    public static ChromeDriver getDriver(){
        if (driver == null) {
            options.addArguments("--remote-allow-origins=*");
            driver = new ChromeDriver(options);
            //创建驱动的时候就加上隐式等待
            //整个测试就都会隐式等待了
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }

    //获取屏幕截图
    //同时通过参数str来判断是哪个测试类中的截图
    public static void getScreenshot(String str) throws IOException {
        List<String> times = getTime();
        //生成的文件夹的格式:./src/test/autotest-2023-05-21/ListTest-20230521-205350-毫秒.png
        //再加上文件的名称filename
        String filename = "./src/test/autotest-"+times.get(0) +"/"+ str +"-" + times.get(1) + ".png";
        File srcfile = driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图放到指定的路径下
        FileUtils.copyFile(srcfile,new File(filename));
    }

    //获取文件名和文件夹名,通过时间区分屏幕截图
    public static List<String> getTime(){
        //文件格式 20230521-205350-毫秒
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        //文件夹格式 2023-05-21
        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 static void close() {
        driver.quit();
    }
}

 

1、登录页面

         主要测试了:

代码:

① 动态传参,在ParamsUtil 类中写了数据的来源,在这里直接调用即可。但用户名和密码有对应关系,所以使用了Map和Set。同时还要注意,传的是Stream流。

② 多参数,在正确的用户名和错误的密码测试中,使用多参数。直接使用注解CsvSource,并传入数据。这里传入的数据都会被测试到。

public class LoginTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_login.html");
    }
    /*
    * 输入正确的用户名和正确的密码能否登录
    * 使用动态参数
    * */
    @ParameterizedTest
    //需要一个同名的静态方法
    @MethodSource
    public void LoginTrue(String name,String password) {
        driver.findElement(By.cssSelector("#username")).sendKeys(name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        String str2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",str2);
    }
    //给LoginTreu提供数据来源
    static Stream<Arguments> LoginTrue(){
        //在公共类中获取数据
        ParamsUtil paramsUtil = new ParamsUtil();
        String username = paramsUtil.getuserName();
        String password = paramsUtil.getTruetextMap().get(username);
        return Stream.of(Arguments.arguments(username,password));
    }
    /*
    * 输入正确的用户名和错误的密码能否登录
    * 多参数
    * */
    @ParameterizedTest
    @CsvSource(value = {"www,qwe","王文哲,sda","张三,dsv4"})
    public void LoginFalse(String username,String password){
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        String str = driver.findElement(By.cssSelector("body")).getText();
        Assertions.assertEquals("当前用户登录用户名或密码错误",str);
    }
    /*
    * 输入空的用户名和空的密码
    * */
    @Test
    public void LoginNull(){
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#submit")).click();
        String str = driver.findElement(By.cssSelector("body")).getText();
        Assertions.assertEquals("当前用户登录用户名或密码为空",str);
//        driver.navigate().back();
    }
    /*
    * 登录文字是否正确
    * */
    @Test
    public void testDenglu(){
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
    }
    /*
    *用户名输入框是否正确
    * */
    @Test
    public void testNameInput(){
        WebElement element = driver.findElement(By.cssSelector("#username"));
        Assertions.assertNotNull(element);
    }
    /*
    * 密码输入框是否正确
    * */
    @Test
    public void testPasswordInput(){
        WebElement element = driver.findElement(By.cssSelector("#password"));
        Assertions.assertNotNull(element);
    }
    /*
    * 提交按钮是否正确
    * */
    @Test
    public void testSubmit(){
        String str = driver.findElement(By.xpath("//*[@id=\"submit\"]")).getAttribute("value");
        Assertions.assertEquals("提交",str);
    }
}

PrarmsUtil类(数据来源):

public class ParamsUtil {
    private Map<String,String> truetextMap = new HashMap<>();
    public Map<String,String> getTruetextMap() {
        truetextMap.put("www","1234");
        truetextMap.put("王文哲","wwz");
        truetextMap.put("张三","123");
        return truetextMap;
    }
    public String getuserName(){
        //这里需要随机返回一组数据
        truetextMap = getTruetextMap();
        Set<String> set = truetextMap.keySet();
        Object[] arr1 = set.toArray();
        String[] arr2 = new String[set.size()];
        for (int i = 0; i < arr2.length;i++) {
            arr2[i] = (String)arr1[i];
        }
        //Math.random返回的是0~1的小数,因此要乘以数组的长度。
        int index =(int)(Math.random()*arr2.length);
        return arr2[index];
    }
}

3、列表页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ListTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    /*
    * 访问博客列表页面
    * */
    @BeforeEach
    public void getURL(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_list.html");
    }

    /*
    * 当用户未登录的时候,能否正确提示用户,并返回到登录页面让用户进行登录
    * */
    @Test
    @Order(1)
    public void testLogin(){
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //再检查是否跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //如果是登录页面
        //进行登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
        String str2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",str2);
    }
    /*
    * 点击写博客,正确跳转到写博客页面
    * */
    @Test
    @Order(2)
    public void testEdit(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
    /*
    * 点击主页,还是在列表页面
    * */
    @Test
    public void testList(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击注销,跳转到登录页面
    * */
    @Test
    public void testDelete(){
        driver.findElement(By.xpath("/html/body/div[1]/a[3]")).click();
        String text1 = driver.findElement(By.xpath("/html/body/div[2]/form/div/h3")).getText();
        String text2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("登录",text1);
        Assertions.assertEquals("提交",text2);
    }
    /*
    * 点击地址,正确跳转到我的gitee页面
    * */
    @Test
    public void testGitee(){
        driver.findElement(By.cssSelector("body > div.container > div.left > div > a")).click();
        String text1 = driver.findElement(By.cssSelector("#git-header-nav > div > div > div.item.gitosc-logo > a > img.ui.inline.black.image")).getAttribute("alt");
        Assertions.assertEquals("Gitee — 基于 Git 的代码托管和研发协作平台",text1);
    }
    /*
    * 点击列表页的查看全文按钮,跳转到详情页面
    * */
    @Test
    public void testView() {
        driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
    * 文章文字是否正确
    * */
    @Test
    public void testWz(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
    * 分类文字是否正确
    * */
    @Test
    public void testFl(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("分类",text);
    }
    @AfterAll
    public static void close(){
        driver.close();
    }
}

 

4、详情页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DetailTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        //因为详情页只能从列表页,点击查看全文进入
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_list.html");

    }
    /*
    * 当用户未登录时,弹窗提示,并跳转到登录页面
    * */
    @Test
    @Order(1)
    public void testLogin(){
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
        //再到博客详情页
        driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
    }
    /*
     * 文章文字是否正确
     * */
    @Test
    public void testWz(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
     * 分类文字是否正确
     * */
    @Test
    public void testFl(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("分类",text);
    }
    @AfterAll
    public static void close(){
        driver.close();
    }
}

 

5、写博客页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class EditTest {
    ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_edit.html");
    }
    /*
    * 当用户未登录时,弹窗提示,并跳转到登录页面
    * */
    @Test
    @Order(1)
    public void testLogin(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
    }
    /*
    * 编写博客,点击发布按钮,跳转到列表页面
    * */
    @Test
    public void testRelease(){
        driver.findElement(By.cssSelector("#title")).sendKeys("日记2");
        driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll")).sendKeys("今天是521,真开心");
        driver.findElement(By.cssSelector("#submit")).click();
        //看是否跳转到列表页面
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击主页,跳转到列表页面
    * */
    @Test
    public void testList(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        //看是否跳转到列表页面
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击注销,跳转到登录页面
    * */
    @Test
    public void testDelete(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
    }
    /*
    * 点击写博客,还是在写博客页面
    * */
    @Test
    public void testEdit(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
    /*
    * 标题栏输入框是否正确显示
    * */
    @Test
    public void testInput(){
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
    }
    /*
    * 发布按钮是否能正确显示
    * */
    @Test
    public void testSubmit(){
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
}

 

6、完善

(1)使用套件

(2)使用屏幕截图

(3)将close方法都提出来,在DriverQuitTest中写close方法,在套件中使用。

套件:

@Suite
@SelectClasses({LoginTest.class,ListTest.class,EditTest.class,DetailTest.class,DriverQuitTest.class})
public class RunSuit {
}

屏幕截图:

    //获取屏幕截图
    //同时通过参数str来判断是哪个测试类中的截图
    public static void getScreenshot(String str) throws IOException {
        List<String> times = getTime();
        //生成的文件夹的格式:./src/test/autotest-2023-05-21/ListTest-20230521-205350-毫秒.png
        //再加上文件的名称filename
        String filename = "./src/test/autotest-"+times.get(0) +"/"+ str +"-" + times.get(1) + ".png";
        File srcfile = driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图放到指定的路径下
        FileUtils.copyFile(srcfile,new File(filename));
    }

    //获取文件名和文件夹名,通过时间区分屏幕截图
    public static List<String> getTime(){
        //文件格式 20230521-205350-毫秒
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        //文件夹格式 2023-05-21
        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;
    }

DriverQuitTest类:

public class DriverQuitTest extends CommonDriver{
    private static ChromeDriver driver = getDriver();
    @Test
    void driverQuit(){
        driver.quit();
    }
}

三、总结

(1)使用了注解,避免生成过多的对象,造成资源和时间的浪费。

(2)通过static修饰静态变量,全局只创建了一次驱动对象,避免重复创造驱动对象造成时间的浪费。

(3)使用参数化,保持用例的简介,提高了代码的可读性。

(4)使用测试套件,一次执行所有我们想要运行的自动化用例。

(5)使用等待(隐式等待+强制等待),提高自动化指令的稳定性,降低自动化出现误报的概率。

(6)使用屏幕截图,方便问题的追溯和解决。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值