您现在的位置是:首页 >技术杂谈 >【针对项目在线OJ系统的测试】:Junit+Selenium网站首页技术杂谈

【针对项目在线OJ系统的测试】:Junit+Selenium

革凡成圣211 2023-05-20 04:00:02
简介【针对项目在线OJ系统的测试】:Junit+Selenium

目录

一、背景介绍:

二、导入的依赖:

三、测试模块1:index页面的测试

测试点1:测试"我的OJ系统这4个字是否存在"

测试点2:测试"题目列表"这4个字是否存在

测试点3:测试"编号","标题","难度"三者是否存在

测试点4:测试题目列表的元素

测试步骤1:明确需要哪些参数(从左到右)

测试步骤2:在一个指定的文件当中,分别放入上述的内容

测试步骤3:编写测试用例代码

四、测试模块:题目详情页和代码编辑的测试

步骤1:明确需要的测试参数

步骤2:新建一个文件,保存两道题目的测试用例,以逗号隔开

步骤3:编写测试用例代码

步骤4:分别针对两道题目进行用户输入代码的测试

针对题目1进行测试:

测试代码1:测试编译错误是否可以检查出来

测试代码2:测试运行异常

测试代码3:测试代码运行超时情况

测试代码4:正确输入的情况

测试代码5:测试用户输入中文注释的情况

第一步:查看后台接收请求的方式(编码集):

 第二步:查看编译生成的文件夹

 第三步:查看编译命令

解决问题

再次验证bug

​编辑


一、背景介绍:

在这一篇文章当中,我们已经实现了一个简易的OJ平台;

【项目篇1】一个在线OJ系统_革凡成圣211的博客-CSDN博客回顾一下我们常见的OJ平台,例如:leetcode,牛客等等,他们都有哪些功能?https://blog.csdn.net/weixin_56738054/article/details/130072129?spm=1001.2014.3001.5502下面,我们来介绍一下,怎样针对这一个平台进行测试。


二、导入的依赖:

       导入的依赖主要是selenium框架的jar包+junit5的jar包,项目的主要测试步骤就是通过运行junit进行排查。

<dependency>
               <groupId>commons-io</groupId>
               <artifactId>commons-io</artifactId>
               <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</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>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

三、测试模块1:index页面的测试

index页面就是一个用户查询题目列表的页面,当用户输入了URL之后,就可以查询这一个页面了

这个页面如下:

 新建一个测试类:IndexTest,并且定位到指定的页面,并且截图,上传到指定的文件夹;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class IndexTest extends CommonDriver{

    /**
     * 获取到这一个driver实例
     */
    private static final FirefoxDriver driver= getDriver();

    @BeforeAll
    public static void getPage() throws InterruptedException, IOException {
        driver.get("http://localhost:8080/OJSystem_war_exploded");
        //需要对于首页进行截图
        //以文件的形式存储
        File srcFile=driver.getScreenshotAs(OutputType.FILE);
        //把截图的文件存放到指定的目录下面
        File destFile=new File("E:/OJSystem/src/test/Files/index.png");
        Thread.sleep(1000);
        FileUtils.copyFile(srcFile,destFile);
        //设置隐式等待时间:最长3秒
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
    }
}

测试点1:测试"我的OJ系统这4个字是否存在"

 /**
     * 测试:"我的OJ系统"这个标题是否存在
     */
    @Test
    @Order(1)
    public void checkTittle(){
        WebElement webElement =driver.findElement(By.cssSelector("body > nav > a"));
        String text=webElement.getText();
        //断言:二者是否一致
        Assertions.assertEquals("我的 OJ 系统",text);
    }

 

 测试结果:通过


测试点2:测试"题目列表"这4个字是否存在

 /**
     * 测试:"题目列表" 是否存在
     */
    @Test
    @Order(2)
    public void checkProblemListIfExits(){
        WebElement element=driver.findElement(By.cssSelector("#tables > div > div > h3"));
        String test= element.getText();
        Assertions.assertEquals("题目列表",test);
    }

 测试结果:通过


测试点3:测试"编号","标题","难度"三者是否存在

