如何避免依赖外部配置的函数的单元测试出现脆弱问题?
解决方案
你遇到的问题本质是被测函数与全局配置硬耦合,导致测试边界不清晰,两种现有方案的缺陷根源是把「函数执行逻辑的正确性」和「生产配置的正确性」两个完全独立的测试目标混在了一起。
第一步:先解耦被测函数与全局配置
给example函数新增配置参数,默认值保留原有的全局常量,不会影响现有业务代码的调用,同时给测试留出了注入自定义配置的入口:
def example(input_dict, ops=OPS, directives=DIRECTIVES): output_dict = {} for item,calcs in directives.items(): output_dict[item] = 0 for operation, field in calcs: output_dict[item] = ops[operation](output_dict[item],input_dict[field]) return output_dict
第二步:拆分两类独立测试用例
1. 测试函数本身的运算逻辑正确性
这部分测试完全不依赖生产的全局配置,自己传入可控的模拟配置,验证函数能按照给定的运算规则、运算指令正确执行计算。这部分测试永远不会因为生产配置修改而失效,只要函数逻辑没错就会通过:
def test_example_logic_correct(self): # 自定义测试用的运算规则和指令,完全可控 test_ops = {'+': operator.add, '-': operator.sub} test_directives = {'test_field': [('+', 'a'), ('-', 'b')]} test_input = {'a': 10, 'b': 3} # 直接写死预期值,不需要重复实现函数逻辑 expected = {'test_field': 7} actual = example(test_input, ops=test_ops, directives=test_directives) self.assertDictEqual(expected, actual)
2. 测试生产配置的正确性
这部分测试的目标就是验证当前线上使用的OPS、DIRECTIVES符合业务预期,直接使用固定预期值的写法即可。如果后续修改了生产配置,这个测试失败是正常的预期行为——刚好能提醒你配置变更后要同步校验业务规则是否符合预期,避免错误配置上线:
def test_production_config_correct(self): # 用生产默认配置,验证结果符合业务要求 expected_result = {'calculated_field': self.value1 + self.value2} actual_result = example(self.input_dict) self.assertDictEqual(expected_result, actual_result)
为什么不建议用原方案2的写法?
测试逻辑和实现逻辑完全重复的情况下,相当于把同一段代码写了两遍,如果原函数存在逻辑缺陷(比如初始值写错、运算顺序写反),测试代码里写一样的错误逻辑,根本无法发现问题,完全失去了测试的意义。
内容的提问来源于stack exchange,提问作者Alvaro Aguilar
相关产品推荐
相关产品推荐

