You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试两段Python代码对任意输入的输出是否完全一致

自写代码与参考解法的输出对比及bug定位方法

核心原理

不需要掌握复杂的测试框架知识,核心逻辑是用完全相同的输入分别运行自写代码和参考代码,自动比对输出差异,找到输出不一致的输入,就是触发你代码逻辑错误的测试用例,顺着这个用例排查执行流程就能定位问题。

操作步骤

  • 整理代码结构
    把自写的待调试代码、官方参考解法放在同一个Python文件中,保证两者的调用入口统一:比如都是同名类下的同名方法,入参、返回值格式完全一致,避免调用逻辑出错。
  • 构造覆盖全场景的测试用例集
    测试用例分三类准备,保证覆盖所有可能的逻辑分支:
    • 题目公开给出的示例用例
    • 手动枚举的边界用例:比如单字符输入、特殊组合输入、题目规定的最大/最小合法值输入
    • 批量随机生成的合法输入:按照题目给定的规则写简单的生成逻辑,批量产出上百上千个合法输入,覆盖人工枚举遗漏的场景
  • 编写自动对比脚本
    遍历所有测试用例,将同一个输入分别传入两个解法的入口函数拿到返回值,一旦出现返回值不一致的情况,立刻打印当前输入、自写代码输出、参考代码输出,终止运行方便排查;如果所有用例遍历完都没有不一致,说明两份代码的逻辑输出完全等价。

罗马数字转整数题的可直接运行示例

把下面的代码保存为.py文件直接运行即可,你可以替换MySolution类的内容为自己写的递归版、迭代版代码做测试:

import random

# -------------------------- 待调试的自写代码区 --------------------------
prefix = ['I', 'X', 'C']
value = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}

def rec(s, v):
    n = s[0:1]
    if len(s) > 1 and n in prefix and value[s[0:1]] < value[s[1:2]]:
        n = s[0:2]
    if len(n) > 1:
        v += value[n[1]] - value[n[0]]
    else:
        v += value[n]
    s = s.removeprefix(n)
    return v if not s else rec(s, v)


class MySolution:
    def romanToInt(self, s: str) -> int:
        return rec(s, 0)

# -------------------------- 官方参考解法区 --------------------------
class RefSolution:
    def romanToInt(self, s: str) -> int:
        val_map = {'I':1, 'IV':3, 'V':5, 'IX':8, 'X':10, 'XL':30, 'L':50, 'XC':80, 'C':100, 'CD':300, 'D':500, 'CM':800, 'M':1000}
        total = val_map[s[0]]
        for i in range(1, len(s)):
            if val_map[s[i]] > val_map[s[i-1]]:
                total -= 2 * val_map[s[i-1]]
            total += val_map[s[i]]
        return total

# -------------------------- 自动对比测试逻辑区 --------------------------
# 1. 初始化测试用例集
test_cases = [
    # 题目示例用例
    "III", "IV", "IX", "LVIII", "MCMXCIV",
    # 手动枚举边界用例
    "I", "V", "M", "MMMCMXCIX", "XL", "CD", "CM", "XIV", "XCIX"
]
# 2. 追加1000个随机生成的合法罗马数字用例
roman_rule = [['M',1000], ['CM',900], ['D',500], ['CD',400], ['C',100], ['XC',90], ['L',50], ['XL',40], ['X',10], ['IX',9], ['V',5], ['IV',4], ['I',1]]
for _ in range(1000):
    rand_num = random.randint(1, 3999)
    rand_str = ""
    remain = rand_num
    for char, val in roman_rule:
        while remain >= val:
            rand_str += char
            remain -= val
    test_cases.append(rand_str)

# 3. 逐用例对比输出
my_solver = MySolution()
ref_solver = RefSolution()
for case in test_cases:
    my_output = my_solver.romanToInt(case)
    ref_output = ref_solver.romanToInt(case)
    if my_output != ref_output:
        print("找到触发bug的测试用例:")
        print(f"输入:{case}")
        print(f"自写代码输出:{my_output}")
        print(f"参考解法输出:{ref_output}")
        exit(0)
print("全部测试用例通过,两份代码输出完全一致")

定位具体逻辑错误的技巧

  • 拿到触发bug的输入后,在自写代码的关键执行节点加打印,输出每一步的中间变量:比如循环/递归每一层的剩余输入、当前处理的字符、临时计算值、累加结果,和参考解法在同一个输入下的中间变量逐行比对,第一个出现数值差异的位置就是逻辑错误的根源。
  • 比如你写的迭代版代码里已经加了每轮的变量打印,只要拿到出错的输入,顺着打印的执行流走一遍,很快就能定位是判断条件写错、字符串截取逻辑有误,还是计算规则不符合题目要求。
  • 如果上千个随机生成的用例都能通过,基本可以确认自写代码的逻辑和参考解法等价,不存在隐藏的逻辑漏洞。

内容的提问来源于stack exchange,提问作者Cesar Lopes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:54:34