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

发表于:2014-05-27来源:外刊It评论作者:不详点击数: 标签:测试驱动开发
3、一次测试太多的项目 看看下面的单元测试,请在不使用和这个词的情况下描述它: 01.[TestMethod] 02.public void ProductPriceTests() 03.{ 04. // Arrange 05. var product

  3、一次测试太多的项目

  看看下面的单元测试,请在不使用“和”这个词的情况下描述它:

  01.[TestMethod]

  02.public void ProductPriceTests()

  03.{

  04. // Arrange

  05. var product = new Product()

  06. {

  07. BasePrice = 10m

  08. };

  09.

  10. // Act

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

  12. decimal discountPrice = product.CalculatePrice(CalculationRules.Discounted);

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

  14.

  15. // Assert

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

  17. Assert.AreEqual(11m, discountPrice);

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

  19.}

  我只能这样描述这个方法:

  “测试中计算基价,打折价和标准价是都能否返回正确的值。”

  这是一个简单的方法来判断你是否一次测试了过多的内容。上面这个测试会有三种情况导致它失败。如果测试失败,我们需要去找到那个/哪些出了错。

  理想情况下,每一个方法都应该有它自己的测试,例如:

  01.[TestMethod]

  02.public void CalculateDiscountedPriceReturnsAmountOf11()

  03.{

  04. // Arrange

  05. var product = new Product()

  06. {

  07. BasePrice = 10m

  08. };

  09.

  10. // Act

  11. decimal discountPrice = product.CalculatePrice(CalculationRules.Discounted);

  12.

  13. // Assert

  14. Assert.AreEqual(11m, discountPrice);

  15.}

  16.

  17.[TestMethod]

  18.public void CalculateStandardPriceReturnsAmountOf12()

  19.{

  20. // Arrange

  21. var product = new Product()

  22. {

  23. BasePrice = 10m

  24. };

  25.

  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);

原文转自:http://www.vaikan.com/top-5-tdd-mistakes/