目录
一.项目介绍
若需要【萌笔趣棋】项目源码可后台私信
(一)项目简介
“新酱爱玩的五子棋” 是一款以《蜡笔小新》春日部角色为主题背景的五子棋游戏。该游戏基于网页端开发,通过简洁易懂的界面设计,为玩家提供经典五子棋的对战体验,融合了趣味性与竞技性,目标用户主要为喜爱五子棋和《蜡笔小新》动漫的人群。
(二)功能介绍
- 注册页面:玩家可在此页面输入自定义的用户名和密码进行账号注册。系统会对输入信息进行验证,确保用户名的唯一性等,成功注册后可获得在游戏中进行对战的资格。
- 登录页面:已注册玩家输入正确的用户名和密码登录游戏。登录成功后,可进入游戏大厅开始游戏相关操作;若输入错误,系统会提示重新输入。
- 游戏大厅:玩家登录后进入游戏大厅,可查看自己的游戏信息,包括用户名、当前分数、比赛场次和获胜场次等。点击 “开始匹配” 按钮,系统会自动为玩家寻找对战对手,在匹配过程中可点击取消匹配。
- 游戏房间:匹配成功后进入游戏房间,玩家和对手在此进行五子棋对战。游戏界面会显示棋盘,玩家按规则轮流落子。当一方率先在棋盘的横线、竖线或斜线上形成连续的五个棋子时,判定为获胜方,系统会显示胜负结果,并更新玩家在游戏大厅中的相关数据(如分数、比赛场次、获胜场次等) 。
(三)页面展示
1.注册页面
2.登录页面
3.游戏大厅页面
信息展示/开始匹配
4.游戏房间页面(对战)
落子/回合切换
胜负判定
二.功能测试
在此就不展示进行功能测试的截图了,具体可以跳转到(三)页面展示
(一)出现的bug
1.在进行注册功能时候,出现了用户名或者密码输入为空,但是仍然注册成功的情况
(二)解决方法
1.在注册页面的前端代码中加入如下拦截请求代码:
// 验证用户名和密码是否为空
if (!username.trim()||!password.trim()) {
alert('用户名或者密码不能为空');
return; // 阻止表单提交
}
三.自动化测试
源码:gobangAutoTest: 网页版五子棋对战——Web自动化测试
(一)测试用例设计
(二)测试准备
1.工具选择:
使用Selenium 并配合Junit单元测试框架
2.搭建和配置环境:
2.1 创建Maven项目——gobangAutoTest
2.2 在pom.xml中引入相关依赖
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</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.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
2.3 包的模块化设计:
(三)编写测试脚本
1.工具类
public class AutotestUtils {
public static EdgeDriver driver;
/**
* 创建驱动对象
*/
public static EdgeDriver createDriver() {
if (driver == null) {
WebDriverManager.edgedriver().setup();
EdgeOptions options = new EdgeOptions();
options.addArguments("--remote-allow-origins=*");
// options.addArguments("-headless");
driver = new EdgeDriver(options);
//创建隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
return driver;
}
/**
* 获取时间戳
*/
public List<String> getTime() {
SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd");
String filename = sim1.format(System.currentTimeMillis());
String dirname = sim2.format(System.currentTimeMillis());
List<String> list = new ArrayList();
list.add(dirname);
list.add(filename);
return list;
}
/**
* 获取屏幕截图
*/
public void getScreenShot(String str) throws IOException {
List<String> list = this.getTime();
String filename = "./src/test/java/com/gobangAutoTest/" + list.get(0) + "/" + str + "_" + list.get(1) + ".png";
File srcfile = (File)driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcfile, new File(filename));
}
}
2.注册功能
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class RegisterPageTest extends AutotestUtils {
//1.驱动对象
public static EdgeDriver driver = createDriver();
/**
访问注册页面的URL
*/
@BeforeAll
static void baseControl() {
driver.get("http://127.0.0.1:8080/register.html");
}
/**
* 检查注册页面是否正常打开
* 检查点:注册框标题 是否存在
*/
@Test
@Order(1)
void registerPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("body > div.login-container > div > h3"));
getScreenShot(getClass().getName());
}
/**
* 检查正常注册的情况,会出现弹窗:注册成功!
*/
@ParameterizedTest
@CsvSource({"na_na,123"})
@Order(3)
void registerSuc(String name,String password) throws InterruptedException, IOException {
String expected = "注册成功!";
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
driver.findElement(By.cssSelector("#submit")).click();
//处理弹窗
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
String accept = alert.getText();
alert.accept();
getScreenShot(getClass().getName());
Assertions.assertEquals(expected,accept);
}
/**
* 检查异常注册的情况:用户名或者密码为空
* 会出现弹窗提示
*/
@ParameterizedTest
@CsvSource({"oppop"})
@Order(3)
void registerFail(String name) throws InterruptedException, IOException {
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
String expected = "用户名或者密码不能为空!";
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#submit")).click();
//处理弹窗
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
String accept = alert.getText();
alert.accept();
getScreenShot(getClass().getName());
Assertions.assertEquals(expected,accept);
}
}
3.登录测试
//一个类注解,表明测试方法将按照@Order注解 指定执行顺序
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class LoginPageTest extends AutotestUtils {
//1.驱动对象
public static EdgeDriver driver = createDriver();
//被BeforeAll修饰的方法必须为静态的,而静态的方法内不能存取非静态变量和非静态方法
//在当前测试类中所有测试方法执行之前只执行一次
@BeforeAll
/**
访问登录页面的URL
*/
static void baseControl() {
driver.get("http://127.0.0.1:8080/login.html");
}
/**
检查登录页面是否正常打开
检查点:登录按钮 登录框标题 是否存在
*/
@Test
@Order(1)
void loginPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("#submit"));
driver.findElement(By.cssSelector("body > div.login-container > div > h3"));
getScreenShot(getClass().getName());
}
/**
检查正常登录的情况
*/
@ParameterizedTest
//为参数化测试提供Csv格式的数据
@CsvSource({"wukong,123","w_o.ogason,123"})
@Order(2)
void loginSuc(String name, String passwd) throws InterruptedException, IOException {
//这三步只是登录的步骤,能不能保证登录是成功的呢?
//clear 先清空
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#password")).sendKeys(passwd);
driver.findElement(By.cssSelector("#submit")).click();
//处理“登录成功的弹窗”
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
//对登录结果进行检验——跳转到游戏大厅页面才算是登录成功
//检查“个人信息框”元素是否存在
//driver.findElement(By.cssSelector("#screen"));
//检查“开始匹配按钮”元素是否存在
driver.findElement(By.cssSelector("#match-button"));
getScreenShot(getClass().getName());
//页面返回——防止执行第二个测试用例时候因为页面跳转而导致元素查找失败
driver.navigate().back();
}
/**
检查异常登录的情况
*/
@ParameterizedTest
@CsvSource({"wukong,12"})
@Order(3)
void loginFail(String name, String passwd) throws IOException {
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#password")).sendKeys(passwd);
driver.findElement(By.cssSelector("#submit")).click();
//对登录失败的结果进行检验
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
String res = alert.getText();
alert.accept();
getScreenShot(getClass().getName());
// System.out.println(res);
assert res.equals("登录失败! 用户名密码错误! 或者该账号正在游戏中!");
}
}
3.“游戏大厅”测试
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GameHallTest extends AutotestUtils {
//1.驱动对象
public static EdgeDriver driver = createDriver();
/**
访问游戏大厅页面的URL
*/
@BeforeAll
static void baseControl() {
driver.get("http://127.0.0.1:8080/game_hall.html");
}
/**
* 检查登录状态下的游戏大厅页面是否正常打开
* */
@Test
@Order(1)
void gameHallLoadRight() throws IOException {
//检查“开始匹配按钮”元素是否存在
driver.findElement(By.cssSelector("#match-button"));
getScreenShot(getClass().getName());
}
/**
* 检查正登录状态下:点击“开始匹配”按钮否会变化
*/
@Test
@Order(2)
void gameHallSuc() throws InterruptedException, IOException {
String expected = "匹配中...(点击取消)";
WebElement matchButton = driver.findElement(By.cssSelector("#match-button"));
matchButton.click();
//强制等待,等按钮文字改变
Thread.sleep(3);
String accept = driver.findElement(By.cssSelector("#match-button")).getText();
getScreenShot(getClass().getName());
Assertions.assertEquals(expected,accept);
}
}
4.“游戏房间”测试
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GameRoomTest extends AutotestUtils {
//1.驱动对象
public static EdgeDriver driver = createDriver();
/**
访问游戏大厅页面的URL
*/
@BeforeAll
static void baseControl() {
driver.get("http://127.0.0.1:8080/game_room.html");
}
/**
* 检查登录——未匹配用户状态下的的游戏房间是否有弹窗
*/
@Test
@Order(1)
void gameRoomFail() throws InterruptedException, IOException {
String expected = "连接游戏失败! reason: 用户并未匹配成功! 不能开始游戏!";
Thread.sleep(1000);
Alert alert = driver.switchTo().alert();
String accept = alert.getText();
alert.accept();
getScreenShot(getClass().getName());
Assertions.assertEquals(expected,accept);
}
}
5.驱动退出和测试套件类
public class driverQuitTest extends AutotestUtils {
public static EdgeDriver driver = createDriver();
@Test
void driverQuit() {
driver.quit();
}
}
@Suite//创建测试套件
// 用于Suite的注解,指定要包含在测试套件中的测试类
@SelectClasses({RegisterPageTest.class, LoginPageTest.class,GameHallTest.class,GameRoomTest.class,driverQuitTest.class})
public class runSuite {
}
(四)测试结果
运行结果
四.性能测试
总体测试框架
例子
1.设置线程组
模拟 100 个虚拟用户同时进行登录操作,在10秒内完成
用于测试五子棋游戏登录功能在高并发场景下的性能和稳定性。
2.添加http请求
3.结果分析
总体而言,从这两个报告看,该 HTTP 请求的响应时间短且稳定,无异常请求,系统在当前测试场景下性能表现良好,能较快速且稳定地处理请求 。
五.总结
功能测试保障软件功能正常、无缺失和错误,让用户有预期体验;性能测试确保软件在不同负载下响应及时、不卡顿崩溃,评估承载能力;自动化测试提升效率、降成本、保准确一致,在开发流程中及时发现问题,稳定软件质量。