Automated Verification of Socket.IO Interfaces Using VerifyBean in Java/Groovy
This article describes how to automate verification of Socket.IO interfaces using a custom VerifyBean class in Java/Groovy, covering setup, message handling, cross‑validation logic, and includes full source code and sample console output.
The author explains the development of an automated testing script for Socket.IO interfaces, leveraging a multi‑functional JSON verification class called VerifyBean . Previously, socket responses were checked manually; the new approach validates responses programmatically.
Background links to earlier articles on socket interface development, WebSocket client encapsulation, Socket.IO client encapsulation, multi‑user testing practices, and the JSON verification class are provided for reference.
A note on Groovy operator overloading ( == ) highlights a subtle bug where equality checks may invoke Java's equals method when the code is packaged as a JAR, causing unexpected behavior and requiring debugging.
Source code for the test script is presented in full, showing how the teacher logs in, connects via a Socket , registers, joins and leaves a room, and then performs cross‑validation of received messages using two List collections and a 2‑second delay. The script utilizes the VerifyBean instances to define verification rules such as JSONPath matching and string containment.
package com.okayqa.socket.test
import com.fun.base.bean.VerifyBean
import com.fun.base.interfaces.ISocketVerify
import com.fun.frame.socket.ScoketIOFunClient
import com.okayqa.socket.base.SocketBase
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 = 43548;
static int activity_id = roomId;
public static void main(String[] args) {
def tbase = getTeaBase()
ScoketIOFunClient teacher = getSocket(tbase)
initAll()
registerAll()
joinRoom(roomId)
leaveRoom(roomId)
def sv = new SV(teacher)
def bean = new VerifyBean("jsonpath|$.cmd|=joinRoomResponse", EMPTY, "FunTester0")
def bean1 = new VerifyBean("contain|61951375269", EMPTY, "FunTester1")
sv.addVerify(bean)
sv.addVerify(bean1)
sleep(2.0);
def thread = new Thread(sv)
thread.start()
logger.info("脚本完成!")
thread.join()
output(sv.vs*.result)
sv.vs.each {it.print()}
ScoketIOFunClient.closeAll()
}
static class SV implements ISocketVerify {
List
vs = new ArrayList<>()
ScoketIOFunClient client
SV(ScoketIOFunClient client) { this.client = client }
@Override void initMsg(List
list) {}
@Override boolean verify() { return false }
@Override void addVerify(VerifyBean verifyBean) { vs << verifyBean }
@Override void remoreVerify(VerifyBean verifyBean) { vs.remove(verifyBean) }
@Override void removeAllVerify() { vs.clear() }
@Override void saveResult() {}
@Override void run() {
synchronized (client.msgs) {
client.msgs.each { x ->
vs.each { v ->
def s = x.substring(1, x.length() - 1)
v.setValue(s)
v.verify()
}
}
}
}
}
}The console output demonstrates the sequence of login, socket connection, registration, room join/leave, and the verification results for each VerifyBean instance, confirming successful validation of both the response command and the teacher ID.
INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/okay_test/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> requestid: Fdev16092381258113
INFO-> 请求uri:https://teach***.cn/api/t_pad/user/login,耗时:984 ms
INFO-> 教师:61951375269,学科:null,名称:范老师零零零,登录成功!
INFO-> Socket 连接: http://ailearn-***.cn:38899/?systemId=61951375269&loginType=3&token=2cc340d010af4fd3a22be276cf2ebec3&userType=1,客户端名称: 老师:61951375269
INFO-> 老师:61951375269 开始连接...
INFO-> 老师:61951375269 连接成功!
INFO-> 老师:61951375269 收到响应:[{"msg":"","code":0,"data":{"role":"T","s_sid":123,"deviceVersion":"1.0","userId":61951375269,"token":"2cc340d010af4fd3a22be276cf2ebec3"},"cmd":"registerResponse"}]
INFO-> 老师:61951375269 收到响应:[{"msg":"","code":0,"data":{"roomId":43548},"cmd":"joinRoomResponse"}]
INFO-> 老师:61951375269 收到响应:[{"msg":"","code":0,"data":{},"cmd":"leaveRoomResponse"}]
INFO-> 脚本完成!
INFO-> verify对象: registerResponse,匹配的字符串: =joinRoomResponse
INFO-> verify对象 $.cmd|=joinRoomResponse ,验证结果: false
INFO-> verify对象 61951375269 ,验证结果: true
INFO-> verify对象: joinRoomResponse,匹配的字符串: =joinRoomResponse
INFO-> verify对象 $.cmd|=joinRoomResponse ,验证结果: true
INFO-> 第1个: true
INFO-> 第1个: true
INFO-> FunTester0 验证结果: true
INFO-> FunTester1 验证结果: true
INFO-> 老师:61951375269 socket链接关闭!
INFO-> 关闭所有Socket客户端!
Process finished with exit code 0Finally, the author invites readers to explore the GitHub/Gitee repositories for the latest code and to join discussions about automated socket testing.
FunTester
10k followers, 1k articles | completely useless
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.