gpt4 book ai didi

unit-testing - 为什么 rdmd 可能不会运行所有单元测试?

转载 作者:行者123 更新时间:2023-12-04 04:06:41 27 4
gpt4 key购买 nike

不幸的是,我似乎无法在一个最小的工作示例中重现这种行为,所以这可能太模糊了。但是,我至少可以说明没有导致该行为的原因。

我有一个 D 模块,其中包含几个带有单元测试的类,其结构类似于:

import std.stdio;

class c1{
int c1func(int blah){ return blah; }
unittest{
writeln("Testing c1 func.");
stdout.flush();
}
}

class c2(T:c3) : c1{
private static int c2func(int blah){ return blah; }
unittest{
writeln("Testing c2 func.");
stdout.flush();
}

int c2fun2(int blah){
T tmp = new T();
return tmp.c3fun(blah);
}
}

class c3{
abstract int c3fun(int blah);
}

class c4 : c3{
override int c3fun(int blah){ return blah; }
}

unittest{
writeln("Testing class c1.");
stdout.flush();
c1 myc2 = new c2!(c4)();
}

我的期望是以下形式的调用:
rdmd --main -unittest tmp.d

会产生输出
Testing c1 func.
Testing class c1.
Testing c2 func.

确实如此(c2 func 的单元测试在实例化之前不会运行)。

但是,在我的类似但更长的 D 模块中,没有运行模板类 c2 对应的单元测试(可以肯定的是,我在其他单元测试中都放置了与此处相同的打印语句)。

这有点令人担忧,因为事实上,一段时间以来我一直依赖这些其他单元测试的正确性。此外,rdmd 很高兴地发现单元测试代码中的语法错误,尽管从未运行过上述代码。

所以这是我可以排除的:
  • rdmd 正在读取单元测试。
  • rdmd 实际上是针对文件的最新版本运行的。
  • rdmd 显然很乐意为模板类的实现运行单元测试,即使它们的参数使用抽象类的特化,只要这些模板类实际被实例化。
  • 我的模板类中的函数(类似于示例代码中的 c2)实际上是在底部的主要单元测试 block 期间被调用的,因此模板类肯定已被实例化。
  • rdmd 本身并没有错,因为使用 dmd 和相同的标志进行编译也无法运行这些单元测试。

  • 关于这里可能出现什么问题的任何想法?如果可以的话,我会提供一个 MWE,但是我写的每个版本似乎都可以正常工作!

    最佳答案

    似乎这是由于 rdmd 对单元测试进行排序的方式造成的,这与我预期的方式不同。

    似乎 RDMD 不是在实例化时调用实例化模板类的单元测试,而是在实例化类的单元测试完成后立即调用。

    这是一个MWE:

    import std.stdio;

    class c1{
    int c1func(int blah){ return blah; }
    unittest{
    writeln("Testing c1 func.");
    stdout.flush();
    }
    }

    class c2(T:c3) : c1{
    private static int c2func(int blah){ return blah; }
    unittest{
    writeln("Testing c2 func.");
    stdout.flush();
    }

    int c2fun2(int blah){
    T tmp = new T();
    return tmp.c3fun(blah);
    }
    }

    class c3{
    abstract int c3fun(int blah);
    }

    class c4 : c3{
    override int c3fun(int blah){ return blah; }
    }

    unittest{
    writeln("Testing class c1.");
    stdout.flush();
    c1 myc2 = new c2!(c4)();
    assert(1==0);
    }

    在这种情况下,底部的单元测试将失败(因为 assert(1==0)),因此模板类的单元测试永远不会运行。

    当将模板类与单元测试一起使用时,这会带来一个主要问题。如果您的模板类失败以某种方式破坏导致实例化它的单元测试失败,那么它自己的单元测试将永远不会运行。在静默失败的情况下(模板类中的错误在我的代码中触发了静默退出),这将表现为模板类的测试从未运行。

    总结 : DMD 通常只是按照它们出现的顺序运行单元测试。然而,由于模板类在模板没有完成的情况下不存在,模板类中的单元测试不会按照它们出现的顺序运行。相反,它们会(按顺序)在模板类被实例化的第一个单元测试之后立即运行。

    解决方法 :在模板类的正下方添加一个单独的单元测试,它只是用所有想要测试的类型实例化它,这将导致单元测试以正确的顺序运行。然而,一个看似更好的策略是在发生实例化的测试 block 之前运行这些单元测试!

    关于unit-testing - 为什么 rdmd 可能不会运行所有单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25298006/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com