PHPUnit袖珍指南 第十二章 测试的其他用途

 
一旦你开始写自动测试,你就会想要发掘更多用途。以下是一些例子。
 
12-1. 敏捷文档
通常来说,在采用敏捷方法作为开发流程的项目中,如极限编程,文档很难和迅速变化的项目设计和代码同步。极限编程要求集体拥有代码,应此,每个开发人员都熟悉整个系统。如果你严格按照规定,编写的类具有自说明能力,你就可以用PHPUnit的TextDox功能根据测试来自动生成文档。这种文档给开发人员对每个类的用途描绘了一个概貌。
 
PHPUnit的TestDoc功能查找测试类的所有方法的名字,把它们转换成句子,如:testBalanceIsInitiallyZero( )变成“Balance is initially zero。”如果有几个测试方法名字的不同只在于前缀或数字,如testBalanceCannotBecomeNegative( ) 和 testBalanceCannotBecomeNegative2( ),转换过的句子“Balance cannot become negative”只会出现一次,其他这样的测试都会成功。
 
以下代码显示用PHPUnit 生成的关于银行帐号(Bank Account)类的敏捷文档,命令是:
phpunit --testdox-text BankAccountTest.txt BankAccountTest
结果显示:
BankAccount
 - Balance is initially zero
 - Balance cannot become negative
 
也可以用--testdox-html BankAccountTest.htm选项生成HTML格式的敏捷文档。
 
敏捷文档也用以用于为项目中的第三方包的假定条件来记录文档。当你使用一个外部包的时候,你也在冒一定的风险。外部包可能不想你预期的那样工作,或在未来版本中有微妙变化,导致你的代码不可运行。你也通过对外部包的假定条件编写测试来解决这个问题。如果你的测试成功了,你的假定条件还是有效。如果你对所有假定条件的测试都作了文档,那么,外部包的版本问题将不再是个问题:如果测试成功了,你的系统还会正常运行。
 
 
12-2.跨团队测试
当你将测试的假定条件文档化后,你就要为你的测试负责。你和包的提供者一起确定这些假设,你要记住,包的提供者对你的测试一无所知。如果你想要与包的提供者形成更密切的关系,你可以使用测试来沟通协调相关活动。
当你同意和包的供应商协调活动时, 你们可以一起写测试。 这样做,测试会显露出尽可能许多的假定。隐藏假定条件会导致合作失败。通过测试,你可以在提供的包中地将你的期望准确记入文档。当所有的测试运行完毕时,包的供应商就知道它正常运行了。
使用残根(参见本书前面的“残根”一章),你能进一步减弱和包供应商之间的耦合。供应商的工作是测试能够运行在包的真正实现上。你的工作是测试运行在自己的代码上。在你得到供应商的包的真正的实现之前,你使用残根工作。用这种方法,两个团队能够独立工作。
 
12-3 调试测试
当你得到一份缺陷报告时,你的第一冲动也许是赶快修复它。经验表明,这种冲动效果不好:修复此缺陷可能会导致其它缺陷。
你应该通过检查如下列表来控制冲动:
-          再次核实一下,确信你能重现缺陷。
-          发现最小范围的出现缺陷的代码。例如,输出时如果数字不正确,找到计算那个数字的对象。
-          写一个自动化的测试,如果该缺陷被修复,此测试会通过,反之会失败。
-          修复缺陷。
发现缺陷的最小可靠再现部分提供了一个发现缺陷真正原因的机会。你写的测试将会提高正确修复缺陷的机会,因为新的测试减少了当未来代码改变时取消本次修复的可能性。
前面所写的所有测试都会减少因疏忽而造成其它问题的可能性。
 
12-4 重构
重构是一种改进现有的代码的设计的受控技术,只有当你有一套测试套件时才能被安全的应用。否则,你也许没有注意到当你修改结构时系统崩溃了。 重构可以分解为一系列行为保留的小的改进,这种改进不会改变程序的行为。
以下情况将帮助你改进项目的代码和设计,使用单位测试验证重构的变革步奏是行为保留的,不会引入其它错误:
-          所有单位测试运行正确。
-          代码传达它的设计意图。
-          代码没有冗余。
-          代码只包含最小数量的类和方法。
 
