Socket.IO接口多用户测试实践

完成Socket协议接口的调试之后,下一步继续进行Socket接口的业务测试了。因为目前接到的需求是一个老师跟学生相互聊天的功能,所以必须通过两个用户的长连接进行测试,经过一些尝试和修改,基本脚本已经完成,分享如下,仅供参考。

之前的Socket相关文章:

思路

目前业务逻辑顺序如下:

  • HTTP登录
  • 通过tokenuid建立长连接
  • register长连接用户
  • join房间
  • 发送消息
  • 关闭Socket

本来计划通过两个线程来完成,后来发现这个跟WebSocket还是有区别的,完全不需要多线程也可以完成测试。最后步骤里面通过sleep(second)closeAll()两个方法配合即可。

结构

分成了三个类:

  • 配置类
  • 基础功能类
  • 脚本

配置类主要存放配置信息的,进行多环境配置的,没啥可讲的。基础功能类,主要是完成对各类的发送对象的封装,我用了Groovy写的,因为太爽了,各位可以看看代码就知道了。脚本类就是编写各类测试脚本,提供测试和造数据功能。

由于对改项目Socket不太熟悉,尚未进行项目优化,后期封装会取消脚本里面的常量参数,更加方便测试。

代码

省略了配置类,因为实在没东西可说的。

基础功能类

目前只做了一部分的,还有大量功能需要跟进。

package com.okayqa.socket.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fun.frame.SourceCode;

/**
 * socket基础类
 */
class SocketBase extends SourceCode {

    /**
     * 注册
     *
     * @param uid
     * @param token
     * @param isS
     * @return
     */
    public static JSONObject getRegister(long uid, String token, boolean isS) {
        JSON.parseObject("{\"cmd\": \"register\", \"userId\": ${uid}, \"role\": \"${isS ? "S" : "T"}\", \"deviceVersion\": \"1.0\", \"s_sid\": 123, \"token\": \"${token}\"}");
    }

    /**
     * 加入房间
     *
     * @param roomId
     * @return
     */
    public static JSONObject getJoinRoom(int roomId) {
        JSON.parseObject("{\"cmd\": \"joinRoom\", \"roomId\": ${roomId}}")
    }

    /**
     * 聊天
     *
     * @param activity_id
     * @param from
     * @param to
     * @param kid
     * @param ktype
     * @param msg
     * @param S2T
     * @return
     */
    public static JSONObject getChat(int activity_id, long from, long to, int kid, int ktype, String msg, boolean S2T) {
        JSON.parseObject("{\"cmd\":\"chat\",\"message\":{\"sender\":${from},\"receiver\":${to},\"body\":\"${msg}\",\"msgtype\":\"chat\",\"mimetype\":\"text\",\"kid\":${kid},\"ktype\":${ktype},\"activity_id\":${activity_id},\"sender_name\":\"SENDER_NAME\",\"sender_role\":\"${S2T ? "student" : "teacher"}\",\"receiver_name\":\"RECEIVER_NAME\",\"receiver_role\":\"${S2T ? "student" : "teacher"}\"}}")

    }

    /**
     * @param actitiviId
     * @param status     status为0无状态,1控屏,2锁屏
     * @return
     */
    public static JSONObject getScreenStatus(int actitiviId, int status) {
        JSON.parseObject("{\"cmd\":\"screenStatus\", \"activityId\":${actitiviId}, \"minicourseId\":int,\"status\":${status}")
    }

}

脚本类

只写了一个老师与学生之间的聊天逻辑测试脚本,提供给各位参考。

package com.okayqa.socket.test


import com.fun.frame.socket.ScoketIOFunClient
import com.fun.utils.Time
import com.okayqa.socket.base.SocketBase
import com.okayqa.socket.profile.OkayScoketConstant
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * wiki:http://wiki.okjiaoyu.cn/display/RJBK/ailearn-instruction-svr
 */
class ST extends SocketBase {

    private static Logger logger = LoggerFactory.getLogger(ST.class)

    static int roomId = 42422;

    static int activity_id = roomId;

    public static void main(String[] args) {

        def tbase = com.okayqa.teacherpad.base.OkayBase.getBase()
        def sbase = com.okayqa.studentpad.base.OkayBase.getBase()

        ScoketIOFunClient teacher = ScoketIOFunClient.getInstance(OkayScoketConstant.HOST + "/?systemId=${tbase.getUid()}&loginType=3&token=${tbase.getToken()}&userType=1", "老师${tbase.getUid()}");
        teacher.connect();
        teacher.addEventListener(OkayScoketConstant.RESPONSE, { objects ->
            String s = ScoketIOFunClient.initMsg(objects);
            logger.info("{} 收到响应:{}", teacher.getCname(), s);
        });

        ScoketIOFunClient student = ScoketIOFunClient.getInstance(OkayScoketConstant.HOST + "/?systemId=${sbase.getUname()}&loginType=3&token=${sbase.getToken()}&userType=2", "学生${sbase.getUname()}");
        student.connect();
        student.addEventListener(OkayScoketConstant.RESPONSE, { objects ->
            String s = ScoketIOFunClient.initMsg(objects);
            logger.info("{} 收到响应:{}", student.getCname(), s);
        });

        teacher.send(OkayScoketConstant.EVENT, getRegister(tbase.getUid(), tbase.getToken(), false));
        teacher.send(OkayScoketConstant.EVENT, getJoinRoom(roomId));
        student.send(OkayScoketConstant.EVENT, getRegister(sbase.getUname() as long, sbase.getToken(), true));
        student.send(OkayScoketConstant.EVENT, getJoinRoom(roomId));



        teacher.send(OkayScoketConstant.EVENT, getChat(activity_id, tbase.getUid(), sbase.getUname() as long, 82, 0, "猜猜我是谁" + Time.getDate(), false));
        student.send(OkayScoketConstant.EVENT, getChat(activity_id, sbase.getUname() as long, tbase.getUid(), 82, 0, "猜猜我是谁" + Time.getDate(), true));



        sleep(10_000);

        logger.info("脚本完成!")
        ScoketIOFunClient.closeAll()
    }


}

控制台

INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/okay_test/,系统编码格式:UTF-8,系统Mac OS X版本:10.15.7
INFO-> requestid: Fdev1606988150561
INFO-> 请求uri:https://teacherpad-stress.xk12.cn/api/t_pad/user/login,耗时:910 ms
INFO-> 教师:61951375269,学科:null,名称:范老师零零零,登录成功!
INFO-> requestid: Fdev1606988151672
INFO-> 请求uri:https://stupad-stress.xk12.cn/api/pad/user/login,耗时:387 ms
INFO-> 用户:81951375949,登录成功!
INFO-> 老师61951375269 开始连接...
INFO-> 老师61951375269 连接成功!
INFO-> 学生81951375949 开始连接...
INFO-> 学生81951375949 连接成功!
······省去若干消息·····
INFO-> 脚本完成!
INFO-> 老师61951375269 socket链接关闭!
INFO-> 学生81951375949 socket链接关闭!
INFO-> 关闭所有Socket客户端!

Process finished with exit code 0

由于消息返回太多了,只截个图看一下就好。

Socket.IO接口测试


公众号FunTester,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。

FunTester热文精选