Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 单元测试-应该对多复杂的方法进行单元测试?_Unit Testing_Complexity Theory - Fatal编程技术网

Unit testing 单元测试-应该对多复杂的方法进行单元测试?

Unit testing 单元测试-应该对多复杂的方法进行单元测试?,unit-testing,complexity-theory,Unit Testing,Complexity Theory,假设我正在测试以下类(~伪代码): 为了让问题变得更复杂。。。有问题的,让我们假设,这些方法中的大多数(例如,Process1、Process2、FinalProcessing、ExtractSpecificAreas)的结果几乎是不可预测的——例如,有一些启发式/决定性算法试图从图像中提取特征:它可能在90%的情况下成功,这是可以接受的 您会对以下哪种方法进行单元测试?除了无效的输入/边界条件外,您如何对这些方法进行单元测试?单元测试的基本方法(或复杂程度)如何才能使单元测试有意义?单元测试的

假设我正在测试以下类(~伪代码):

为了让问题变得更复杂。。。有问题的,让我们假设,这些方法中的大多数(例如,Process1、Process2、FinalProcessing、ExtractSpecificAreas)的结果几乎是不可预测的——例如,有一些启发式/决定性算法试图从图像中提取特征:它可能在90%的情况下成功,这是可以接受的


您会对以下哪种方法进行单元测试?除了无效的输入/边界条件外,您如何对这些方法进行单元测试?单元测试的基本方法(或复杂程度)如何才能使单元测试有意义?

单元测试的一般规则是测试您可以测试的尽可能小的部件。一个好的规则是,每个测试都应该从公共API中精确地执行一个方法

这意味着它应该只执行这个方法,而不执行其他方法,即使是暂时的。因此,如果您想测试
foo()
并且它调用
bar()
,那么您应该模拟
bar()
,而不是也测试它。不过,调用内部私有方法
baz()
也可以

如果您的方法调用数百个内部方法,那么这将调用

原因是单元测试中的失败应该将您指向问题的确切位置。如果您要进行单元测试
main()
,那么失败只会告诉您项目的代码中有一个bug。比如说,如果您进行了单元测试,但测试失败了,那么您就可以非常准确地知道bug的位置

这也回答了您的问题:您有返回不可预测结果的方法。模拟它们将允许您始终返回已知的好/坏结果,因此您可以测试正确处理这些结果的方法

对于不可预测的方法,您必须找到类似的策略。我在这里假设你在某个地方有神经网络,比如说,经过训练的。因此,一个测试可能是将一些训练图像传递给该方法N次,直到您确信图像在90%的时间内正确排序

同样,您应该能够将这些方法划分为可预测和不可预测的部分,然后使用模拟或统计分析进行测试


两个伟大的模拟框架是和。

我认为Aaron Digulla已经指出了最重要的事情:测试尽可能小的部分并使用模拟对象


但让我再补充一件事:您可能还想测试您的整个应用程序,也就是说,这些小部件是否能够很好地协同工作(这将是集成测试,而不是单元测试,但无论如何,您应该同时做这两件事)。为了测试启发式算法,我发现从一个容易解决的任务开始是很有用的——在你的例子中,这将是一种“简单”的图像。当然,这只是给了你一个基准,并不能保证它能在90%的情况下工作。但无论如何,它在开发过程中是有帮助的,如果您愿意,您可以使用更真实的样本来增强(集成)测试套件。

实际上,没有神经网络,只有复杂的确定性算法。然而,由于它们的复杂性和输入数据的质量,它们很少有误报或漏报。如果您对它们进行单元测试,失败的测试可能不会从本质上指出方法失败,只是遗漏了案例。这听起来好像它们总是会为相同的输入返回相同的结果。如果是这样,那么您可以像其他代码一样对它们进行单元测试。不要使用随机输入编写单元测试。创建一组图像,在其中您知道正确的结果(或者至少可以肯定算法的结果必须正确),并在单元测试中使用这些预期结果。
// (...)
public Result Process(Image image)
{
    Image image2 = PreprocessImage(image);
    PartialResult r1 = Process1(image2);
    PartialResult r2 = Process2(r1);
    Result result = FinalProcessing(r2);

    return result;
}

public Image PreprocessImage(Image image)
{
    Image tmp1 = Resize(image);
    Image tmp2 = Blur(tmp1);
    Image tmp3 = Median(tmp2);
    Image tmp4 = ExtractSpecificAreas(tmp3);

    return tmp4;
}

public Image Median(Image image)
{
     // Actual image median algorithm
}