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

news2024/11/20 13:26:54

目录

一、背景介绍:

二、导入的依赖:

三、测试模块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已解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式(十二)之装饰器模式

文章目录什么是装饰器模式例子&#xff1a;总结什么是装饰器模式 现在有一块蛋糕&#xff0c;涂上奶油就变成了奶油蛋糕&#xff0c;如果加上草莓就是草莓奶油蛋糕&#xff0c;再加上蜡烛就变成了生日蛋糕。 程序中的对象与蛋糕十分相似。将对象类比成蛋糕&#xff0c;不断的加…

Faster-RCNN代码解读6:主要文件解读-中

Faster-RCNN代码解读6&#xff1a;主要文件解读-中 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现&#xff0c;不要多想&#xff0c;我还没有厉害到可以一个人复现所有代码。所以&#xff0c;是参考别人的代码&#xff0c;进行自己的解读。 ​ 代码来自于B站的UP主&#xff…

Qt音视频开发36-超时检测和自动重连的设计

一、前言 如果网络环境正常设备正常&#xff0c;视频监控系统一般都是按照正常运行下去&#xff0c;不会出现什么问题&#xff0c;但是实际情况会很不同&#xff0c;奇奇怪怪七七八八的问题都会出现&#xff0c;就比如网络出了问题都有很多情况&#xff08;交换机故障、网线故…

TensorFlow 1.x 深度学习秘籍:11~14

原文&#xff1a;TensorFlow 1.x Deep Learning Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…

持续集成——通过docker命令安装Jenkins

一、持续集成体系介绍 1、核心价值&#xff1a; 集成自动化测试&#xff0c;减少重复劳动 尽早发现和解决缺陷,减少风险 形成有机整体&#xff0c;明确阶段交付物 2、常见集成方案 a、阶段化 为不同的构建测试套件建立不同的CI循环周期 单元测试运行时间短&#xff0c;反馈…

测试基础篇

目录软件测试的生命周期测试用例设计如何描述一个bug如何创建一个Bug案例Bug的级别Bug的生命周期测试人员和开发人员产生争执了怎么办&#xff1f;软件测试的生命周期 软件测试的生命周期&#xff1a;需求分析→测试计划→测试设计、软件开发→测试执行→测试评估 软件测试&a…

AXI DMA

PG021 AXI DMA&#xff1a;AXI Direct Memory Access AXI DMA为内存和AXI4-Stream外设之间提供了高带宽的直接内存访问&#xff0c;其可选的S/G功能可以将CPU从数据搬运任务中解放出来。 AXI DMA通过AXI4-LITE接口对寄存器做一些配置和获取 MM2S&#xff1a;MemoryMap to St…

css 盒模型

CSS 中的盒子模型包括 IE 盒子模型和标准的 W3C 盒子模型。 box-sizing(有 3 个值哦)&#xff1a;border-box,padding-box,content-box 这两种盒子模型最主要的区别就是 width 的包含范围&#xff1a; 在 标准的盒子模型中&#xff0c;width只是 content 部分&#xff08;b…

嵌入式51单片机02-独立按键系列

文章目录独立按键一. 独立按键基础知识二. 独立按键系列代码1. 独立按键控制LED&#xff08;按下灯亮&#xff0c;松开灯灭&#xff09;&#xff08;1&#xff09;仿真电路图&#xff08;2&#xff09;源代码&#xff08;3&#xff09;实验结果2. 独立按键控制LED&#xff08;按…

聚观早报|阿里云正式推出通义千问;京东零售开启5年最大组织变革

今日要闻&#xff1a;国家网信办规范生成式人工智能服务&#xff1b;阿里云正式推出通义千问&#xff1b;京东零售开启5年来最大组织变革&#xff1b;飞书将推出智能AI助手「My AI」&#xff1b;乐高将继续扩大在华零售布局国家网信办规范生成式人工智能服务 4 月 11 日&#x…

谈一谈Java的ThreadLocal

目录 先说原理&#xff1a; 再上代码&#xff1a; 运行结果&#xff1a; 先说原理&#xff1a; ThreadLocal 是一个本地线程副本变量工具类&#xff0c;它可以在每个线程中创建一个副本变量&#xff0c;每个线程可以独立地修改自己的副本变量&#xff0c;而不会影响其他线程…

【进阶C语言】自定义类型:结构体,枚举,联合

前言 作者简介&#xff1a;热爱跑步的恒川&#xff0c;正在学习C/C、Java、Python等。 本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等&#xff0c;持续更新&#xff01; 相关…

ECM8.0——CCCM相关代码

ECM8.0——CCCM相关代码概览predIntraCCCMxCccmCalcModelsxCccmApplyModelxCccmCreateLumaRefxCccmGetLumaRefBufxCccmGetLumaPuBufxCccmCalcRefAverxCccmCalcRefArea概览 函数名称函数作用predIntraCCCM总体代码&#xff0c;根据CCCM技术预测输出xCccmCalcModels计算CCCM滤波器…

Idea+maven+spring-cloud项目搭建系列--14 整合请求参数校验

前言&#xff1a;当我们在进行web 项目的开发时&#xff0c;对于前端传入的参数&#xff0c;都需要进行一些非空必填等的验证&#xff0c;然后在进行业务逻辑的处理&#xff0c;如果写一堆的if 判断很不优雅&#xff0c;那么有没有好的方式来帮忙处理&#xff0c;本文通过hiber…

光电隔离转换器 直流信号放大器 导轨安装DIN11 IPO OC系列

概述&#xff1a; 导轨安装DIN11 IPO OC系列模拟信号隔离放大器是一种将输入信号隔离放大、转换成按比例输出的直流信号混合集成厚模电路。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等需要直流信号隔离测控的行业。此系列产品内部采用了线性光电隔离技术相…

DSP中定点与浮点运算

一、定点数及其定标 在定点DSP芯片中&#xff0c;采用的是定点数据数值运算&#xff0c;其操作数一般采用整形数来表示。一个整形数的最大表示范围由DSP芯片给定字长决定。字长越长&#xff0c;表示的范围越大&#xff0c;精度越高。 举例16位字长 每个16数位用1个符号位表示正…

九龙证券|这一刻,资本市场进入全新时代!

2023年4月10日&#xff0c;第一批10家主板注册制企业上市鸣锣敲钟&#xff0c;奏响了触及本钱商场灵魂深处革新的序曲。 动能切换中的我国对于高效资源配置的渴望&#xff0c;与革新进行时的本钱商场对于全面注册制的探究&#xff0c;一起凝集成一股连绵有力之暖流&#xff0c;…

学习安全攻防技能30讲-开篇|别说你没有被安全困扰过

文章目录学习安全攻防技能30讲-开篇|别说你没有被安全困扰过研读开篇安全重要吗&#xff1f;安全难学吗&#xff1f;学习安全攻防技能30讲-开篇|别说你没有被安全困扰过 研读开篇 文中说到一个竞赛叫CTF&#xff0c;这个之前从来没有听过的&#xff0c;作为开发人员涨知识了。…

Java封装

Java封装\huge{Java封装}Java封装 JavaJavaJava的三大特征之一。 作用 告知如何设计对象的属性和方法&#xff0c;将对象完全独立起来。 ❗❗封装原则 对象代表什么&#xff0c;就要封装对应的数据&#xff0c;并且提供对应数据的行为。&#xff08;尤其是后半句非常重要&a…

012:Mapbox GL显示弹窗Popup

第012个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中显示弹窗。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共70行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozhuan…