了解单元测试

时间:2011-06-28 15:11:09

标签: php unit-testing codeigniter testing

我正在努力了解单元测试的工作原理。到目前为止,我知道你正在根据你输入的内容测试函数的输出。好的。这是否意味着如果您的函数唯一可能返回一个数据类型,您只需要为它编写一个测试?所以说我写的函数只有返回TRUE或FALSE的可能性,这是否意味着我只是检查响应是否是布尔值?

然后还说我有一个从数据库中提取博客帖子的功能。假设将函数设置为:如果行数= 0,则返回FALSE,否则返回结果。所以我现在有可能返回一个布尔值或数组的函数。你怎么测试那个?该函数现在不仅仅依赖于输入,而是依赖于数据库中的内容。

7 个答案:

答案 0 :(得分:9)

有用的函数不会随机返回truefalse。在某些情况下,它会返回true ,在其他情况下会返回false

单元测试因此会做三件事(按此顺序):

  1. 创建一个环境,您可以从中了解该函数是应该返回true还是false(此环境称为测试夹具)。
  2. 运行要测试的功能。
  3. 将功能结果与您的期望进行比较。
  4. 显然,这不能用所有可能的输入完成(如果可以做,这将是一个证明,而不是测试),因此单元测试的艺术是选择合适的测试夹具。有两种方法可以解决这个问题:

    • 黑盒测试查看选择灯具的功能规格:有效输入值是什么?它们应该如何影响输出?
    • 白盒测试查看函数并选择灯具,使得函数的每个语句都由至少一个灯具执行。
      

    ...如果行数= 0,则返回FALSE,否则返回结果。

    如果这样的函数通过调用DBMS的API(例如mysql_query)直接向数据库服务器发送查询,那么测试夹具的创建将包括

    1. 设置数据库。
    2. 将行插入数据库(或不是,取决于测试是否应检查结果是否正确返回或正确返回FALSE)。
    3. 另一方面,如果该函数调用自定义函数(例如由对象关系映射器提供),则测试夹具应该提供该自定义函数的模拟实现。依赖注入有助于确保调用者和被调用者失去耦合,因此真正的实现可以在运行时替换为模拟实现。

答案 1 :(得分:5)

你有正确的要点。如果设备有外部特性,则有两种方法。创建Mock类或使用某种类型的fixture。

使用您的数据库示例如果您正在测试必须调用数据访问类以从数据库中提取数据的类,那么您通常会模拟该数据访问类,使您计划从中调用的方法返回响应您期望。

另一方面,如果您实际上是在测试数据访问类本身,那么您将使用一个fixture - 一个填充了您知道的数据的测试数据库。然后测试数据访问类是否返回了正确的数据。

答案 2 :(得分:3)

我认为您需要对单元测试进行一些阅读。要回答关于您应该测试的案例的第一个问题,建议您阅读Boundary-Value testingequivalence partitioning。在你的情况下,是的,你断言输出是真还是假,但有多个前提条件可以导致相同的结果?如果是这样,需要进行测试。

关于返回值取决于数据库的第二个问题。这严格来说不是单元测试(即它涉及多个单元)。我建议您花一些时间阅读mock objects

答案 3 :(得分:2)

单元测试只意味着您获得了预期的输出。为您的程序可能处于的每个可想象的,独特的状态编写测试,并确保您的功能输出符合您的预期。

例如,您可以在数据库为空,几行或完整的情况下进行测试。

然后对于每个状态,给出不同的输入(一对无效,一对有效)。

单元测试只是将您的程序分解为单元并确保每个单元按预期工作。

编辑:

维基百科有一篇关于unit testing的精彩文章。

答案 4 :(得分:2)

对于单元测试,您试图隔离并测试某些代码片段。您可以通过提供输入来执行此操作,以便在代码正常工作时知道答案应该是什么。如果您正在测试函数是否正确返回布尔值,那么您需要提供您知道将评估为“false”的输入,然后检查以确保该函数确实返回“false”。您还需要编写一个应该评估为“true”的测试。事实上,在你确信函数按预期工作之前,用尽可能多的不同输入编写尽可能多的测试。

在使用数据库进行单元测试时似乎有不同意见。有些人认为,如果您使用的是正在执行集成测试的数据库。无论如何,对于单元测试,您应该知道输入是什么,并知道预期答案应该是什么。您对要测试的内容的解释与单元测试的实际情况不符。一旦建议创建一个每次运行单元测试时始终包含相同数据的测试数据库。这样,您始终可以知道输入是什么,并知道输出应该是什么。您可以通过创建内存数据库(如Hypersonic)来实现此目的。

希望这有帮助!

答案 5 :(得分:1)

如果你允许我提出建议,请参阅Roy Osherove撰写的这本书:单位测试艺术http://amzn.com/1933988274。这不是一本巨大的武器 - 大规模的书。

在本书之前,我从未读过有关UnitTesting的任何内容,但现在很清楚UnitTest是如何工作的。

希望它有所帮助!

答案 6 :(得分:0)

我应该指出,单元测试不只是关于你的功能给出的结果;它也是关于它们如何变异/影响其他物体的。从某种意义上说,它们测试在对象之间传递的消息。