Unit testing 请解释单元测试

Unit testing 请解释单元测试,unit-testing,testing,Unit Testing,Testing,我对单元测试有点困惑。我看到了自动化测试的价值。我想也许一个好的例子是帮助我理解的最好方式。假设我有一个二进制搜索函数,我想进行单元测试 现在在测试中,我想知道这样的事情:搜索是否找到第一个元素、最后一个元素和其他元素?搜索是否正确比较unicode字符。搜索是否处理符号和其他“痛苦”字符。单元测试会涵盖这一点,还是我遗漏了它?您将如何为我的二进制搜索编写单元测试 function search(collection, value){ var start = 0, end = collecti

我对单元测试有点困惑。我看到了自动化测试的价值。我想也许一个好的例子是帮助我理解的最好方式。假设我有一个二进制搜索函数,我想进行单元测试

现在在测试中,我想知道这样的事情:搜索是否找到第一个元素、最后一个元素和其他元素?搜索是否正确比较unicode字符。搜索是否处理符号和其他“痛苦”字符。单元测试会涵盖这一点,还是我遗漏了它?您将如何为我的二进制搜索编写单元测试

function search(collection, value){
 var start = 0, end = collection.length - 1, mid;
 while (start <= end) {
  mid = start + ((end - start) / 2);
  if (value == collection[mid])
   return mid;
  if (collection[mid] < value)
   end = mid - 1;
  else
       start = mid + 1;
 }
 return mid;
}

不,你没有错过它,这是单元测试设计来告诉你的。通过测试好的和坏的输入、边缘情况等,您有了正确的想法。您需要对每个条件进行一次测试。测试将设置任何先决条件,然后断言您的计算(或任何可能的计算)符合您的预期

是的,就是这样。你问的每一个问题都可以用作测试。将单元测试视为三个步骤。设置一些先决条件,运行一些“正在测试”的代码,并编写一个断言来记录您的期望

在您的情况下,使用某些特定值(或无值)设置“集合”就是设置前提条件

使用特定参数调用搜索方法正在运行测试中的代码

检查方法返回的值是否与预期值匹配是断言步骤


给这三件事起一个名字来描述你要做的事情(如果CollectionisEmpty,那么SearchMethodFaily是否失败),然后你就有了一个单元测试。

你对单元测试的期望是正确的;这主要是验证和验证预期的行为

我认为很多人都忽略了单元测试的一个价值,那就是它的价值随着时间的推移而增加。当我写一段代码,写一个单元测试时,我基本上只是测试代码是否做了我认为应该做的事情,在我选择检查的任何方面都没有失败,等等。这些都是好事,但它们的价值有限,因为它们表达了您当时对系统的了解;他们不能帮助你做一些你不知道的事情(我的算法中是否有一个我不知道也不想测试的秘密bug?)

在我看来,单元测试的真正价值是它们随时间而获得的价值。该值有两种形式;文档价值和验证价值

文档值是单元测试的值,表示“这是代码作者期望这段代码做的”。这种东西的价值怎么强调都不为过;当你在一个有大量未充分记录的遗留代码的项目上工作时,我告诉你,这种文档价值就像一个奇迹

另一个值是验证值;当代码在项目中继续存在时,事情会被重构、更改和转移。单元测试验证您认为以某种方式工作的组件是否继续以这种方式工作。这在帮助发现潜入项目的错误方面是非常宝贵的。例如,更改数据库解决方案有时是透明的,但有时,这些更改会导致某些工作方式发生意外变化;对依赖于ORM的组件进行单元测试可以捕获底层行为中的关键细微变化。当你有一段代码一段时间以来一直完美地工作,并且没有人认为在失败中考虑它的潜在作用时,这真的很有用。这些类型的bug可能需要很长时间才能找到,因为您最后要查找的位置是已经坚如磐石很长时间的组件。单元测试验证了“岩石坚固性”

function testFirst(){
 var collection = ['a','b','c','x','y','z'],first = 'a', findex = 0;
 assert(seach(collection,first),findex);
}
function testLast(){
 var collection = ['a','b','c','x','y','z'], last = 'z', lindex = 5;
 assert(seach(collection,last),lindex);
}