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

rlb*_*ond 125 unit-testing

许多帖子的完全重复:

什么是单元测试?
什么是良好的单元测试?
新的单元测试
单元测试 - 定义
学习单元测试
如何正确模拟和单元测试
单元测试:初学者问题
还有更多...
另外,Google for site:stackoverflow.com"你好吗"单元测试

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

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

非常感谢您的帮助.

Joh*_*sch 154

什么是单元测试?

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

测试的输出可以像控制台输出一样简单,也可以是GUI中的" 绿灯 ",例如NUnit,或者是不同的语言特定框架.

执行单元测试的设计是简单的,一般的测试都写在函数的形式,将决定一个返回值是否等于当你写的函数(或价值你,你很期待值会想到,当你最终把它写- 当你首先编写测试时,这称为测试驱动开发.

你如何进行单元测试?

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

int CombineNumbers(int a, int b) {
    return a+b;
}
Run Code Online (Sandbox Code Playgroud)

单元测试代码看起来像这样:

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);
}
Run Code Online (Sandbox Code Playgroud)

运行测试时,将通知您这些测试已通过.现在您已经构建并运行了测试,您知道这个特定的功能或单元将按预期执行.

现在想象另一个开发人员出现并改​​变CombineNumbers()性能的功能,或其他一些原因:

int CombineNumbers(int a, int b) {
    return a * b;
}
Run Code Online (Sandbox Code Playgroud)

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

什么时候应该进行单元测试?

它们应该尽可能频繁地完成.当您在开发过程中执行测试时,您的代码将自动设计得比您刚编写函数然后继续进行设计更好.此外,依赖注入等概念将自然地演变为您的代码.

最明显的好处是知道在进行更改时,如果它们都通过了测试,则没有其他单独的代码单元受其影响.


Mat*_*ttJ 56

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

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

大多数语言都有单元测试框架,你应该为自己研究一下.

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


ann*_*ata 13

什么...

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

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

怎么样...

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

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

什么时候...

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


Tet*_*tha 5

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

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

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

HTH.tetha