How to Test a Teacher‑Student Chat Socket API with Groovy Scripts
This article walks through building and executing a Groovy‑based test script that registers two users, joins a room, exchanges chat messages over a Socket (WebSocket) connection, and cleanly closes the sockets, illustrating the full workflow and code structure for backend socket API testing.
After completing the Socket protocol interface debugging, the author proceeds to business testing of the Socket interface for a teacher‑student chat feature, using two long‑connected users.
Idea
The workflow is:
HTTP login
Establish a long connection using token and
uid registerthe long‑connection user join a room
Send messages
Close the Socket The author discovered that multithreading is unnecessary; a simple sleep(second) followed by closeAll() suffices.
Structure
The implementation is divided into three classes:
Configuration class – holds environment settings (no detailed discussion).
Base functionality class – written in Groovy, encapsulates JSON command generation.
Script class – drives the test scenario.
Base Functionality Class
Provides static methods that build JSON commands for registration, room joining, chat, and screen status.
package com.okayqa.socket.base;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fun.frame.SourceCode;
/**
* socket base class
*/
class SocketBase extends SourceCode {
/**
* Register
* @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}\"}");
}
/**
* Join room
* @param roomId
* @return
*/
public static JSONObject getJoinRoom(int roomId) {
JSON.parseObject("{\"cmd\": \"joinRoom\", \"roomId\": ${roomId}}");
}
/**
* Chat
*/
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\"}\"}});
}
/**
* Screen status
* @param actitiviId
* @param status (0: none, 1: control screen, 2: lock screen)
*/
public static JSONObject getScreenStatus(int actitiviId, int status) {
JSON.parseObject("{\"cmd\":\"screenStatus\", \"activityId\":${actitiviId}, \"minicourseId\":int, \"status\":${status}}");
}
}Script Class
Creates teacher and student clients, connects them, registers, joins a room, exchanges chat messages, waits, then closes all sockets.
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();
}
}Console Output
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 0An image below shows a portion of the console log.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
