> 文章列表 > 【针对项目在线OJ系统的测试】:Junit+Selenium

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

【针对项目在线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();@BeforeAllpublic 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已解决。