科学计算库的单元测试


15

我以前在单元测试中有过一些经验,我称之为(不是贬义)经典的软件工程项目:MVC,带有用户GUI,数据库,中间层的业务逻辑等。现在,我我用C#编写了一个科学计算库(是的,我知道C#太慢了,使用C,不要重新发明轮子,所有这些,但是我们有很多人在C#中从事科学计算,我们有点需要)。就软件开发行业而言,这是一个小项目,因为我主要是自己写这篇文章,有时是在一些同事的帮助下编写的。另外,我并没有为此获得报酬,最重要的是,这是一个学术项目。我的意思是,我希望它有一天能达到专业水平,因为我正计划开源。

无论如何,该项目正在变得越来越庞大(大约18,000行代码,对于一个人的项目而言,我认为这是很大的),而且它也变得一发不可收拾。我正在使用git进行源代码控制,我认为我还不错,但是我正在像老派一样进行测试,我的意思是编写编写测试系统大部分内容的完整控制台应用程序,主要是因为我不知道如何在这种情况下进行单元测试,尽管我认为那是我应该做的。问题在于该库主要包含算法,例如图算法,分类器,数值解算器,随机分布等。我只是不知道如何为每种算法指定微小的测试用例,因为其中很多是随机的,我不知道如何验证正确性。例如,对于分类,有一些指标,例如精度和召回率,但是这些指标对于比较两种算法比判断一种算法更好。那么,如何在这里定义正确性?

最后还有性能问题。我知道它是一套完全不同的测试,但是性能是科学工具的重要功能之一,而不是用户满意度或其他软件工程指标。

我最大的问题之一是数据结构。我可以针对kd-tree进行的唯一测试是压力测试:插入许多随机向量,然后执行许多随机查询,然后与朴素的线性搜索进行比较。性能相同。使用数值优化器,我可以测试基准功能,但是再次,这是压力测试。我不认为这些测试可以归类为单元测试,最重要的是,它们不能连续运行,因为其中大多数都很繁重。但是我也认为这些测试需要完成,我不能只插入两个元素,弹出根,是的,它适用于0-1-n的情况。

那么,这种软件的(单元)测试方法是什么(如果有)?以及如何围绕代码-构建-提交-集成周期组织单元测试和繁重的单元测试?

Answers:


19

我想说科学计算实际上非常适合单元测试。您具有确定的输入和输出,明确定义的前提条件和后置条件,根据某些设计师的想法,这些条件可能不会每隔一周更改一次,并且没有难以测试的UI要求。

您列举了一些可能引起麻烦的元素;这是他们的处理方法:

  • 随机算法:有两种可能性。如果您实际上想测试随机数本身,只需安排大量重复并断言预期的案例比例符合期望的标准,并且具有足够大的错误余量,那么虚假的测试失败将非常罕见。(A测试套件,不可靠信号幻象的错误是很多比一个不抓住每一个可能的缺陷变得更糟。)或者使用一个可配置的随机源,并通过依赖确定性源更换系统时钟(或者不管它是你使用)注射,使您的测试变得完全可预测。
  • 仅在精度/召回率方面定义的算法:没有什么可以阻止您放入整套输入用例,并通过将它们全部加起来来测量精度和召回率;这只是半自动有效地生成此类测试用例的问题,因此提供测试数据不会成为提高生产率的瓶颈。可替代地,如果例程是足够可预测的,则指定一些明智选择的输入/输出对并断言算法可以精确计算所需的输入也可以工作。
  • 非功能性需求:如果规范确实给出了明确的空间/时间需求,那么您基本上必须运行整个输入/输出对套件,并验证资源使用情况是否大致符合所需的使用方式。这里的技巧是首先校准您自己的测试类,以免您无法测量十个不同大小的问题,这些问题最终导致测量速度太快,或者花费太长时间以至于无法运行测试套件。您甚至可以编写一个小型用例生成器,该生成器可以创建不同大小的测试用例,具体取决于PU的运行速度。
  • 快速和慢速运行的测试:无论是单元测试还是集成测试,您通常都会得到很多非常快的测试和一些非常慢的测试。由于定期运行测试非常有价值,因此我通常走实用主义的道路,将我拥有的所有东西分成快速和慢速套件,以便快速的套件可以尽可能频繁地运行(一定在每次提交之前运行),而不管是否两个测试“语义上”属于或不属于。

+1。非常感谢,您的回答有很多。仅有几个问题:关于元启发式算法的优化算法如何?我有很多基准函数,但是我只能用它们比较两种不同的算法。我还需要找到一个基准算法吗?遗传算法正确意味着什么?以及我如何测试每种“可参数化”的策略,例如重组和突变的类型等?
亚历杭德罗·皮亚德

1
对于元启发式算法,我会选择一些特征性的I / O对,即例程的“成功案例”,并验证该方法(或两者中较好的一个)确实找到了该解决方案。在优化研究中,碰巧能够正常工作的“挑剔”问题当然是禁忌,但对于软件测试而言,这并不是一个问题-您并不是在断言算法的质量,只是正确的实现。那是您可以证明的唯一“正确性”。至于乘法参数化例程:是的,我担心这需要组合数量的测试……
Kilian Foth,

因此,就像设计一个琐碎的基准测试以解决所有正确的实现方式一样?有没有办法证明算法的质量?我知道我通常不能定义质量标准,但是至少我希望没有任何改变会降低所达到的质量?
亚历杭德罗·皮亚德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.