Go测试环境无缓冲Channel重复接收,生产环境行为正常问题排查
测试资源跨用例未隔离
要是playerReadyChannel或者sendReadyUpPrompt协程是全局变量、或者被多个测试用例共享,前序测试结束后协程没被彻底终止,就会一直监听Channel。新测试用例发送就绪信号时,旧协程也会接收并打印日志,前序测试的资源关闭日志自然会夹杂进来。生产环境里每个会话都是独立实例,不会有跨实例共享协程/Channel的情况,所以不会触发重复日志。无缓冲Channel的生命周期未绑定测试用例
测试中如果复用了全局的playerReadyChannel,前序测试的协程还阻塞在接收操作上,新测试用例发送信号时,旧协程和当前测试的新协程会同时接收信号,造成重复打印。生产环境里Channel和协程的生命周期和用户会话绑定,会话结束就会回收资源,不会出现这种复用残留的问题。测试并发控制不当
要是表格驱动测试里用了t.Parallel()开启用例并发执行,又没做资源的并发安全隔离,多个用例的协程会同时操作同一个Channel,导致同一条就绪信号被多个协程接收,出现重复日志。生产环境的请求处理有严格的会话隔离,不会出现跨会话的并发操作同一资源的情况。协程缺少退出机制
sendReadyUpPrompt协程如果没有监听退出信号的逻辑,前序测试结束后,协程会一直卡在playerReady的接收步骤上。后续测试用例向同一个Channel发送信号时,这个残留协程会立刻接收并打印日志,导致重复触发。生产环境中客户端断开或会话结束时,会有专门的清理逻辑终止协程,不会有残留。
内容的提问来源于stack exchange,提问作者Allister