/**
     * 测试:编号、标题、难度三者是否存在
     */
    @Test
    @Order(3)
    public void checkProblemListTittles(){
        //测试:"编号"是否存在
        WebElement element1=driver.findElement(By.cssSelector("#tables > div > div > table > thead > tr > th:nth-child(1)"));
        String number=element1.getText();
        Assertions.assertEquals("编号",number);
        //测试:"标题"是否存在
        WebElement element2=driver.findElement(By.cssSelector("#tables > div > div > table > thead > tr > th:nth-child(2)"));
        String tittle=element2.getText();
        Assertions.assertEquals("标题",tittle);
        //测试:"难度"是否存在
        WebElement element3=driver.findElement(By.cssSelector("#tables > div > div > table > thead > tr > th:nth-child(3)"));
        String hard=element3.getText();
        Assertions.assertEquals("难度",hard);
    }

测试结果:通过


测试点4:测试题目列表的元素

测试目的:验证题目列表当中的内容是否正确;

例如验证第一题的序号是不是"1",链接是不是"两数之和",难度是否为"简单"

考虑到测试的题目是一系列的题目,因此可以采用参数化的方式模拟参数传入。


测试步骤1:明确需要哪些参数(从左到右)

参数1:题目编号的CSS选择器;

参数2:题目编号的预期;

参数3:题目链接"两数之和"的链接的CSS选择器;

参数4:题目链接"两数之和"的文本;

参数5:题目难度的CSS选择器;

参数6:题目难度的文本;


测试步骤2:在一个指定的文件当中,分别放入上述的内容

在指定目录下面,新建一个.csv文件,并且配置这两个题目的参数


#题目1的测试参数

problemTable > tr:nth-child(1) > td:nth-child(1),1,problemTable > tr:nth-child(1) > td:nth-child(2) > a,两数之和,problemTable > tr:nth-child(1) > td:nth-child(3),简单


#题目2的测试参数

problemTable > tr:nth-child(2) > td:nth-child(1),3,problemTable > tr:nth-child(2) > td:nth-child(2) > a,搜索插入位置,problemTable > tr:nth-child(2) > td:nth-child(3),简单

测试步骤3:编写测试用例代码

分别抓取上述题目列表里面的三个元素的CSS选择器,进行测试,或者点击题目链接,进行截图。

/**
     * 在csc文件当中:#是注释,不可以直接拼接
     * 测试index页面的题目
     * 题目链接的css选择器@param cssSelector
     * 预计的标题@param tittleExcept
     * 预计的编号@param number
     * 预计的难度@param hard
     */
    @ParameterizedTest
    @Order(4)
    @CsvFileSource(files = "E:\OJSystem\src\main\resources\ProjectTest.csv")
    public void checkClickTittle(
                                 String numberCss,String numberExcept,
                                 String tittleLinkedCss,String tittleExcept,
                                 String difficultCss,String difficultExcept) throws InterruptedException, IOException {
        {
            //校验题目列表编号是否正确
            WebElement numberElem = driver.findElement(By.cssSelector("#"+numberCss));
            String realNumber = numberElem.getText();
            //比较列表和实际的是否一致
            Assertions.assertEquals(numberExcept, realNumber);
        }
        {
            //获取到题目链接的css选择器
            WebElement TittleLinkElement = driver.findElement(By.cssSelector("#"+tittleLinkedCss));
            //获取题目链接的实际内容
            String tittleReal = TittleLinkElement.getText();
            Assertions.assertEquals(tittleExcept, tittleReal);
            //点击,看一下跳转的结果:
            TittleLinkElement.click();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //截图:看是否成功跳转
            File srcFile=driver.getScreenshotAs(OutputType.FILE);
            //把截图的文件存放到指定的目录下面
            File destFile=new File("E:/OJSystem/src/test/Files/ProblemLinked"+numberExcept+".png");
            Thread.sleep(1000);
            FileUtils.copyFile(srcFile,destFile);
        }
        {
            //题目难度的CSS选择器
            WebElement difficulties = driver.findElement(By.cssSelector("#"+difficultCss));
            String realTittle=difficulties.getText();
            //难度的比较
            Assertions.assertEquals(difficultExcept,realTittle);
        }
    }

