文章目录
一、项目背景
五子棋作为经典策略型棋类游戏,其核心规则要求玩家在网格状棋盘上交替落子,率先形成横向、纵向或斜向连续五枚同色棋子的一方获胜。在互联网技术驱动下,这一历史悠久的智力竞技活动正经历网络化转型,其载体从传统的实体棋盘演变为数字化交互形态。当前主流的在线五子棋解决方案致力于构建轻量化访问入口,通过浏览器即可实现多人在线博弈或人机对抗,无需依赖本地软件安装。本项目的核心目标在于打造跨终端适配的即时对战环境,依托标准化Web技术确保用户无论使用桌面设备、移动终端还是平板电脑,均可获得统一的低延迟交互体验,从而突破传统棋类游戏的空间与设备限制,实现全天候可访问的沉浸式策略竞技场景。
二、项目功能
-
注册页面:用户可通过输入有效的用户名和密码完成注册,注册成功后将自动跳转至登录页面。
-
登录页面:用户输入正确的用户名和密码即可登录,登录成功后将直接进入游戏大厅页面。
-
游戏大厅页面:该页面展示登录玩家的基本信息,包括用户名、积分、参赛场次及获胜场次。玩家点击"开始匹配"按钮后进入匹配状态,此时按钮将变为"匹配中…(点击停止)",再次点击可取消匹配,按钮恢复原状。若匹配成功,用户将被自动分配至游戏房间。
-
游戏房间页面:房间内包含两位玩家,分别担任先手方与后手方,玩家仅能在自己的回合进行操作。当任意一方达成五子连珠时,游戏结束并显示胜负结果。双方均可点击"回到大厅"按钮返回游戏大厅。
三、测试计划
1. 功能测试
1.1 注册页面
1.1.1 正常注册
- 输入合法的账号和密码,点击注册
1.1.2 异常注册
-
未输入账号和密码,点击登录
-
输入账号,但是未输入密码,点击登录
-
未输入账号,但是输入密码,点击登录
-
输入已经注册的账号,输入密码,点击登录
1.2 登录页面
1.2.1 正常登录
- 输入正确的账号和密码,点击登录
1.2.2 异常登录
-
未输入账号和密码,点击登录
-
输入账号但是未输入密码,点击登录
-
未输入账号但是输入密码,点击登录
-
输入正确的账号,错误的密码,点击登录
1.3 游戏大厅页面
1.3.1 开始匹配
1.3.2 取消匹配
1.4 游戏房间页面
1.4.1 落子
-
在己方回合能否落子
-
在非己方回合能否落子
1.4.2 游戏结束
-
一方横轴五子连珠是否获胜
-
一方竖轴五子连珠是否获胜
-
一方正对角线五子连珠是否获胜
-
一方斜对角线五子连珠是否获胜
-
对手掉线时是否直接判胜
2. 自动化测试
2.1 创建浏览器驱动类
package com.example.java_gobang.common;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
/**
* @author hanzishuai
* Blog : https://blog.csdn.net/qrwitu142857 [原文地址,请尊重原创]
* @date 2025/4/20 22:22
* @Description
*/
public class Utils {
public static WebDriver driver = null;
public WebDriverWait wait = null;
/**
* Created by hanzishuai on 2025/4/20
*
* @param
* @return void
* @Description 创建 Driver
*/
private WebDriver createChromeDriver() {
if (driver == null) {
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
driver = new ChromeDriver(options);
// 隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
}
return driver;
}
private WebDriver createEdgeDriver() {
if (driver == null) {
WebDriverManager.edgedriver().setup();
EdgeOptions options = new EdgeOptions();
options.addArguments("--remote-allow-origins=*");
driver = new EdgeDriver(options);
// 隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
}
return driver;
}
public Utils(String url) {
driver = createChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(2));
driver.get(url);
}
public Utils(String url, BrowserName browserName) {
if (browserName.getBrowserName().equals(BrowserName.EDGE.getBrowserName())) {
driver = createEdgeDriver();
} else if (browserName.getBrowserName().equals(BrowserName.CHROME.getBrowserName())) {
driver = createChromeDriver();
}
wait = new WebDriverWait(driver, Duration.ofSeconds(2));
driver.get(url);
}
/**
* Created by hanzishuai on 2025/4/20
*
* @param str 截图名称的前缀
* @return
* @Description 屏幕截图
*/
public void screenShot(String str) throws IOException {
// 设置文件名和图片名称格式
SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");
String dirTime = sim1.format(System.currentTimeMillis());
String fileTime = sim2.format(System.currentTimeMillis());
String fileName = "src/test/java/com/example/java_gobang/images/" + dirTime + "/" + str + "_" + fileTime + ".png";
// 截图
File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile, new File(fileName));
}
}
2.2 注册页面测试
package com.example.java_gobang.tests;
import com.example.java_gobang.common.BrowserName;
import com.example.java_gobang.common.Utils;
import lombok.SneakyThrows;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.util.UUID;
/**
* @author hanzishuai
* Blog : https://blog.csdn.net/qrwitu142857
* @date 2025/5/11 22:16
* @Description
*/
public class RegisterPage extends Utils {
public static final String url = "http://101.201.246.67:58080/register.html";
public RegisterPage() {
super(url);
}
public RegisterPage(BrowserName browserName) {
super(url, browserName);
}
/**
* Created by hanzishuai on 2025/5/11
*
* @Description 检查注册页面是否加载完毕
*/
@SneakyThrows
public void checkRegisterPageRight() {
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
screenShot("checkRegisterPageRight");
}
private void register(String username, String password) {
// 将输入框清空
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
// 输入账号密码,并点击提交
if (username != null) {
driver.findElement(By.cssSelector("#username")).sendKeys(username);
}
if (password != null) {
driver.findElement(By.cssSelector("#password")).sendKeys(password);
}
driver.findElement(By.cssSelector("#submit")).click();
}
@SneakyThrows
public void registerFail() {
// 不输入账号和密码,点击提交
register(null, null);
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
Alert alert = driver.switchTo().alert();
String text = alert.getText();
assert text.equals("注册失败!");
// 点击确定
alert.accept();
// 截图
screenShot("registerFail");
// 输入账号,不输入密码,点击提交
register("awa1", null);
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("注册失败!");
// 点击确定
alert.accept();
// 截图
screenShot("registerFail");
// 不输入账号,输入密码,点击提交
register(null, "123");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("注册失败!");
// 点击确定
alert.accept();
// 截图
screenShot("registerFail");
// 输入已注册的账号,输入正确的密码,点击提交
register("awa", "123456");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("注册失败!");
// 点击确定
alert.accept();
// 截图
screenShot("registerFail");
}
@SneakyThrows
public void registerSuccess() {
String username = UUID.randomUUID().toString().replace("-", "").substring(0,7);
register(username, "123");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
Alert alert = driver.switchTo().alert();
String text = alert.getText();
assert text.equals("注册成功!");
// 点击确定
alert.accept();
// 截图
screenShot("registerSuccess");
// 注册成功会跳转到登录页面
String text1 = driver.findElement(By.cssSelector("body > div.login-container > div.login-dialog > h3")).getText();
assert "登录".equals(text1);
}
}
2.3 登录页面测试
package com.example.java_gobang.tests;
import com.example.java_gobang.common.BrowserName;
import com.example.java_gobang.common.Utils;
import lombok.SneakyThrows;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
/**
* @author hanzishuai
* Blog : https://blog.csdn.net/qrwitu142857
* @date 2025/5/9 11:04
* @Description
*/
public class LoginPage extends Utils {
public static final String url = "http://101.201.246.67:58080/login.html";
public LoginPage() {
super(url);
}
public LoginPage(BrowserName browserName) {
super(url, browserName);
}
/**
* Created by hanzishuai on 2025/4/21
*
* @param
* @return void
* @Description 检查页面是否可以正常打开
*/
@SneakyThrows
public void checkLoginPageRight() {
// 检查登录框是否加载成功
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
// 截图
screenShot("checkPageRight");
}
private void login(String username, String password) {
// 将输入框清空
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
// 输入账号密码,并点击提交
if (username != null) {
driver.findElement(By.cssSelector("#username")).sendKeys(username);
}
if (password != null) {
driver.findElement(By.cssSelector("#password")).sendKeys(password);
}
driver.findElement(By.cssSelector("#submit")).click();
}
@SneakyThrows
public void loginFail() {
// 不输入账号和密码,点击提交
login(null, null);
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
Alert alert = driver.switchTo().alert();
String text = alert.getText();
assert text.equals("登录失败!");
// 点击确定
alert.accept();
// 截图
screenShot("LoginFail");
// 输入账号,不输入密码,点击提交
login("awa", null);
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("登录失败!");
// 点击确定
alert.accept();
// 截图
screenShot("LoginFail");
// 不输入账号,输入密码,点击提交
login(null, "123");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("登录失败!");
// 点击确定
alert.accept();
// 截图
screenShot("LoginFail");
// 输入账号,输入错误的密码,点击提交
login("awa", "12");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
alert = driver.switchTo().alert();
text = alert.getText();
assert text.equals("登录失败!");
// 点击确定
alert.accept();
// 截图
screenShot("LoginFail");
}
@SneakyThrows
public void loginSuccess() {
login("awa", "123456");
// 等待弹窗出现
wait.until(ExpectedConditions.alertIsPresent());
// 处理弹窗
Alert alert = driver.switchTo().alert();
String text = alert.getText();
assert text.equals("登录成功!");
// 点击确定
alert.accept();
// 截图
screenShot("LoginSuccess");
// 如果登录成功会进入游戏大厅页面
driver.findElement(By.cssSelector("#match-button"));
}
}
2.4 游戏大厅页面测试
package com.example.java_gobang.tests;
import com.example.java_gobang.common.BrowserName;
import com.example.java_gobang.common.Utils;
import lombok.SneakyThrows;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
/**
* @author hanzishuai
* Blog : https://blog.csdn.net/qrwitu142857
* @date 2025/5/11 22:28
* @Description
*/
public class GameHallPage extends Utils {
public static final String url = "http://101.201.246.67:58080/game_hall.html";
public GameHallPage() {
super(url);
}
public GameHallPage(BrowserName browserName) {
super(url, browserName);
}
@SneakyThrows
public void checkGameHallPageRight() {
driver.findElement(By.cssSelector("#screen"));
driver.findElement(By.cssSelector("#match-button"));
screenShot("checkGameHallPageRight");
}
@SneakyThrows
public void startMatch() {
WebElement button = driver.findElement(By.cssSelector("#match-button"));
button.click();
String text = button.getText();
assert "匹配中...(点击停止)".equals(text);
screenShot("startMatch");
}
@SneakyThrows
public void stopMatch() {
WebElement button = driver.findElement(By.cssSelector("#match-button"));
button.click();
String text = button.getText();
assert "开始匹配".equals(text);
screenShot("stopMatch");
}
}
2.5 自动化测试视频
黑白浮生项目自动化测试
四、附件
摘要: