什么是单元测试,你是如何做到的?

时间:2009-03-16 21:57:29

标签: unit-testing

许多帖子的完全重复:

What is unit testing?
 What Makes a Good Unit Test?
 New to Unit Testing
 Unit Testing - definitions
 Learning Unit Testing
 How to properly mock and unit test
 Unit Testing: Beginner Questions
 And many more ...
 另外,Google为site:stackoverflow.com "how do you" unit-test

我已经阅读了一些关于单元测试的问题,但我并不确切知道它是什么或者你是如何做到的。我希望有人能告诉我以下内容:

  • IS单元测试究竟是什么?它是内置到代码中还是作为单独的程序运行?或其他什么?
  • 你是怎么做到的?
  • 什么时候应该这样做?是否有时间或项目不这样做?一切都是可以测试的吗?

非常感谢你的帮助。

7 个答案:

答案 0 :(得分:148)

什么是单元测试?

单元测试只是验证各个代码单元(主要是函数)是否按预期工作。通常你自己编写测试用例,但有些可以自动生成。

测试的输出可以像控制台输出一样简单,也可以像green light这样的GUI中的“NUnit”或不同的语言特定框架。

执行单元测试的目的很简单,通常测试是以函数的形式编写的,这些函数将确定返回值是否等于编写函数时所期望的值(或者期望的值) 最终编写它时 - 在您首先编写测试时,这称为Test Driven Development

您如何进行单元测试?

想象一下你想要测试一个非常简单的函数:

int CombineNumbers(int a, int b) {
    return a+b;
}

单元测试代码如下所示:

void TestCombineNumbers() {
    Assert.IsEqual(CombineNumbers(5, 10), 15); // Assert is an object that is part of your test framework
    Assert.IsEqual(CombineNumbers(1000, -100), 900);
}

当您运行测试时,您将被告知这些测试已通过。现在您已经构建并运行了测试,您知道这个特定的函数或单元将按预期执行。

现在想象另一位开发人员出现并更改CombineNumbers()函数以获得性能或其他原因:

int CombineNumbers(int a, int b) {
    return a * b;
}

当开发人员运行您为这个非常简单的函数创建的测试时,他们会看到第一个Assert失败,他们现在知道构建已经破坏。

何时应进行单元测试?

他们应该尽可能多地完成。当您在开发过程中执行测试时,您的代码将自动设计得比您刚编写函数然后继续进行设计更好。此外,诸如Dependency Injection之类的概念将自然地演变为您的代码。

最明显的好处是知道在进行更改时,如果所有代码都通过了测试,则不会受到其他单个代码单元的影响。

答案 1 :(得分:49)

单元测试涉及将程序分解成碎片,并对每个部分进行一系列测试。

通常,测试作为单独的程序运行,但测试方法因语言和软件类型(GUI,命令行,库)而异。

大多数语言都有unit testing frameworks,您应该为自己查看一个。

测试通常定期运行,通常在每次更改源代码后运行。越多越好,因为你越早发现问题。

答案 2 :(得分:13)

什么...

针对一系列测试自动测试代码的方法,旨在实施预期结果并管理变更。

在这个意义上,“单位”是代码中最小的原子组件,对测试有意义,通常是一些类的方法。此过程的一部分是构建存根对象(或“模拟”),它允许您将单元作为独立对象使用。

如何...

几乎总是,单元测试的过程内置于IDE(或通过扩展),以便它在每次编译时执行测试。存在许多框架用于帮助创建单元测试(实际上是模拟对象),通常命名为 foo Unit(参见jUnit,xUnit,nUnit)。这些框架提供了一种创建测试的形式化方法。

作为一个过程,测试驱动开发(TDD)通常是单元测试的动机(但单元测试不需要TDD),假设测试是规范定义的一部分,因此要求首先编写它们,只编写代码以“解决”这些测试。

:当...

总是

