测试驱动开发上的五大错误(4)

发表于:2013-06-18来源:外刊IT评论作者:不详点击数: 标签:tdd
26. // Act 27. decimal standardPrice = product.CalculatePrice(CalculationRules.Standard); 28. 29. // Assert 30. Assert.AreEqual(12m, standardPrice); 31.} 32. 33.[TestMethod] 34.public void NoDiscountR

  26. // Act

  27. decimal standardPrice = product.CalculatePrice(CalculationRules.Standard);

  28.

  29. // Assert

  30. Assert.AreEqual(12m, standardPrice);

  31.}

  32.

  33.[TestMethod]

  34.public void NoDiscountRuleReturnsBasePrice()

  35.{

  36. // Arrange

  37. var product = new Product()

  38. {

  39. BasePrice = 10m

  40. };

  41.

  42. // Act

  43. decimal basePrice = product.CalculatePrice(CalculationRules.None);

  44.

  45. // Assert

  46. Assert.AreEqual(10m, basePrice);

  47.}

  注意这些非常具有描述性的测试名称。如果一个项目里有500个测试,其中一个失败了,你能根据名称就能知道哪个测试应该为此承担责任。

  这样我们可能会有更多的方法,但换来的好处是清晰。我在《代码大全(第2版)》里看到了这句经验之谈:

  为方法里的每个IF,And,Or,Case,For,While等条件写出独立的测试方法。

  驱动测试开发纯粹主义者可能会说每个测试里只应该有一个断言。我想这个原则有时候可以灵活处理,就像下面测试一个对象的属性值时:

  01.public Product Map(ProductDto productDto)

  02.{

  03. var product = new Product()

  04. {

  05. ID = productDto.ID,

  06. Name = productDto.ProductName,

  07. BasePrice = productDto.Price

  08. };

  09.

  10. return product;

  11.}

  我不认为为每个属性写一个独立的测试方法进行断言是有必要的。下面是我如何写这个测试方法的:

  01.[TestMethod]

  02.public void ProductMapperMapsToExpectedProperties()

  03.{

  04. // Arrange

  05. var mapper = new ProductMapper();

  06. var productDto = new ProductDto()

  07. {

  08. ID = "sp-001",

  09. Price = 10m,

  10. ProductName = "Super Product"

  11. };

  12.

  13. // Act

  14. Product product = mapper.Map(productDto);

  15.

  16. // Assert

  17. Assert.AreEqual(10m, product.BasePrice);

  18. Assert.AreEqual("sp-001", product.ID);

  19. Assert.AreEqual("Super Product", product.Name);

  20.}

  4、先写程序后写测试

  我坚持认为,驱动测试开发的意义远高于测试本身。正确的实施驱动测试开发能巨大的提高开发效率,这是一种良性循环。我看到很多开发人员在开发完某个功能后才去写测试方法,把这当成一种在提交代码前需要完成的行政命令来执行。事实上,补写测试代码只是驱动测试开发的一个内容。

  如果不是按照先写测试后写被测试程序的红,绿,重构方法原则,测试编写很可能会变成一种体力劳动。

  如果想培养你的单元测试习惯,你可以看一些关于TDD的材料,比如The String Calculator Code Kata。

  5、测试的过细

  请检查下面的这个方法:

  1.public Product GetByID(string id)

  2.{

  3. return _productRepository.GetByID(id);

  4.}

  这个方法真的需要测试吗?不,我也认为不需要。

  驱动测试纯粹主义者可能会坚持认为所有的代码都应该被测试覆盖,而且有这样的自动化工具能扫描并报告程序的某部分内容没有被测试覆盖,然而,我们要当心,不要落入这种给自己制造工作量的陷阱。

  很多我交谈过的反对驱动测试开发的人都会引用这点来作为不写任何测试代码的主要理由。我对他们的回复是:只测试你需要测试的代码。我的观点是,构造器,geter,setter等方法没必要特意的测试。让我们来加深记忆一下我前面提到的经验论:

  为方法里的每个IF,And,Or,Case,For,While等条件写出独立的测试方法。

  如果一个方法里没有任何一个上面提到的条件语句,那它真的需要测试吗?

  祝测试愉快!

原文转自:http://www.aqee.net/top-5-tdd-mistakes/