代码之家  ›  专栏  ›  技术社区  ›  goodside

通过在代码修订中断言一致的行为来进行Python测试?

  •  1
  • goodside  · 技术社区  · 6 年前

    典型的Python单元测试断言某些函数返回预先计算的输出值,例如:

    def average(a, b):
        return (a + b) / 2
    
    def test_average():
        assert average(2, 4) == 3
    

    但是我不安的是测试框架在断言的结果中留下的模糊性( 3

    def test_average(a, b):
        params = [
            [1, 3, 2],
            [9000.5, 9000.5, 9000.5], 
            [100, -100, 0],
            [-1, 3, 1],
            [0, 0, 0]
        ]
        for a, b, result in params:
            assert average(a, b) == result
    

    但是,如果参数列表很长或计算结果比较困难,则必须在两个选项中进行选择:

    1. 在ipyth测试基下手工保存一次测试值

    大多数开发人员使用这两种方法的组合。但这两种方法都不能证明密码是 对的 一致的 跨越代码的修订。运行测试实际上只是测试代码的行为与编写测试时相同。

    def demo_average():
        arg_a_vals = [0, -4.2, 1/12] + range(-100, 1000, 5)
        arg_b_vals = [0, -10**200, math.pi] + range(2**20, 2**20 + 17)
        return [
            a, b, average(a, b)
            for a in arg_a_vals
            for b in arg_b_vals
        ]
    
    def save_demo(results):
        with open(f"demo_v{__version__}.json", "w") as f:
            json.dump(results, f)
    
    def load_demo(version):
        with open(f"demo_v{version}.json") as f:
            return json.load(f)
    
    def test_average():
        result = demo_average()
        save_demo(result)
        saved_result = load_demo(GOOD_PRIOR_VERSION)
        assert_lists_are_equal(result, saved_result)
    
    

    这个例子故意简单,但是 save_demo load_demo test_average demo_average 一种可能的输入值的枚举,其输出应在不同版本之间进行比较。请注意,代码 与普通断言测试不同,包括任何预期的输出值作为文本。

    如果测试框架知道版本控制系统并且可以在多个克隆版本上运行演示来生成 results

    对代码进行修订后,结果一致 ,而不是在测试用例中声明特定的预期结果。[编辑:德克赫尔曼在评论中指出,这有时被称为 .]

    tox

    Hypothesis . 假设很有趣,而且它的工作方式也与普通测试有很大的不同。简单地说,你把测试写成高度参数化/通用化的断言,而假设做了一些聪明的事情来探索失败的参数空间。但是通过阅读文件,我看不出这对我的案子有何影响。我的目标是编写测试来断言行为的版本间一致性,而不是孤立地检查可以断言的关于代码的单个版本的任何属性。

    0 回复  |  直到 6 年前
    推荐文章