测试结果:通过 


四、测试模块:题目详情页和代码编辑的测试

步骤1:明确需要的测试参数

参数1:题目的编号(主键Id);

参数2:标题:例如"两数之和"的CSS选择器;

参数3:标题的内容:例如"两数之和";

参数4:题目细节的CSS选择器(例如上图当中的题目细节就是描述)

参数5:代码编辑框的CSS选择器


步骤2:新建一个文件,保存两道题目的测试用例,以逗号隔开

#测试第一题:两数之和
1,problemDesc > h3,1.两数之和_简单,problemDesc > pre > p,editor > div.ace_scroller > div

#测试第二题:搜索插入位置
3,problemDesc > h3,3.搜索插入位置_简单,problemDesc > pre > p,editor > div.ace_scroller > div

步骤3:编写测试用例代码

由于真实的题目长度和代码编辑框当中的代码呈现比较长,因此就不使用断言测试了,改为:观察+控制台输出的方式。

 /**
     *
     * 针对某一题设计的测试
     * 测试详情页的元素是存在
     * 标题的CSS选择器@param tittleCss
     * 题目的描述的CSS选择器@param detailsCss
     * 模板代码的CSS选择器@param templateCodeCss
     */
    @ParameterizedTest
    @CsvFileSource(files = "E:\OJSystem\src\main\resources\ProblemDetails.csv")
    public void testDescribe(String tittleId,
                             String tittleCss,String tittleContentExcept,
                             String detailsCss,
                             String codeEditCss){
        //锁定题目的标题
        driver.get("http://localhost:8080/OJSystem_war_exploded/problemDetail.html?id="+tittleId);
        //设置最长等待时间
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        //测试标题是否符合预期
        {
            WebElement tittleCssReal = driver.findElement(By.cssSelector("#"+tittleCss));
            String realContent = tittleCssReal.getText();
            //测试题目的标题和预期是否一致
            Assertions.assertEquals(tittleContentExcept,realContent);
        }
        //测试题目的描述是否和预期一样
        {
            WebElement descCssReal=driver.findElement(By.cssSelector("#"+detailsCss));
            String realDetails=descCssReal.getText();
            System.out.println("真实的题目"+realDetails);
        }
        //测试模板代码
        {
            WebElement codeEditElem=driver.findElement(By.cssSelector("#"+codeEditCss));
            //获取到模板代码的测试框
            String codeText=codeEditElem.getText();
            System.out.println("测试框的代码:"+codeText);
        }
    }

步骤4:分别针对两道题目进行用户输入代码的测试

在这里就不再使用自动化脚本进行测试了,因为用户输入代码的场景比较复杂,不适宜使用自动化测试,改为手工测试;

针对题目1进行测试:

测试代码1:测试编译错误是否可以检查出来

测试结果:

 测试情况:通过


测试代码2:测试运行异常

测试代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] nums1=new int[3];
        nums1[3]=0;
        return nums1;
    }
}

测试结果:

测试结果:通过 


测试代码3:测试代码运行超时情况

测试代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        
        int i=0;
        while(i<=100){
            System.out.println(i++);
            i--;
        }
        return nums;
    }
}

测试情况:通过 


测试代码4:正确输入的情况

测试情况:通过测试。


测试代码5:测试用户输入中文注释的情况


这是一个BUG!!

排除步骤:

第一步:查看后台接收请求的方式(编码集):

发现是utf8编码集,并且控制台也正常的输出了用户提交的题目:

 


 第二步:查看编译生成的文件夹


 第三步:查看编译命令

此处我采用的命令是:javac -encoding utf8 %s -d %s,采用的是utf8的编码集进行编译的。

切换到cmd命令行,再次使用这个命令编译一下:

        bug原因分析:windows系统默认的编码集是gbk,因此需要采用gbk的编码集来进行编译(但是,如果把项目部署到Linux系统,就不用gbk了,就需要采用utf8编码集。


解决问题

把编译的命令改成: javac -encoding gbk %s -d %s


再次验证bug

bug已解决。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。