相关疑难解决方法(0)

你如何对单元测试进行单元测试?

我在MVCStoreFront应用程序上观看Rob Connerys的网络广播,我注意到他甚至是最普通的东西,例如:

public Decimal DiscountPrice
{
   get
   {
       return this.Price - this.Discount;
   }
}
Run Code Online (Sandbox Code Playgroud)

会有一个测试像:

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,80);
}
Run Code Online (Sandbox Code Playgroud)

虽然,我都是单元测试,但我有时想知道这种形式的测试首次开发是否真的有益,例如,在实际过程中,您的代码上方有3-4层(业务请求,需求文档,架构文档) ,实际定义的业务规则(折扣价格是价格 - 折扣)可能被错误定义.

如果是这种情况,您的单元测试对您来说毫无意义.

此外,您的单元测试是另一个失败点:

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,90);
}
Run Code Online (Sandbox Code Playgroud)

现在测试存在缺陷.显然,在一个简单的测试中,这没什么大不了的,但是我们说我们正在测试一个复杂的业务规则.我们在这里获得了什么?

快速推进应用程序生命的两年,当维护开发人员维护它时.现在业务改变了规则,测试再次中断,一些菜鸟开发人员然后错误地修复了测试......我们现在又有了另一个失败点.

我所看到的只是更多可能的失败点,没有真正有益的回报,如果折扣价格错误,测试团队仍然会发现问题,单元测试如何保存任何工作?

我在这里错过了什么?请教我爱TDD,因为到目前为止我很难接受TDD.我也想要,因为我想保持进步,但这对我来说没有意义.

编辑:有几个人一直提到测试有助于执行规范.根据我的经验,规范也是错误的,通常是错误的,但也许我注定要在一个组织中工作,这些组织的规范是由那些不应该编写规范的人编写的.

tdd agile test-first

89
推荐指数
9
解决办法
4444
查看次数

你的单位测试有多深?

我发现关于TDD的事情是它需要时间来设置你的测试并且自然是懒惰的我总是想写尽可能少的代码.我似乎做的第一件事是测试我的构造函数已经设置了所有的属性,但这是否有点过分?

我的问题是你在单元测试中写出了什么级别的粒度?

..是否有一个测试太多的情况?

tdd unit-testing

88
推荐指数
7
解决办法
8万
查看次数

应该测试内部实现,还是仅测试公共行为?

给定软件......

  • 该系统由几个子系统组成
  • 每个子系统由几个组件组成
  • 每个组件都使用许多类实现

...我喜欢编写每个子系统或组件的自动化测试.

我没有为组件的每个内部类编写测试(因为每个类都有助于组件的公共功能,因此可以通过组件的公共API从外部测试/测试).

当我重构组件的实现时(我经常这样做,作为添加新功能的一部分),因此我不需要改变任何现有的自动化测试:因为测试仅依赖于组件的公共API和公共API通常是扩大而不是改变.

我认为这个政策与重构测试代码这样的文件形成了鲜明的对比,后者说...

  • "......单元测试..."
  • "......系统中每个班级的测试班......"
  • "......测试代码/生产代码比率...理想地被认为接近1:1的比例......"

...所有这些我认为我不同意(或至少不练习).

我的问题是,如果你不同意我的政策,你会解释原因吗?在什么情况下这种测试程度不足?

综上所述:

  • 公共接口经过测试(并经过重新测试),很少改变(它们被添加到但很少被改变)
  • 内部API隐藏在公共API之后,可以在不重写测试公共API的测试用例的情况下进行更改

脚注:我的一些"测试用例"实际上是作为数据实现的.例如,UI的测试用例包含数据文件,其中包含各种用户输入和相应的预期系统输出.测试系统意味着拥有测试代码,该代码读取每个数据文件,将输入重放到系统中,并断言它获得相应的预期输出.

虽然我很少需要更改测试代码(因为公共API通常是添加而不是更改),但我发现有时候(例如每周两次)需要更改一些现有的数据文件.当我更好地更改系统输出(即新功能改进现有输出)时可能会发生这种情况,这可能导致现有测试"失败"(因为测试代码只会尝试断言输出没有改变).要处理这些情况,我会执行以下操作:

  • 重新运行自动化测试套件,该套件有一个特殊的运行时标志,告诉它不要断言输出,而是将新输出捕获到新目录中
  • 使用可视化差异工具查看哪些输出数据文件(即哪些测试用例)已更改,并验证这些更改是否正常并且符合新功能的预期
  • 通过将新目录中的新输出文件复制到运行测试用例的目录(覆盖旧测试)来更新现有测试

脚注:通过"组件",我的意思是"一个DLL"或"一个组件"...这个大到足以在系统的体系结构或部署图上可见,通常使用数十个或100个类实现,以及因此与公共API只包含约1或接口少数......一些可能被分配到的开发商之一的团队(其中不同的组件被分配到不同的团队),并且将根据康威定律有一个相对稳定的公共API.


脚注:文章面向对象测试:神话与现实说,

神话:黑盒测试就足够了. 如果您使用类接口或规范仔细测试测试用例设计,则可以确保该类已经完全运用.白盒测试(查看方法的实现来设计测试)违反了封装的概念.

现实:OO结构很重要,第二部分.许多研究表明,开发人员认为黑盒测试套件非常彻底,只能在测试实施中使用三分之一到一半的语句(更不用说路径或状态)了.这有三个原因.首先,选择的输入或状态通常执行正常路径,但不强制所有可能的路径/状态.其次,单独的黑盒测试无法揭示惊喜.假设我们已经测试了被测系统的所有指定行为.为了确信没有未指明的行为,我们需要知道系统的任何部分是否未被黑盒测试套件执行.获取此信息的唯一方法是通过代码检测.第三,通常很难在不检查源代码的情况下执行异常和错误处理.

我应该补充一点,我正在进行白盒功能测试:我看到了代码(在实现中),我编写了功能测试(驱动公共API)来练习各种代码分支(功能实现的细节).

refactoring integration-testing automated-tests unit-testing code-coverage

44
推荐指数
4
解决办法
1万
查看次数