AcCode项目测试报告

文章目录


项目介绍

AcCode是一个类似于牛客力扣的在线OJ平台,可以进行算法题的编写,提交后可以看到题目是否通过。项目使用的技术栈有:Java、MySQL、SpringBoot、MyBatis、Redis、Nginx、Docker。

项目的主要功能有:

  1. 登录注册
  2. 添加/修改题目信息
  3. 提交并运行代码,查看代码运行是否通过
  4. 反向代理和负载均衡
  5. 沙箱机制保护物理主机

编写测试用例

部分测试截图

根据测试用例编写自动化测试

使用Junit5+selenium对项目进行简单的自动化测试。把项目验证码关闭,方便自动化测试。

1. 创建功能类

java 复制代码
public class AutoTestUtil {
    private static volatile ChromeDriver driver;
    private AutoTestUtil(){}
    public static ChromeDriver getDriver() {
        if (driver == null){
            synchronized (AutoTestUtil.class) {
                if (driver == null) {
                    ChromeOptions options = new ChromeOptions();
                    options.addArguments("--remote-allow-origins=*");
                    driver = new ChromeDriver(options);
                    // 设置隐式等待
                    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
                }
            }
        }
        return driver;
    }
}

2. 编写注册功能自动化

java 复制代码
// 标注排序
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RegAutoTest {
    private static ChromeDriver driver;

    @BeforeAll
    public static void init() {
        driver = AutoTestUtil.getDriver();
        driver.get("http://127.0.0.1:7777/reg.html");
        driver.manage().window().maximize();
    }

    /**
     * 检测页面是否正确打开
     */
    @Order(1)
    @Test
    public void check() {
        String key = driver.findElement(By.xpath("/html/body/div/h1")).getText();
        // 断言
        Assertions.assertEquals("注册账号",key);
    }

    /**
     * 错误注册
     * @param username
     * @param password
     * @param confirmPassword
     */
    @Order(2)
    @ParameterizedTest
    @CsvSource(value = {"null,null,null","null,test,test","test,null,test","test,test,null","test,test,1234"})
    public void errorReg(String username,String password,String confirmPassword) throws InterruptedException {
        WebElement usernameInput = driver.findElement(By.xpath("//*[@id=\"username\"]"));
        WebElement passwordInput = driver.findElement(By.cssSelector("#password"));
        WebElement confirmPass = driver.findElement(By.xpath("//*[@id=\"confirmPassword\"]"));
        if (!"null".equals(username)) {
            usernameInput.sendKeys(username);
        }
        if (!"null".equals(password)) {
            passwordInput.sendKeys(password);
        }
        if (!"null".equals(confirmPassword)) {
            confirmPass.sendKeys(confirmPassword);
        }
        driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();
        Thread.sleep(800);
        // 点击警告弹窗上的确认按钮
        driver.switchTo().alert().accept();
        usernameInput.clear();
        passwordInput.clear();
        confirmPass.clear();
    }

    @Order(3)
    @ParameterizedTest
    @CsvSource(value = {"test,test,test"})
    public void successReg(String username,String password,String confirmPassword) throws InterruptedException {
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password);
        driver.findElement(By.xpath("//*[@id=\"confirmPassword\"]")).sendKeys(confirmPassword);
        driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();
        Thread.sleep(500);
        driver.switchTo().alert().accept();
    }

    @AfterAll
    public static void quit() {
        driver.quit();
    }


}

执行示例:

3.编写登录功能自动化

编写自动化代码

java 复制代码
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoginAutoTest {
    private static ChromeDriver driver;

    @BeforeAll
    public static void init() {
        driver = AutoTestUtil.getDriver();
        driver.get("http://127.0.0.1:7777/login.html");
        driver.manage().window().maximize();
    }

    /**
     * 检测页面是否正确打开
     */
    @Order(1)
    @Test
    public void check() {
        String str = driver.findElement(By.cssSelector("body > div > h1")).getText();
        Assertions.assertEquals("AcCode登录",str);
    }

    @Order(2)
    @ParameterizedTest
    @CsvSource(value = {"null,null","null,test","test,null","test,123","demo,demo"})
    public void errorLogin(String username,String password) throws InterruptedException {
        WebElement usernameInput = driver.findElement(By.cssSelector("#username"));
        WebElement passwordInput = driver.findElement(By.xpath("//*[@id=\"password\"]"));
        if (!"null".equals(username)) {
            usernameInput.sendKeys(username);
        }
        if  (!"null".equals(password)) {
            passwordInput.sendKeys(password);
        }
        driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();
        Thread.sleep(800);
        driver.switchTo().alert().accept();
        usernameInput.clear();
        passwordInput.clear();
    }

    @Order(3)
    @ParameterizedTest
    @CsvSource(value = {"admin,admin","test,test"})
    public void success(String username,String password) throws InterruptedException {
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password);
        driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();
        // 检测是否跳转到题目列表页面
        String str = driver.findElement(By.xpath("//*[@id=\"tables\"]/div/div/h3")).getText();
        Assertions.assertEquals("题目列表",str);
        // 注销
        driver.findElement(By.cssSelector("body > nav > a.btn.btn-light")).click();
        Thread.sleep(400);
        driver.switchTo().alert().accept();
    }

    @AfterAll
    public static void quit() {
        driver.quit();
    }
}

测试中发现bug,如果用户不存在查询不到就会出现空指针异常,被统一异常处理捕获。

所有测试用例全部通过

自动化测试展示:

性能测试

使用LoadRunner对项目进行简单的性能测试。模拟多个用户同时进行登录后进入题目点击提交题目。

1.使用VUG编写性能测试脚本

模拟用户进入登录页面并进行登录

c 复制代码
Action()
{
	// 开启进入登录页面事务
	lr_start_transaction("login_html");
	
	/* 注册获取返回参数,该方法可以配合打印返回数据,检测数据内容 */
	web_reg_save_param("ParaResult",
					   "LB=",
					   "RB=",
					   LAST);
	// 定义虚拟用户集合点
	lr_rendezvous("user_start");
	// 定义检测点,检测登录页面是否正确打开
	web_reg_find("Text=AcCode",LAST);
	// 访问登录页面
	web_url("login_html",
		"URL=http://127.0.0.1:7777/login.html",
		"TargetFrame=",
		"Resource=0",
		"Referer=",
		LAST);
	// 结束进入登录页面事务
	lr_end_transaction("login_html",LR_AUTO);
	
	// 开启登录事务
	lr_start_transaction("login");
	// 进行登录
	web_submit_data("user_login",
		"Action=http://127.0.0.1:7777/user/login",
		"Method=POST",
		"TargetFrame=",
		"Referer=",
		"Mode=HTTP",
		ITEMDATA,
		"Name=username", "Value={username}", ENDITEM,
		"Name=password", "Value={password}", ENDITEM,
		LAST);
	// 定义检测点,检测登录后题目列表页面是否正确打开
	web_reg_find("Text=ID",LAST);
	// 结束进入登录事务
	lr_end_transaction("login",LR_AUTO);
	
	// 开启访问题目列表事务
	lr_start_transaction("problemList_html");
	// 访问题目列表页面
	web_url("index_html",
		"URL=http://127.0.0.1:7777/index.html",
		"TargetFrame=",
		"Resource=0",
		"Referer=",
		LAST);
	
	// 结束访问题目列表事务
	lr_end_transaction("problemList_html",LR_AUTO);
	return 0;
}

添加4个用户名密码

2. 创建测试场景

1.设置10个虚拟用户

2.设置没5秒初始化两个用户

3.设置每5秒进入2个虚拟用户到测试场景

4.设置虚拟用户循环执行5分钟

5.设置执行结束后,每5秒退出一个虚拟用户

6.添加监控系统资源

监控CPU的运行时间和剩余内存

3.开始执行

4. 简单分析性能测试报告

事务报告

在事务报告中,一般只关心平均值和标准偏差,标准偏差值越大,说明越不稳定 ,可以到在脚本里写的login事务,

运行的虚拟用户图表

这个图标对应了前面设置的每5秒进入两个虚拟用户到测试场景,以及每5秒有一个虚拟用户从测试场景退出,中间从40秒到5分4时秒是服务器的负载时间,对应前设置的循环执行5分钟。

点击率表

通过点击率表可以看到和虚拟用户运行表运行对应起来,虚拟用户的增多点击率也随之增多,点击率越多说明和服务器的交互次数也越多。

吞吐量图表

吞吐量图形和点击数图形有点相似,但是吞吐量的曲线会稍微延后一点递增,因为吞吐量表示的是响应返回的资源数量,是要现有请求才会有响应的。

系统资源消耗图

precessorTime:CPU使用时间,被消耗的处理器时间数量

Available MBytes:可用的物理内存,一般根据这个指标推算消耗的物理内存有多大。(已经消耗的物理内存=实际内存 - 可用物理内存)


相关推荐
Seven 7 Chihiro3 小时前
软件测试之缺陷介绍
功能测试
测试老哥6 小时前
Jmeter测试脚本编写技巧
自动化测试·软件测试·功能测试·测试工具·jmeter·职场和发展·性能测试
Seven 7 Chihiro12 小时前
软件测试之非功能测试设计
功能测试
小白学大数据1 天前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
weixin_419349791 天前
selenium 报错 invalid argument: invalid locator
selenium·测试工具
程序猿000001号1 天前
Selenium 深度解析:自动化浏览器操作的利器
selenium·测试工具·自动化
大霞上仙2 天前
selenium 在已打开浏览器上继续调试
python·selenium·测试工具
字节程序员2 天前
使用JUnit进行集成测试
jmeter·junit·单元测试·集成测试·压力测试
座礁2 天前
4、交换机IP接口功能
网络·功能测试
小码哥说测试3 天前
Charles简单压力测试
自动化测试·软件测试·网络协议·selenium·接口测试·压力测试·postman