在日常测试工作中,测试工程师经常会遇到这样的烦恼:
有时候仅仅为了把一个截图发给开发,可能要经历「拍照 → 传到自己手机 → 微信转发 → 再传到 PC」这样的繁琐流程。
基于这些痛点,我开发了一个轻量级的测试效能小工具 —— 扫码上传助手 🧩。
它的目标非常简单: 让测试机与 PC 之间传文件,像发微信一样方便。
每次启动时,PC 端会自动生成一个上传二维码,并展示在浏览器页面上。 扫码后即可进入对应的上传通道。

测试机打开微信扫码(或浏览器扫码)二维码后,自动跳转到上传页面。
上传文件(截图、录屏、日志等)后,PC 端页面会实时接收并显示文件。


除了文件,测试人员还可以直接发送文字消息到 PC 端,比如:
「复现步骤」「异常时间点」「接口返回错误码」等。

手机端无需登录账号,也不需要安装 App。
只要能扫码、能上传,就能使用。
真正实现测试机与 PC 的轻量级高效互通。
整个系统采用 前后端分离架构:
📱 手机端(H5 上传页面)
⇅ HTTP / WebSocket
🖥️ PC 端(浏览器显示 + WebSocket 监听)
⇅
☁️ 服务端(Spring Boot)
通过 ZXing 生成带任务 ID 的二维码,扫描后跳转上传页:
@Slf4j
@RestController
@RequestMapping("qrcode")
public class QrCodeController {
@Value("${frontend.url}")
private String frontendUrl;
@GetMapping("/{taskId}")
public ResponseEntity<String> generateQRCode(@PathVariable String taskId) throws Exception {
String baseUrl = frontendUrl + "/upload?taskId=" + URLEncoder.encode(taskId, StandardCharsets.UTF_8.name());
int width = 300, height = 300;
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new QRCodeWriter().encode(baseUrl, BarcodeFormat.QR_CODE, width, height, hints);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", baos);
String base64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(baos.toByteArray());
return StatusCode.OK.build(base64);
}
}
支持多文件与文字消息上传,上传后通过 WebSocket 实时推送到前端展示:
@PostMapping("/files")
public ResponseEntity<List> upload(@RequestParam String taskId,
@RequestParam(value = "files", required = false) List<MultipartFile> files,
@RequestParam(value = "content", required = false) String content) throws IOException {
List<UploadMessage> list = new ArrayList<>();
// 发送文本消息
if (content != null && !content.isEmpty()) {
UploadMessage textMsg = new UploadMessage();
textMsg.setTime(LocalDateTime.now().toString());
textMsg.setContent(content);
UploadWebSocket.broadcast(taskId, textMsg);
list.add(textMsg);
}
// 上传文件
if (files != null) {
for (MultipartFile file : files) {
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
String uploadDir = staticLocation + "/upload/other/";
File dest = new File(uploadDir, fileName);
dest.getParentFile().mkdirs();
file.transferTo(dest);
UploadMessage msg = new UploadMessage();
msg.setTime(LocalDateTime.now().toString());
msg.setFileUrl("static/upload/other/" + fileName);
UploadWebSocket.broadcast(taskId, msg);
list.add(msg);
}
}
return StatusCode.OK.build(list);
}
每个二维码对应一个 WebSocket 任务通道,用于推送实时消息:
@Slf4j
@Component
@ServerEndpoint(value="/ws/upload/{taskId}")
public class UploadWebSocket {
// taskId -> set of sessions (多个客户端可以订阅同一个 taskId)
private static final Map<String, Set<Session>> SESSION_MAP = new ConcurrentHashMap<>();
private static final ObjectMapper MAPPER = new ObjectMapper();
private String taskId;
@OnOpen
public void onOpen(Session session, @PathParam("taskId") String taskId) {
this.taskId = taskId;
SESSION_MAP.computeIfAbsent(taskId, k -> Collections.newSetFromMap(new ConcurrentHashMap<>())).add(session);
}
@OnMessage
public void onMessage(Session session, String message, @PathParam("taskId") String taskId) {
// 可处理客户端消息(例如心跳),这里忽略
}
@OnClose
public void onClose(Session session, @PathParam("taskId") String taskId) {
Set<Session> set = SESSION_MAP.get(taskId);
if (set != null) set.remove(session);
}
@OnError
public void onError(Session session, Throwable thr) {
// 日志忽略
}
public static void broadcast(String taskId, UploadMessage msg) {
Set<Session> sessions = SESSION_MAP.getOrDefault(taskId, Collections.emptySet());
if (sessions.isEmpty()) return;
try {
String text = MAPPER.writeValueAsString(msg);
// 迭代发送(并发安全)
for (Session s : sessions) {
if (s.isOpen()) {
try { s.getBasicRemote().sendText(text); } catch (Exception ignored) {}
}
}
} catch (Exception ignored) {}
}
}
1️⃣ 启动服务端
运行 Spring Boot 项目,打开浏览器访问二维码生成页。
2️⃣ 扫描二维码
测试机用微信 / 浏览器扫码,跳转上传页面。
3️⃣ 上传文件或消息
上传截图、视频或输入文字说明。
4️⃣ PC 端实时显示结果
上传后内容自动推送并显示在 PC 端界面。
这个 扫码上传工具 虽然小巧,但解决了我们测试工作中一个长期的痛点。它让测试人员能更专注于 问题定位与分析,而不是被低效的文件传输方式拖慢节奏。
如果你也经常为测试机与 PC 之间传文件发愁,不妨试试开发这个工具 👇💬 欢迎留言告诉我你的建议!后续我还计划支持:上传后自动通知开发(Webhook)。