--------------------------------------------------------------------------------------------------------------------
原文:
Chapter 12. Other Uses for Tests
Once you get used to writing automated tests, you will likely discover more uses for tests. Here are some examples.
 
12-1. Agile Documentation
Typically, in a project that is developed using an agile process, such as Extreme Programming, the documentation cannot keep up with the frequent changes to the project's design and code. Extreme Programming demands collective code ownership, so all developers need to know how the entire system works. If you are disciplined enough to use "speaking names" for your tests that describe what a class should do, you can use PHPUnit's TestDox functionality to generate automated documentation for your project based on its tests. This documentation gives developers an overview of what each class of the project is supposed to do.
 
PHPUnit's TestDox functionality looks at a test class and all the test method names and converts them from camel case PHP names to sentences: testBalanceIsInitiallyZero( ) becomes "Balance is initially zero." If there are several test methods whose names differ only by a suffix of one or more digits, such as testBalanceCannotBecomeNegative( ) and testBalanceCannotBecomeNegative2( ), the sentence "Balance cannot become negative" will appear only once, assuming that all of these tests succeed.
 
The following code shows the agile documentation for the Bank Account class (in Example 10) generated by running phpunit --testdox-text BankAccountTest.txt BankAccountTest:
 
    BankAccount
     - Balance is initially zero
     - Balance cannot become negative
 
 
 
Alternatively, the agile documentation can be generated in HTML format by using --testdox-html BankAccountTest.htm.
 
Agile documentation can be used to document the assumptions you make about the external packages in your project. When you use an external package, you are exposed to the risks that the package will not behave as you expect, and that future versions of the package will change in subtle ways that will break your code, without you knowing it. You can address these risks by writing a test about how the external package works every time you make an assumption. If your test succeeds, your assumption is valid. If you document all your assumptions with tests, future releases of the external package will be no cause for concern: if the tests succeed, your system should continue working.
 
12-2. Cross-Team Tests
When you document assumptions with tests, you own the tests. The supplier of the packagewho you make assumptions aboutknows nothing about your tests. If you want a closer relationship with the supplier of a package, you can use the tests to communicate and coordinate your activities.
 
When you agree on coordinating your activities with the supplier of a package, you can write the tests together. Do this in such a way that the tests reveal as many assumptions as possible. Hidden assumptions are the death of cooperation. With the tests, you document exactly what you expect from the supplied package. The supplier will know the package is complete when all the tests run.
 
By using stubs (see the section "Stubs," earlier in this book), you can further decouple yourself from the supplier. The job of the supplier is to make the tests run with the real implementation of the package. Your job is to make the tests run for your own code. Until such time as you have the real implementation of the supplied package, you use stub objects. Following this approach, the two teams can develop independently.
 
12-3. Debugging Tests
When you get a defect report, your impulse might be to fix the defect as quickly as possible. Experience shows that this impulse will not serve you well; it is likely that the fix for the defect will cause another defect.
 
You can hold your impulse in check by doing the following:
 
Verifying that you can reproduce the defect.
 
Finding the smallest-scale demonstration of the defect in the code. For example, if a number appears incorrectly in an output, find the object that is computing that number.
 
Writing an automated test that fails but will succeed when the defect is fixed.
 
Fixing the defect.
 
Finding the smallest reliable reproduction of the defect gives you the opportunity to really examine the cause of the defect. The test you write will improve the chances that when you fix the defect, you really fix it, because the new test reduces the likelihood of undoing the fix with future code changes.
 
All the tests you wrote before reduce the likelihood of inadvertently causing a different problem.
 
12-4. Refactoring
Refactoring, the controlled technique for improving the design of an existing code base, can be applied safely only when you have a test suite. Otherwise, you might not notice the system breaking while you are carrying out the restructuring. Refactoring can be broken down into a series of small behavior-preserving transformations.
 
The following conditions will help you to improve the code and design of your project, while using unit tests to verify that the refactoring's transformation steps are, indeed, behavior- preserving and do not introduce errors:
 
All unit tests run correctly.
 
The code communicates its design principles.
 
The code contains no redundancies.
 
The code contains the minimal number of classes and methods.
 
 
阅读更多
想对作者说点什么?
相关热词

博主推荐

换一批

没有更多推荐了,返回首页