网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究

马肤

温馨提示:这篇文章已超过465天没有更新,请注意相关的内容是否还可用!

摘要:本文介绍了网页版五子棋对战的实现和自动化测试。五子棋对战作为一种经典的策略游戏,通过网页版可以实现多人在线对战,提高了游戏的互动性和趣味性。在实现过程中,需要关注游戏逻辑、界面交互等方面的设计。为了确保游戏的质量和稳定性,需要进行自动化测试,包括功能测试、性能测试等。通过自动化测试,可以及时发现并修复潜在的问题,提高游戏的用户体验。

文章目录

  • 前言
  • 一、项目描述
    • 项目演示链接
    • 二、实现的功能与操作
      • 1.登录注册
      • 2.游戏大厅
        • 线程安全问题
        • 多开处理
        • 3.五子棋对战
        • 三、项目测试
          • 1.测试用例
          • 2.测试技术点
          • 3.部分测试用例展示
            • (1)注册页面
            • (2)登录页面
            • (3)游戏大厅页面
            • (4)游戏对战页面
            • 4.项目测试的结果
              • 视频演示链接
              • 总结

                前言

                五子棋对战网页应用是一个基于Web技术的在线多人五子棋游戏。该应用提供了用户注册、登录、匹配对手、对战等功能,旨在为用户提供轻松愉快的游戏体验。本篇文章主要用来记录我的网页版五子棋项目,包括项目介绍、实现功能、测试用例、自动化测试等。


                一、项目描述

                该项目支持玩家随时随地与其他在线玩家进行五子棋对战,实现实时的棋局同步和即时通讯。利用 WebSocket 技术实现双向通信,保证游戏过程中的实时性和即时交互,提供更流畅的游戏体验。 提供游戏大厅,展示在线玩家信息、排名和当前对局状态。内置匹配系统,自动匹配合适的对手,确保玩家能够享受到公平有趣的游戏。

                技术栈:

                前端: 使用HTML5、CSS3、JavaScript以及现代前端框架(如React、Vue等)构建直观、响应式的用户界面。

                后端: 基于Spring MVC、Spring Boot等后端框架,使用WebSocket实现实时通信,处理用户认证、游戏逻辑和数据存储。

                数据库: 使用关系型数据库MySQL存储用户信息、对战历史等数据。

                实时通信: 使用WebSocket技术,实现玩家之间的实时通信和对战同步。

                webSocket:是一个应用层协议。四个核心点:建立连接之后、收到消息之后、出现连接异常、出现连接关闭。客户端通过webSocket.send()发送消息,服务器使用sendMessage()发送消息。

                项目演示链接

                二、实现的功能与操作

                现在已实现注册登录功能、游戏匹配功能、下棋功能。

                1.登录注册

                登录主要是判定用户是不是合法登录;注册这一块比登录多一个确认密码,以及注册的这个人是不是在数据库中存在。

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第1张后端代码如下(示例):

                    @RequestMapping("/login")
                    public Object login(HttpServletRequest request, String username, String password) {
                        // 1.从数据库中找到匹配用户
                        User user = userMapper.selectByName(username);
                        System.out.println("当前登录用户:user=" + user);
                        if (user == null || !user.getPassword().equals(password)) {
                            // 登录失败
                            System.out.println("登录失败!");
                            return new User();
                        }
                        HttpSession httpSession = request.getSession(true);
                        httpSession.setAttribute("user", user);
                        return user;
                    }
                    @RequestMapping("/register")
                    public Object register(String username, String password) {
                        try {
                            User user = new User();
                            user.setUsername(username);
                            user.setPassword(password);
                            userMapper.insert(user);
                            return user;
                        } catch (org.springframework.dao.DuplicateKeyException e) {
                            User user = new User();
                            return user;
                        }
                    }
                

                注册前端代码(示例):

                    
                        function mysub() {
                            var username = jQuery("#username");
                            var password = jQuery("#password");
                            var password2 = jQuery("#password2");
                            if(username.val()=="") {
                                alert("请先输入用户名!");
                                username.focus();
                                return;
                            }
                            if(password.val()=="") {
                                alert("请先输入密码!");
                                password.focus();
                                return;
                            }
                            if(password2.val()=="") {
                                alert("请确认密码!");
                                password2.focus();
                                return;
                            }
                            if(password2.val()!=password.val()) {
                                alert("两次密码输入不一致!");
                                password.focus();
                                return;
                            }
                            jQuery.ajax({
                                url:"/user/register",
                                type:"POST",
                                data:{"username":username.val(),"password":password.val()},
                                success:function(result) {
                                    if(result && result.username) {
                                        if(confirm("恭喜:注册成功,是否跳转到登录页面?")) {
                                            location.href = "/login.html";
                                        }
                                    }else {
                                        alert("抱歉:注册失败,请重试!");
                                    }
                                }
                            });
                        }
                    
                

                2.游戏大厅

                游戏大厅需要先实现其大厅页面,里面包括玩家信息、开始匹配按钮,而最重要的则是一旦玩家点击开始匹配之后,需要给该按钮添加一个点击事件,这里就涉及我们的核心:游戏匹配,我们创建了两个个优先级队列,玩家登录成功将该玩家加入进一个玩家在线的HashMap,玩家点击匹配按钮后,将其加入另一个表示游戏匹配的HashMap。这里的我们需要考虑线程安全问题和多开问题。实现思路如下图所示:

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第2张

                游戏匹配后端代码如下(示例):

                    // 建立连接之后
                    @Override
                    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                        // 玩家上线,加入到onlineUserManager
                        try {
                            //1.先获取当前用户的身份信息
                            // webSocketSession通过addInterceptors获取httpsession中的Attributes
                            User user = (User) session.getAttributes().get("user");
                            //2.判定当前用户是否是已经在线状态
                            if (onlineUserManager.getFromGameHall(user.getUserId()) != null
                                    || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                                //说明当前用户已经登录!
                                //告知客户端重复登录
                                MatchResponse response = new MatchResponse();
                                response.setOk(true);
                                response.setReason("当前禁止多开!");
                                response.setMessage("repeatConnection");
                                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                                // 直接关闭有些太激进
                                //session.close();
                                return;
                            }
                            //3.将玩家设置为在线状态
                            onlineUserManager.enterGameHall(user.getUserId(), session);
                            System.out.println("玩家:" + user.getUsername() + " 进入游戏大厅!");
                        } catch (NullPointerException e) {
                            System.out.println("[MatchAPI.afterConnectionEstablished]当前用户未登录");
                        }
                    }
                    // 处理传输信息
                    @Override
                    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
                        // 处理开始匹配请求和处理停止匹配请求
                        User user = (User) session.getAttributes().get("user");
                        // 获取客户端发送给服务器的数据
                        String payload = message.getPayload();
                        // 将JSON搁置的字符串,转换为对象
                        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
                        MatchResponse response = new MatchResponse();
                        if (request.getMessage().equals("startMatch")) {
                            //(1)进入匹配队列
                            //(2)创建一个类表示匹配队列,把当前用户加进去
                            matcher.add(user);
                            response.setOk(true);
                            response.setMessage("startMatch");
                        } else if (request.getMessage().equals("stopMatch")) {
                            // (1)退出匹配队列
                            // (2)创建一个类表示匹配队列,把当前用户从队列中移除
                            matcher.remove(user);
                            // 移除之后,返回一个响应给客户端
                            response.setOk(true);
                            response.setMessage("stopMatch");
                        } else {
                            // 非法情况
                            response.setOk(false);
                            response.setReason("非法的匹配请求");
                        }
                        String jsonString = objectMapper.writeValueAsString(response);
                        session.sendMessage(new TextMessage(jsonString));
                    }
                    // 处理传输异常
                    @Override
                    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                        // 玩家下线,从 onlineUserManager 中删除
                        try {
                            User user = (User) session.getAttributes().get("user");
                            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
                            // 保证退出的人和登录的人是一个人
                            if (tmpSession == session) {
                                onlineUserManager.exitGameHall(user.getUserId());
                                System.out.println("玩家:" + user.getUsername() + " 退出游戏大厅!");
                            }
                            // 如果玩家正在匹配中,而 websocket 连接断开
                            matcher.remove(user);
                        } catch (NullPointerException e) {
                            System.out.println("[MatchAPI.handleTransportError]当前用户未登录");
                        }
                    }
                	// 处理传输关闭
                    @Override
                    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
                        try {
                            // 玩家下线,从 onlineUserManager 中删除
                            User user = (User) session.getAttributes().get("user");
                            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
                            // 保证退出的人和登录的人是一个人
                            if (tmpSession == session) {
                                onlineUserManager.exitGameHall(user.getUserId());
                                System.out.println("玩家:" + user.getUsername() + " 退出游戏大厅!");
                            }
                            // 如果玩家正在匹配中,而 websocket 连接断开
                            matcher.remove(user);
                        } catch (NullPointerException e) {
                            System.out.println("[MatchAPI.afterConnectionClosed]当前用户未登录");
                        }
                    }
                

                线程安全问题

                我们对玩家进入游戏使用的是一个HashMap,玩家点击匹配按钮后,被加入另一个HashMap,而我们的系统涉及多个用户同时使用,则多线程访问同一个HashMap容易产生线程安全问题,这里我们将HashMap改为ConcurrentHashMap来处理线程安全问题,ConcurrentHashMap是线程安全的,它通过使用锁分段(segmented-locking)技术来提高并发访问性能。它允许多个修改操作并发进行,而不会导致数据不一致。

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第3张

                多开处理

                (1)一个账户多个地方登录,那这种对于我们系统是不允许存在的,我们通过seesion判断当前用户是否存在,并且不允许一个客户端同时匹配两个用户。

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第4张

                (2)我的用户是按照分数划分为三个梯队,由于 handlerMatch 是在单独的线程中调用,因此要考虑到访问队列的线程安全问题.,需要加上锁。

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第5张

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第6张

                3.五子棋对战

                当游戏匹配已经有两个或两个以上的玩家,则会匹配成功进入同一个游戏房间,进行游戏对战。进入到游戏房间,这里的棋盘我们是用canvas画上去的,双方下棋的时候,使用websocket给双方用户通知提示当前对手信息,重写websocket四个核心方法,也要判断游戏输赢后通知给玩家。实现过程如下图所示:

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第7张

                重写websocket的四个核心方法,并实现通知玩家谁输谁赢的方法noticeThatUserWin。

                游戏对战后端代码如下(示例):

                Override
                    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                        GameReadyResponse response = new GameReadyResponse();
                        // 1.先获取到用户的身份信息,(从httpsession中拿到当前用户的对象)
                        User user = (User) session.getAttributes().get("user");
                        if (user == null) {
                            response.setOk(false);
                            response.setReason("用户尚未登录!");
                            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                            return;
                        }
                        // 2.判断当前用户是否已经进入房间
                        Room room = roomManager.getRoomByUserId(user.getUserId());
                        if (room == null) {
                            // 该玩家还没有匹配到对手,不应该进入房间
                            response.setOk(false);
                            response.setReason("用户尚未匹配到!");
                            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                            return;
                        }
                        // 3.判断当前是不是多开用户
                        if (onlineUserManager.getFromGameHall(user.getUserId()) != null
                                || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                            response.setOk(true);
                            response.setReason("禁止多开游戏页面");
                            response.setMessage("repeatConnection");
                            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                            return;
                        }
                        // 4.设置当前玩家上线
                        onlineUserManager.enterGameRoom(user.getUserId(), session);
                        // 5.把两个玩家加入到游戏房间中
                        synchronized (room) {
                            if (room.getUser1() == null) {
                                room.setUser1(user);
                                // 把先连入房间的玩家作为先手方
                                room.setWhiteUser(user.getUserId());
                                System.out.println("玩家1:" + user.getUsername() + " 进入游戏房间,已经准备就绪!");
                                return;
                            }
                            if (room.getUser2() == null) {
                                // 进入到这里说明user1已经进入房间
                                room.setUser2(user);
                                System.out.println("玩家2:" + user.getUsername() + " 进入游戏房间,已经准备就绪!");
                                // 两个玩家就绪后
                                // 通知玩家1
                                noticeGameReady(room, room.getUser1(), room.getUser2());
                                // 通知玩家2
                                noticeGameReady(room, room.getUser2(), room.getUser1());
                                return;
                            }
                        }
                        // 6.此处如果又有玩家尝试连接同一个房间(理论上是不存在的)
                        response.setOk(false);
                        response.setReason("当前房间已满,您不能加入房间!");
                        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                    }
                    private void noticeGameReady(Room room, User thisUser, User thatUser) throws IOException {
                        GameReadyResponse resp = new GameReadyResponse();
                        resp.setOk(true);
                        resp.setReason("");
                        resp.setMessage("gameReady");
                        resp.setReason(room.getRoomId());
                        resp.setThisUserId(thisUser.getUserId());
                        resp.setThatUserId(thatUser.getUserId());
                        resp.setWhiteUser(room.getWhiteUser());
                        // 把当前的响应数据传回给对应的玩家
                        WebSocketSession webSocketSession = onlineUserManager.getFromGameRoom(thisUser.getUserId());
                        webSocketSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));
                    }
                    @Override
                    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
                        // 1.从session里拿到当前用户信息
                        User user = (User) session.getAttributes().get("user");
                        if (user == null) {
                            System.out.println("[handleTextMessage] 当前玩家尚未登录!");
                            return;
                        }
                        // 2.根据玩家id获取到房间对象
                        Room room = roomManager.getRoomByUserId(user.getUserId());
                        // 3.通过room对象来处理这次具体的请求
                        room.putChess(message.getPayload());
                    }
                    @Override
                    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                        User user = (User) session.getAttributes().get("user");
                        if (user == null) {
                            return;
                        }
                        WebSocketSession exitSession = onlineUserManager.getFromGameRoom(user.getUserId());
                        if (session == exitSession) {
                            onlineUserManager.exitGameRoom(user.getUserId());
                        }
                        System.out.println("当前用户:" + user.getUsername() + " 游戏房间连接异常!");
                        // 通知对手获胜了
                        noticeThatUserWin(user);
                    }
                    @Override
                    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
                        User user = (User) session.getAttributes().get("user");
                        if (user == null) {
                            return;
                        }
                        WebSocketSession exitSession = onlineUserManager.getFromGameRoom(user.getUserId());
                        if (session == exitSession) {
                            onlineUserManager.exitGameRoom(user.getUserId());
                        }
                        System.out.println("当前用户:" + user.getUsername() + " 离开游戏房间!");
                        // 通知对手获胜了
                        noticeThatUserWin(user);
                    }
                    // 判断输赢,并通知给玩家
                    private void noticeThatUserWin(User user) throws IOException {
                        // 1.根据当前玩家,找到玩家所在的房间
                        Room room = roomManager.getRoomByUserId(user.getUserId());
                        if (room == null) {
                            System.out.println("当前房间已经释放,无需通知对手!");
                            return;
                        }
                        // 2.根据房间找到对手
                        User thatUser = (user == room.getUser1()) ? room.getUser2() : room.getUser1();
                        // 3.找到对手的在线状态
                        WebSocketSession webSocketSession = onlineUserManager.getFromGameRoom(thatUser.getUserId());
                        if (webSocketSession == null) {
                            // 对手也掉线了
                            System.out.println("对手已经掉线,无需通知!");
                            return;
                        }
                        // 4.构造一个响应,通知对手,你是获胜方
                        GameResponse resp = new GameResponse();
                        resp.setMessage("putChess");
                        resp.setUserId(thatUser.getUserId());
                        resp.setWinner(thatUser.getUserId());
                        webSocketSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(resp)));
                        // 5.更新玩家分数信息
                        int winUserId = thatUser.getUserId();
                        int loseUserId = user.getUserId();
                        userMapper.userWin(winUserId);
                        userMapper.userLose(loseUserId);
                        // 6.释放房间对象
                        roomManager.remove(room.getRoomId(), room.getUser1().getUserId(), room.getUser2().getUserId());
                    }
                

                三、项目测试

                1.测试用例

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第8张

                2.测试技术点

                测试工具:Selenium4+Junit5

                (1)使用定位元素定位、元素操作(findElement、cssSelector、sendKeys)实现页面交互;

                (2)获取页面相关元素并使用断言(Assertions)判断元素或者文本信息与预期是否符合;

                (3)使用@BeforeEach、@BeforeAll、@AfterAll等注解降低代码冗余;

                (4)使用参数化方法,@CsvSource批量测试多组数据;

                (5)使用@Order注解,设置测试内部执行顺序;

                (7)使用套件(suit)将测试用例连起来,以便批量运行测试用例。

                3.部分测试用例展示

                (1)注册页面

                根据对注册页面的测试用例编写,分别对注册页面可否正常打开、注册失败、注册成功进行测试。

                这里写出测试注册成功的逻辑:

                1)首先,清空登录框,以防多组登录;

                2)使用参数测试,将CsvSource准备好的多组测试数据,使用cssSelector选择器选中输入框,用sendKey输入准备好的数据;

                3)输入完注册信息后,再选中登录按钮后用click点击注册按钮;

                4)由于点击注册按钮后会alert出一个弹窗提示,所以此时将driver切换到alert;

                5)切换到alert后,提取到弹窗信息,根据弹窗信息判断是否注册成功;

                6)注册成功后跳转到登录页面,此时使用写好的截图方法,记录下此刻。

                    @ParameterizedTest
                    @CsvSource({"刘云,123,1234"})
                    @Order(2)
                    public void registerFail(String name, String password, String password2) throws IOException {
                        //清空登录框,以防多组登录
                        driver.findElement(By.cssSelector("#username")).clear();
                        driver.findElement(By.cssSelector("#password")).clear();
                        driver.findElement(By.cssSelector("#password2")).clear();
                        //进行注册
                        driver.findElement(By.cssSelector("#username")).sendKeys(name);
                        driver.findElement(By.cssSelector("#password")).sendKeys(password);
                        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
                        driver.findElement(By.cssSelector("#submit")).click();
                        //driver转到alert
                        Alert alert = driver.switchTo().alert();
                        //获取弹窗中的提示信息
                        String actual = alert.getText();
                        if (actual.equals("请先输入用户名!")) {
                            System.out.println("用户名为空!");
                        } else if (actual.equals("请先输入密码!")){
                            System.out.println("密码为空!");
                        } else if (actual.equals("请确认密码!")) {
                            System.out.println("再次输入密码为空!");
                        } else if (actual.equals("两次密码输入不一致!")) {
                            System.out.println("两次密码不一致!");
                        } else if(actual.equals("抱歉:注册失败,请重试!")){
                            System.out.println("已有该用户,请重试!");
                        } else if(actual.equals("恭喜:注册成功,是否跳转到登录页面?")) {
                            System.out.println("注册成功,跳转到登录页面!");
                        } else {
                            System.out.println("注册异常!");
                        }
                        alert.accept();
                        getScreenShot(getClass().getName());
                    }
                

                (2)登录页面

                根据测试用例,我们对登录页面是否正常、登录失败、登录成功分别测试。

                这里写出测试登录失败的逻辑:

                1)清空登录框。防止多组登录;

                2)登录,使用cssSelector选择器和sendkeys输入文本,csvSource准备好测试数据;

                3)获取弹窗和弹窗中的提示信息;

                4)使用assertion判断实际信息和提示信息是否一致,一致则登录成功。

                    @ParameterizedTest
                    @CsvSource({"张三,1234"})
                    @Order(2)
                    public void loginFail(String name, String password) throws IOException {
                        //登录失败
                        try {
                            // 清空登录框,以防多组登录
                            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);
                            getScreenShot(getClass().getName());
                            driver.findElement(By.cssSelector("#submit")).click();
                            //获取警告框文本
                            String expect = "登录失败!";
                            Alert alert = driver.switchTo().alert();
                            String actual = alert.getText();
                            System.out.println(actual);
                            Assertions.assertEquals(expect, actual);
                            alert.accept();
                        } catch (TimeoutException e) {
                            System.out.println("登录失败:未出现警告框");
                        } catch (UnhandledAlertException e) {
                            System.out.println("警告框文本与预期不符:" + e.getMessage());
                        }
                    }
                

                (3)游戏大厅页面

                根据游戏大厅的测试用例,编写页面加载正常、检测用户登录、匹配按钮的测试代码。

                其匹配按钮的测试代码逻辑如下:

                1)由于点击匹配按钮需要是登录的状态下,所以先进行用户的登录;

                2)登录后点击匹配按钮;

                3)查看点击后的匹配按钮的状态是否发生变化;

                4)再次点击按钮;

                5)查看按钮是否恢复为开始匹配状态。

                    @Test
                    @Order(3)
                    public void isMatch() throws IOException, InterruptedException {
                        // 1.先登录
                        driver.get("http://127.0.0.1:8081/login.html");
                        driver.findElement(By.cssSelector("#username")).clear();
                        driver.findElement(By.cssSelector("#password")).clear();
                        driver.findElement(By.cssSelector("#username")).sendKeys("张三");
                        driver.findElement(By.cssSelector("#password")).sendKeys("123");
                        driver.findElement(By.cssSelector("#submit")).click();
                        // 2.进入到游戏大厅页面后,点击匹配按钮
                        driver.findElement(By.cssSelector("#match-button")).click();
                        // 3.获取点击匹配后的信息
                        String actual = "匹配中...(点击停止)";
                        getScreenShot(getClass().getName());
                        String clickAfter = driver.findElement(By.cssSelector("#match-button")).getText();
                        // 4.判断
                        Assertions.assertEquals(clickAfter, actual);
                        // 5.再次点击
                        driver.findElement(By.cssSelector("#match-button")).click();
                        String clickAgain = driver.findElement(By.cssSelector("#match-button")).getText();
                        // 6.判断
                        actual = "开始匹配";
                        Assertions.assertEquals(clickAgain, actual);
                        getScreenShot(getClass().getName());
                    }
                

                (4)游戏对战页面

                根据测试用例对游戏匹配成功后游戏对战页面进行测试,主要测试点是页面上的棋盘和显示屏元素。

                测试步骤:

                1)防止多开,创建两个浏览器驱动(edgeDriver、chromeDriver);

                2)分别在两个浏览器上登录不同的账户;

                3)登录成功后进入游戏大厅页面,分别点击开始匹配按钮;

                4)匹配成功后进入游戏对战页面,寻找棋盘和显示屏两个标志元素。

                    // 创建驱动
                    private static EdgeDriver edgeDriver = createEdgeDriver();
                    private static ChromeDriver chromeDriver = createChromeDriver();
                    // 将两个不同系统的用户匹配进同一游戏房间
                    public void userLogin() {
                        // user1
                        edgeDriver.get("http://127.0.0.1:8081/login.html");
                        edgeDriver.findElement(By.cssSelector("#username")).sendKeys("六1");
                        edgeDriver.findElement(By.cssSelector("#password")).sendKeys("123");
                        edgeDriver.findElement(By.cssSelector("#submit")).click();
                        // user2
                        chromeDriver.get("http://127.0.0.1:8081/login.html");
                        chromeDriver.findElement(By.cssSelector("#username")).sendKeys("王五");
                        chromeDriver.findElement(By.cssSelector("#password")).sendKeys("123");
                        chromeDriver.findElement(By.cssSelector("#submit")).click();
                        // user1和user2进同一游戏房间
                        edgeDriver.findElement(By.cssSelector("#match-button")).click();
                        chromeDriver.findElement(By.cssSelector("#match-button")).click();
                    }
                    /**
                     * 测试游戏对战页面
                     * 检查点:有棋盘、提示版元素
                     */
                    @Test
                    @Order(1)
                    public void testGameBoard() {
                        // 不同系统的两个用户匹配到同一个房间
                        userLogin();
                        // 测试游戏对战页面
                        edgeDriver.findElement(By.cssSelector("#chess"));
                        chromeDriver.findElement(By.cssSelector("#chess"));
                    }
                

                4.项目测试的结果

                视频演示链接

                网页版五子棋对战实现和自动化测试,网页版五子棋对战实现与自动化测试研究 第9张


                完整项目代码可联系博主。

                总结

                这篇文章记录了五子棋项目现在已实现的功能及web页面自动化测试,后续将对该项目扩充聊天功能(同一个房间的用户可以发送消息)及测试方法。


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码