【萌笔趣棋】网页五子棋项目测试报告

目录

一.项目介绍 

(一)项目简介

(二)功能介绍

(三)页面展示

1.注册页面

2.登录页面

3.游戏大厅页面

4.游戏房间页面(对战)

二.功能测试

(一)出现的bug

 (二)解决方法

三.自动化测试

(一)测试用例设计

(二)测试准备

(三)编写测试脚本

1.工具类

2.注册功能

3.登录测试

3.“游戏大厅”测试

4.“游戏房间”测试

5.驱动退出和测试套件类

(四)测试结果

四.性能测试

例子

五.总结

一.项目介绍 

此项目的开发文章跳转:【萌笔趣棋】项目开发-优快云博客

(一)项目简介

“新酱爱玩的五子棋” 是一款以《蜡笔小新》春日部角色为主题背景的五子棋游戏。该游戏基于网页端开发,通过简洁易懂的界面设计,为玩家提供经典五子棋的对战体验,融合了趣味性与竞技性,目标用户主要为喜爱五子棋和《蜡笔小新》动漫的人群。

(二)功能介绍

  1. 注册页面:玩家可在此页面输入自定义的用户名和密码进行账号注册。系统会对输入信息进行验证,确保用户名的唯一性等,成功注册后可获得在游戏中进行对战的资格。
  2. 登录页面:已注册玩家输入正确的用户名和密码登录游戏。登录成功后,可进入游戏大厅开始游戏相关操作;若输入错误,系统会提示重新输入。
  3. 游戏大厅:玩家登录后进入游戏大厅,可查看自己的游戏信息,包括用户名、当前分数、比赛场次和获胜场次等。点击 “开始匹配” 按钮,系统会自动为玩家寻找对战对手,在匹配过程中可点击取消匹配。
  4. 游戏房间:匹配成功后进入游戏房间,玩家和对手在此进行五子棋对战。游戏界面会显示棋盘,玩家按规则轮流落子。当一方率先在棋盘的横线、竖线或斜线上形成连续的五个棋子时,判定为获胜方,系统会显示胜负结果,并更新玩家在游戏大厅中的相关数据(如分数、比赛场次、获胜场次等) 。

(三)页面展示

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:用户登录性能测试

此处比较简答,省略

场景 2:并发匹配性能测试

目标:验证 “开始匹配” 接口在高并发下的响应速度、匹配成功率及超时机制有效性。

步骤:

场景 3:WebSocket 落子消息性能测试

目标:验证匹配成功后,双方实时落子的消息延迟与可靠性。

场景 4:用户数据更新性能测试

目标:验证匹配结束后,用户分数、场次等数据更新的并发处理能力与准确性。

五.总结

功能测试保障软件功能正常、无缺失和错误,让用户有预期体验;性能测试确保软件在不同负载下响应及时、不卡顿崩溃,评估承载能力;自动化测试提升效率、降成本、保准确一致,在开发流程中及时发现问题,稳定软件质量。

### 使用Postman测试阁API接口 #### 1. 准备工作 在开始测试之前,需要明确阁提供的API接口文档或URL地址。如果没有官方文档,可以通过抓包工具(如Fiddler、Charles)分析其请求路径和参数[^1]。假设我们已经获取到阁的API接口信息,例如搜索小说的接口为`https://api.biquge.com/search`。 #### 2. 配置Postman环境 - 打开Postman,点击“New”按钮创建一个新的请求。 - 在请求名称中输入一个有意义的名字,例如“Search Novels”。 - 设置请求类型为`GET`或`POST`,具体取决于阁API的实现方式[^2]。 #### 3. 构建请求 根据阁API的具体要求,配置以下内容: - **URL**: 输入API接口的完整URL地址,例如`https://api.biquge.com/search`。 - **Params**: 如果是`GET`请求,可以在Params选项卡中添加查询参数。例如,添加`keyword`参数用于搜索小说名称: ```plaintext Key: keyword Value: 斗破苍穹 ``` - **Headers**: 根据API文档,可能需要设置特定的请求头信息,例如`Content-Type`或`Authorization`。如果不确定,可以尝试默认值: ```plaintext Key: Content-Type Value: application/json ``` #### 4. 发送请求并查看响应 点击“Send”按钮发送请求,Postman会显示服务器返回的结果。通常包括以下几个部分: - **Status Code**: 表示请求的状态,例如`200 OK`表示成功。 - **Body**: 包含API返回的具体数据,通常是JSON格式。例如: ```json { "code": 200, "message": "success", "data": [ { "id": 12345, "title": "斗破苍穹", "author": "天蚕土豆" } ] } ``` #### 5. 自动化测试 如果需要对阁API进行自动化测试,可以使用Postman的集合功能。创建一个新的Collection,并将上述请求添加到其中。然后通过Postman的 Newman CLI 或者内置的 Runner 工具运行测试集合[^2]。 ```python # 示例代码:使用Python调用阁API(供参考) import requests url = "https://api.biquge.com/search" params = {"keyword": "斗破苍穹"} headers = {"Content-Type": "application/json"} response = requests.get(url, params=params, headers=headers) print(response.json()) ``` #### 6. 注意事项 - 确保API接口的URL和参数正确无误。 - 如果API需要认证,可能需要在Headers中添加`Authorization`字段[^3]。 - 测试过程中遇到问题时,可以参考Postman社区或相关文档。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值