几乎。非常小的一次性项目可能不值得,但只有当你确定它们真的是一次性的时候。理论上,每个面向对象的程序都是可单元测试的,但是一些设计模式使这很困难。众所周知,单例模式存在问题,相反,依赖性注入框架非常以单元测试为导向。

答案 3 :(得分:5)

什么是单元测试?定义很棘手。在技​​术层面,您可以构建调用代码库中的函数并验证结果的函数。基本上,你得到一些诸如“assert(5 + 3)== 8”之类的东西,只是更复杂(如DataLayer(MockDatabase())。getUser()。name ==“Dilbert”)。 在工具视图级别,您可以添加一个自动的,特定于项目的检查,如果所有内容仍然像您认为的那样有效。如果您重构并且实现复杂的算法,这非常非常有用。 结果通常是一堆文档和更少的错误,因为代码的行为被固定下来。

我为所有边缘情况构建测试用例并运行它们类似于世代垃圾收集器的工作方式。当我实现一个类时,我只运行涉及该类的测试用例。完成该课程后,我会运行所有单元测试,以查看是否一切仍然有效。

只要测试代码很容易保持未经测试,您应该尽可能多地进行测试。鉴于此,不,并非所有事情都能以理智的方式进行测试。想想用户界面。想想一个航天飞机或核弹的驱动程序(至少不是纯粹的JUnit测试;))。但是,很多代码都是可测试的。数据结构是。算法是。大多数Applicationlogic类都是。所以测试吧!

HTH。 tetha

答案 4 :(得分:2)

我发现说明它的最简单方法是查看一些代码。 NUnit网站上的这个入门页面很好地介绍了什么以及如何

http://www.nunit.org/index.php?p=quickStart&r=2.5

一切都可以测试吗?通常,如果它计算的东西然后是。 UI代码是另一个需要处理的问题,因为模拟用户点击按钮很棘手。

你应该测试什么?我倾向于围绕我知道会变得棘手的事情编写测试。复杂的状态转换,业务关键计算,这类事情。一般来说,我并不太担心测试基本的输入/输出内容,尽管纯粹主义者无疑会说我在前面错了,应该测试所有。像许多其他事情一样,没有正确答案!

答案 5 :(得分:1)

  

IS单元测试究竟是什么?是吗   内置到代码中或作为单独运行   程式?或其他什么?

From MSDN:单元测试的主要目标是在应用程序中使用最小的可测试软件,将其与代码的其余部分隔离开来,并确定它是否完全符合您的预期。

基本上,您正在编写一小段代码来测试代码的各个位。在.net世界中,您可以使用NUnit或MBunit等内容运行这些小代码,甚至可以使用Visual Studio中的内置测试工具。在Java中,您可以使用JUnit。基本上,测试运行者将构建您的项目,加载并执行单元测试,然后让您知道它们是否通过。

  

你是怎么做到的?

说单元测试说起来容易做起来难。要善于完成它需要相当多的练习。您需要以便于单元测试以使测试有效的方式构建代码。

  

什么时候应该这样做?是否有时间或项目不这样做?是   一切都可以测试?

你应该在有意义的地方去做。并非所有东西都适合单元测试。例如,UI代码非常难以进行单元测试,您通常无法从中获益。但是,业务层代码通常非常适合测试,而且大多数单元测试都是针对测试的。

单元测试是一个很大的主题,为了充分了解它如何最有利于你,我建议你拿一本关于单元测试的书,比如“Test Driven Development by Example”,这将让你掌握一把关于概念以及如何将它们应用于您的代码。

答案 6 :(得分:1)

关于“如何做”部分:

我认为ScalaTest的介绍可以很好地说明不同风格的单元测试。

关于“何时去做”部分:

单元测试不仅用于测试。通过单元测试,您还可以将软件设计强制为可单元测试的。许多人认为,无论测试的其他好处如何,这种设计大部分都是Good Design(TM)。

因此,进行单元测试的一个原因是强制您的设计成为一种有希望更容易维护的东西,而不是为单元测试而设计的东西。