上周和朋友内测我开发的德州扑克小游戏,撞到一个离谱场景:玩家 A 手持同花顺 all-in,玩家 B 跟注后居然被判定赢了底池。顺着日志往下查才发现,核心规则引擎里同花顺的牌型判定权重比四条还低,而且边池(Side Pot)的分割逻辑完全没考虑全押玩家的下注额,底池分配全错。面对一堆堆叠的历史代码和几乎为零的边界场景测试,我决定用测试驱动开发(TDD)加系统化调试的思路逐步攻坚。
先补测试,再动代码
改代码之前第一步不是修 bug,而是先摸清当前实现和测试状态:项目原本的单元测试只覆盖基础单局流程,核心规则、下注逻辑、边池计算的覆盖率不到 30%,多玩家全押、边池分割这类复杂场景完全没覆盖。
我把所有已知 bug 和边界场景列成测试用例清单:全押下的底池分配、不同牌型的判定边界、加注 / 跟注的状态流转校验等。补边池分割用例时,还挖出一个之前没暴露的问题——三个玩家全押的场景下,原逻辑直接按玩家顺序分配底池,完全没考虑每人实际能匹配的下注额:比如 P1 下注 20 全押、P2 下注 50、P3 下注 100,原逻辑会把全部底池判给 P3,完全不符合规则。这个发现印证了「先补测试再改代码」的必要性:直接改边池逻辑很容易漏掉这类多玩家边界。
三类核心 bug 逐一清掉
按测试先行的原则,每补一组用例就对应修一个根因。
牌型判定权重写反了,这是最核心的问题:写规则引擎时把同花顺权重误设成 3,四条是 4,牌型大小完全搞反。我先写两组用例,分别输入同花顺和四条的手牌,断言同花顺优先级更高,再改权重配置,同时跑全量牌型测试,确认顺子、同花等其他牌型权重没受影响。
下注 / 轮次逻辑只做了基础状态流转,没有非法操作校验:玩家已经全押的状态下仍能触发加注,甚至会因为余额为负导致后续流程崩溃。我补了「全押玩家无法加注」「下注额超过余额自动截断」等用例,再对应加状态校验,现在非法操作会被直接拦截,不会进后续牌局。
边池逻辑原本是简化的按玩家顺序分配,不符合规则。我把计算拆成两步:先算每个玩家实际可匹配的下注额生成对应边池,再按「每个玩家最多赢自己下注额匹配的边池」分配。还是刚才 P1 下注 20、P2 下注 50、P3 下注 100 的场景,现在会先生成 203 的边池 1(三人争)、302 的边池 2(P2 和 P3 争)、50 的边池 3(归 P3),分配结果完全符合规则。补完所有边池边界测试后,逻辑一次性通过,没有回归。
把验证锁进 CI
除了核心逻辑,我还补了两处:交互层输入校验,玩家下注输负数或超余额会直接弹提示,不提交到后端;核心的规则、下注、边池测试都集成进 CI,每次提交自动跑全量,当前核心逻辑覆盖率已经到 85% 以上。之前有一次改牌型权重不小心把顺子的权重改低了,要不是自动化测试及时拦下来,上线又要出大问题。
回头看,游戏规则、金融逻辑这类容错率低的场景,先补全边界用例再改代码,能避开绝大部分回归 bug。调试前先把所有可能的边界、异常场景系统化列一遍,补完测试再动手,比上来就改代码稳得多;核心逻辑一定要加自动化验证,人工测试永远有漏测概率,集成到 CI 每次提交自动校验,线上 bug 概率能大幅降下来。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/mihuyang/article/details/165556063



