您现在的位置是:首页 >技术杂谈 >【针对项目在线OJ系统的测试】:Junit+Selenium网站首页技术杂谈
【针对项目在线OJ系统的测试】:Junit+Selenium
目录
一、背景介绍:
在这一篇文章当中,我们已经实现了一个简易的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已解决。