Unit testing 当正确性定义不好时进行测试?

Unit testing 当正确性定义不好时进行测试?,unit-testing,language-agnostic,automated-tests,data-mining,Unit Testing,Language Agnostic,Automated Tests,Data Mining,我通常尝试对任何代码使用单元测试,这些代码在给定一些合理的小的、定义良好的输入集的情况下很容易定义正确的行为。这对于捕捉bug非常有效,我一直在我个人的泛型函数库中这样做 然而,我编写的许多代码都是数据挖掘代码,基本上是在大型数据集中查找重要的模式。在这种情况下,正确的行为通常没有很好的定义,并且取决于许多不同的输入,这些输入方式不容易被人类预测(例如,数学不能合理地用手来完成,这就是为什么我首先使用计算机来解决这个问题)。这些输入可能非常复杂,以至于几乎不可能提出一个合理的测试用例。识别值得测

我通常尝试对任何代码使用单元测试,这些代码在给定一些合理的小的、定义良好的输入集的情况下很容易定义正确的行为。这对于捕捉bug非常有效,我一直在我个人的泛型函数库中这样做

然而,我编写的许多代码都是数据挖掘代码,基本上是在大型数据集中查找重要的模式。在这种情况下,正确的行为通常没有很好的定义,并且取决于许多不同的输入,这些输入方式不容易被人类预测(例如,数学不能合理地用手来完成,这就是为什么我首先使用计算机来解决这个问题)。这些输入可能非常复杂,以至于几乎不可能提出一个合理的测试用例。识别值得测试的边缘情况是极其困难的。有时算法甚至不是确定性的


通常,我会尽我所能,使用断言进行健全性检查,并创建一个具有已知模式的小型玩具测试用例,非正式地查看答案是否至少“看起来合理”,而不一定是客观正确的。有没有更好的方法来测试这类情况?

最终,你必须决定你的程序应该做什么,然后进行测试

我认为您只需要基于小数据集编写单元测试,以确保您的代码完全符合您的要求。如果这为您提供了一个合理的数据挖掘算法,那么这是一个单独的问题,我认为不可能通过单元测试来解决它。代码的正确性有两个“级别”:

  • 您的代码正确地实现了给定的数据挖掘算法(您应该进行单元测试)
  • 您实现的数据挖掘算法是“正确的”——解决了业务问题。这是一个相当开放的问题,它可能既取决于算法的某些参数,也取决于实际数据(不同的算法适用于不同类型的数据)
    嗯,有几个答案。 首先,正如你提到的,做一个小案例研究,手工计算。因为你写了算法,你知道它应该做什么,所以你可以在有限的情况下做

    另一种方法是将程序的每个组件分解为可测试的部分。 如果A调用B调用C调用D,并且您知道A、B、C、D都给出了正确的答案,那么您可以测试A->B、B->C和C->D,然后您可以合理地确定A->D给出了正确的响应

    此外,如果还有其他程序可以完成您希望完成的任务,请尝试获取它们的数据集。或者是一个开源项目,您可以对其使用测试数据,看看您的应用程序是否给出了类似的结果

    测试数据挖掘代码的另一种方法是,获取一个测试集,然后引入您正在寻找的类型的模式,然后再次测试,看看它是否能将新模式与旧模式区分开来


    而且,经过验证的方法是,手动浏览您自己的代码,看看代码是否按照您的意思执行

    当遇到这样的情况时,我倾向于构建一个或多个存根数据集,以反映真实数据的基本复杂性。我经常和客户一起这样做,以确保我抓住了复杂性的本质


    然后我可以将这些数据编码成一个或多个数据集,这些数据集可以用作进行非常特定的单元测试的基础(有时它们更像是带有存根数据的集成测试,但我认为这不是一个重要的区别)。因此,虽然您的算法对于“通用”数据集可能有“模糊”结果,但对于特定数据集,这些算法几乎总是有一个单一的正确答案。

    实际上,这里的挑战是:因为您的应用程序旨在以智能的方式执行模糊的、不确定的任务,您希望实现的目标就是让应用程序在发现这些模式方面比人类做得更好。这是伟大的,强大的,酷。。。但是如果你成功了,那么任何人都很难说,“在这种情况下,答案应该是X。”

    实际上,计算机最好会说:“不是真的。我明白你为什么这么想,但是考虑一下这4.2个百万兆字节的信息。你读过了吗?基于这些,我认为答案应该是Z。” 如果你真的成功实现了最初的目标,最终用户有时可能会说:“佐维,你是对的。这是一个更好的答案。你找到了一种模式,可以让我们赚钱!(或者节省我们的钱,或者其他什么)。”

    如果这样的事情永远不会发生,那么你为什么要让计算机首先检测这些类型的模式呢

    所以,我能想到的最好的事情就是让现实生活帮助你建立一个测试场景列表。如果在过去发现了一种模式,但结果证明它是有价值的,那么进行一次“单元测试”,看看您的系统在提供类似数据时是否发现了它。我引用“单元测试”是因为它可能更像一个集成测试,但您仍然可以选择使用NUnit、VS.Net、RSpec或您正在使用的任何单元测试工具

    对于其中一些测试,您可能会以某种方式尝试“模拟”4.2 TB的数据(您不会真正模拟数据,但在更高的级别上,您会模拟从该数据得出的一些结论)。对于其他人,可能您有一个“测试数据库”,其中包含一些数据,您希望从中检测到一组模式


    此外,如果你能做到这一点,如果系统能够“描述其检测到的模式背后的推理”,那就太好了。这会让业务用户仔细考虑应用程序是否正确的问题。

    这很棘手。这听起来类似于围绕文本搜索引擎编写测试。如果你继续努力,你会发现:

    • 从一个小的、简化的