Google测试精华文章(1) - 测试行为,而非实现
2014-02-21 16:14
337 查看
Your trusty Calculator class is one of your most popular open source projects, with many happy users:
假设类Calculator是你最受欢迎的开源项目之一,有很多的使用者:
You also have tests to help ensure that it works properly:
并且你还针对这个类写了些测试来确保这个类工作正常:
However, a fancy new library promises several orders of magnitude speedup in your code if you use it in place of the addition operator. You excitedly change your code to use this library:
然而,有一天,你发现有一个奇特的新库(Library)能保证如果你用这个库代替以前的加法操作的话,你的代码性能提升好几个数量级。于是你欣然修改了你的代码去使用这个库:
That was easy, but what do you do about the tests for this code? None of the existing tests should need to change since you only changed the code's implementation, but its user-facing behavior didn't change. In most cases, tests should focus on testing your code's public API, and your code's implementation details shouldn't need to be exposed to tests.
这很简单,但是测试代码怎么办?需要修改吗?当然不用做任何的修改,因为你只改变代码的实现,而没改变代码面向使用者的行为。在大多数情况下,测试应该只专注于测试你代码的公共API,而代码的具体实现应该是隐藏的,不应该被测试。
Tests that are independent of implementation details are easier to maintain since they don't need to be changed each time you make a change to the implementation. They're also easier to understand since they basically act as code samples that show all the different ways your class's methods can be used, so even someone who's not familiar with the implementation should usually be able to read through the tests to understand how to use the class.
测试独立于实现会使得其更容易去维护,因为当你只是修改功能的实现时,不用每次都去改case。而且这样的测试也更容易理解,因为这些测试基本上可以当作你的Code samples,能够展示使用你的类的方法的所有方式,所以即使有人不熟悉你的代码实现,也能通过读你的测试用例来理解如何使用这些类。
There are many cases where you do want to test implementation details (e.g. you want to ensure that your implementation reads from a cache instead of from a datastore), but this should be less common since in most cases your tests should be independent of your implementation.
当然也确实有很多Cases想要测试具体代码的实现细节(比如:你想要确保你确实是从一个Cache里读数据而不是从Datastore里),但是这应该不太常见因为在大多数情形里你的测试应该独立于你的具体实现。
Note that test setup may need to change if the implementation changes (e.g. if you change your class to take a new dependency in its constructor, the test needs to pass in this dependency when it creates the class), but the actual test itself typically shouldn't need to change if the code's user-facing behavior doesn't change.
注意Test Setup可能会跟着实现改变(比如,如果你修改你的类让其依赖于它的构造函数,那么在创建这个类时,你就得在你的测试里传入这个依赖对象), 但是实际上,只要代码对于使用者来说行为不变,那么Test也就不用变。
如果您看了本篇博客,觉得对您有所收获,请点击下面的 [推荐]
如果您想转载本博客,请注明出处
如果您对本文有意见或者建议,欢迎留言
PS:欢迎大家加PowerMock交流群(332365691),一起交流讨论~
假设类Calculator是你最受欢迎的开源项目之一,有很多的使用者:
public class Calculator { public int add(int a, int b) { return a + b; } }
You also have tests to help ensure that it works properly:
并且你还针对这个类写了些测试来确保这个类工作正常:
public void testAdd() { assertEquals(3, calculator.add(2, 1)); assertEquals(2, calculator.add(2, 0)); assertEquals(1, calculator.add(2, -1)); }
However, a fancy new library promises several orders of magnitude speedup in your code if you use it in place of the addition operator. You excitedly change your code to use this library:
然而,有一天,你发现有一个奇特的新库(Library)能保证如果你用这个库代替以前的加法操作的话,你的代码性能提升好几个数量级。于是你欣然修改了你的代码去使用这个库:
public class Calculator { private AdderFactory adderFactory; public Calculator(AdderFactor adderFactory) { this.adderFactory = adderFactory; } public int add(int a, int b) { Adder adder = adderFactory.createAdder(); ReturnValue returnValue = adder.compute(new Number(a), new Number(b)); return returnValue.convertToInteger(); } }
That was easy, but what do you do about the tests for this code? None of the existing tests should need to change since you only changed the code's implementation, but its user-facing behavior didn't change. In most cases, tests should focus on testing your code's public API, and your code's implementation details shouldn't need to be exposed to tests.
这很简单,但是测试代码怎么办?需要修改吗?当然不用做任何的修改,因为你只改变代码的实现,而没改变代码面向使用者的行为。在大多数情况下,测试应该只专注于测试你代码的公共API,而代码的具体实现应该是隐藏的,不应该被测试。
Tests that are independent of implementation details are easier to maintain since they don't need to be changed each time you make a change to the implementation. They're also easier to understand since they basically act as code samples that show all the different ways your class's methods can be used, so even someone who's not familiar with the implementation should usually be able to read through the tests to understand how to use the class.
测试独立于实现会使得其更容易去维护,因为当你只是修改功能的实现时,不用每次都去改case。而且这样的测试也更容易理解,因为这些测试基本上可以当作你的Code samples,能够展示使用你的类的方法的所有方式,所以即使有人不熟悉你的代码实现,也能通过读你的测试用例来理解如何使用这些类。
There are many cases where you do want to test implementation details (e.g. you want to ensure that your implementation reads from a cache instead of from a datastore), but this should be less common since in most cases your tests should be independent of your implementation.
当然也确实有很多Cases想要测试具体代码的实现细节(比如:你想要确保你确实是从一个Cache里读数据而不是从Datastore里),但是这应该不太常见因为在大多数情形里你的测试应该独立于你的具体实现。
Note that test setup may need to change if the implementation changes (e.g. if you change your class to take a new dependency in its constructor, the test needs to pass in this dependency when it creates the class), but the actual test itself typically shouldn't need to change if the code's user-facing behavior doesn't change.
注意Test Setup可能会跟着实现改变(比如,如果你修改你的类让其依赖于它的构造函数,那么在创建这个类时,你就得在你的测试里传入这个依赖对象), 但是实际上,只要代码对于使用者来说行为不变,那么Test也就不用变。
原文地址
Testing on the Toilet: Test Behavior, Not Implementation
如果您看了本篇博客,觉得对您有所收获,请点击下面的 [推荐]
如果您想转载本博客,请注明出处
如果您对本文有意见或者建议,欢迎留言
PS:欢迎大家加PowerMock交流群(332365691),一起交流讨论~
相关文章推荐
- 精华的微软文章".NET 数据访问架构指南",特别是数据库连接的测试.即监视链接池化 (2)
- 精华的微软文章".NET 数据访问架构指南",特别是数据库连接的测试.即监视链接池化 (2)
- 精华的微软文章".NET 数据访问架构指南",特别是数据库连接的测试.即监视链接池化(1)
- 利用google对特定站点进行测试的实现
- B+ Tree实现,可以参考另一篇文章进行磁盘读写测试
- 行为驱动:Cucumber + Selenium + Java(五) - 使用maven来实现cucumber测试和报告
- MySQL主从复制与读写分离在windows系统下的实现(amoeba3.0+mysql5.1实现)因版本问题,本文在原来文章基础上有更改并且本人已经测试成功
- seo优化之Google和Baidu Ping服务实现快速收录文章的java,php代码实现
- 行为驱动:Cucumber + Selenium + Java(三) - 使用标签实现测试分组
- seo优化之Google和Baidu Ping服务实现快速收录文章的java,php代码实现
- 利用google对特定站点进行测试的实现
- 行为驱动:Cucumber + Selenium + Java(四) - 实现测试用例的参数化
- 基于测试行为,而不是测试实现
- 精华的微软文章".NET 数据访问架构指南",特别是数据库连接的测试.即监视链接池化(1)
- 《How Google Tests Software》 - Google是如何测试软件的?
- AI决策算法 行为树实现(二)
- QueueUserApc实现DLL注入的测试
- java 实现以行为单位读取txt文件(1)
- 深入FFM原理与实践(转载美团点评的文章,准备自己实现一遍FFM)
- 用JSON 和 Google 实现全文翻译