??xml version="1.0" encoding="utf-8" standalone="yes"?>
单说来,他们Ҏ无从得知。开发h员编写那U运行不正常或只在某些情况下q行正常的代码是一个严重的问题。他们通常只测试代码能否在很少的情况下正常q行Q而不是验证代码能够在所有情况下均正常运行?/p>
发现软g错误的情冉|很多Q?
1.由首ơ编写代码的开发h员发现?
2.由尝试运行代码的开发h员发现?
3.q中的其他开发h员或试人员发现?
4.作ؓ产品大规模测试的一部分?
5.由最l用户发现?
如果在第一U情况下发现软g错误Q则修复错误比较ҎQ成本也很低。情况越靠后Q修复Y仉误的成本p高;修复一个由最l用户发现的软g错误可能要耗费 100 ?1000 倍的成本。更不用说用户通常因ؓ软g错误D工作无法l箋Q而一直等C一个版本才能解决问题?br> 如果开发h员能够在~写代码期间发现所有的软g错误Q那再好不q了。ؓ此,您必ȝ写能在编写代码时q行的测试?/p>
试是Y件开发的重要环节之一。按照Y件开发的q程试可分为:单元试、功能测试、性能试、性能试、集成测试、系l测试、域试QField testQ等。我们这里将主要研究的是面向E序员的单元试?/p>
什么是单元试
单元试是开发者编写的一段代码Q用于检验被代码中的一个很明确的功能是否正。通常而言Q一个单元测试是用于判断某个特定条gQ或者场景)下某个特 定函数的行ؓ。例如,你可能把一个很大的值放入一个有序list 中去Q然后确认该值出现在list 的尾部。或者,你可能会从字W串中删除匹配某U模式的字符Q然后确认字W串实不再包含q些字符了?/p>
单元试是由E序员自己来完成Q最l受益的也是E序员自己。可以这么说Q程序员有责ȝ写功能代码,同时也就有责Mؓ自己的代码编写单元测试。执行单元测试,是Z证明q段代码的行为和我们期望的一致?/p>
Z么要使用单元试
我们~写代码Ӟ一定会反复调试保证它能够编译通过。如果是~译没有通过的代码,没有MZ愿意交付l自q客户。但代码通过~译Q只是说明了它的语法正确Q我们却无法保证它的语义也一定正,没有M人可以轻易承D代码的行ؓ一定是正确的?/p>
q运Q单元测试会为我们的承诺做保证。编写单元测试就是用来验证这D代码的行ؓ是否与我们期望的一致。有了单元测试,我们可以自信的交付自q代码Q而没有Q何的后顾之忧?/p>
单元试有下面的q些优点Q?/p>
1、它是一U验证行为?/p>
E序中的每一功能都是测试来验证它的正确性。它Z后的开发提供支~。就是开发后期,我们也可以轻杄增加功能或更改程序结构,而不用担心这个过E中会破坏重要的东西。而且它ؓ代码的重构提供了保障。这P我们可以更自由的对E序q行改进?/p>
2、它是一U设计行为?/p>
~写单元试我们从调用者观察、思考。特别是先写试Qtest-firstQ,q我们把程序设计成易于调用和可试的,卌使我们解除Y件中的耦合?/p>
3、它是一U编写文的行ؓ?/p>
单元试是一U无L文Q它是展C函数或cd何用的最x档。这份文是可编译、可q行的,q且它保持最斎ͼ永远与代码同步?/p>
4、它h回归性?/p>
自动化的单元试避免了代码出现回归,~写完成之后Q可以随旉地的快速运行测试?
单元试的范?nbsp;
如果要给单元试定义一个明的范畴Q指出哪些功能是属于单元试Q这g很难。但下面讨论的四个问题,基本上可以说明单元测试的范畴Q单元测试所要做的工作?/p>
1?它的行ؓ和我期望的一致吗Q?/p>
q是单元试最Ҏ的目的,我们是用单元测试的代码来证明它所做的是我们所期望的?br>
2?它的行ؓ一直和我期望的一致吗Q?/p>
~写单元试Q如果只试代码的一条正\径,让它正确C遍,q不是真正的完成。Y件开发是一个项复杂的工E,在测试某D代码的行ؓ是否和你的期望一 致时Q你需要确认:在Q何情况下Q这D代码是否都和你的期望一_譬如参数很可疑、硬盘没有剩余空间、缓冲区溢出、网l掉U的时候?/p>
3?我可以依赖单元测试吗Q?/p>
不能依赖的代码是没有多大用处的。既然单元测试是用来保证代码的正性,那么单元试也一定要值得依赖?/p>
4?单元试说明我的意图了吗Q?/p>
单元试能够帮我们充分了解代码的用法Q从效果上而言Q单元测试就像是能执行的文Q说明了在你用各U条件调用代码时Q你所能期望这D代码完成的功能?/p>
不写试的借口
到这里,我们已经知道了用单元测试的U种理由。但目前的实际情冉|大多数程序员不进行单元测试,或只q行单的单元试。下面是一些他们常用的接口Q?/p>
1?~写单元试太花旉了?/p>
我们知道Q在开发时早发现BUGQ就能节省更多的旉Q降低更多的风险。如果你仍然认ؓ在编写品代码的时候,q是没有旉~写试代码Q那么请先考虑下面q些问题Q?/p>
1Q、对于所~写的代码,你在调试上面׃多少旉?br> 2Q、对于以前你自认为正的代码Q而实际上q些代码却存在重大的bugQ你׃多少旉在重新确认这些代码上面?br> 3Q、对于一个别人报告的bugQ你׃多少旉才找出导致这个bug 的源码位|?br> 回答完这些问题,你一定不再以“太花旉”作ؓ拒绝单元试的借口?/p>
2?q行试的时间太长了?/p>
合适的试是不会让q种情况发生的。实际上Q大多数试的执行都是非常快的,因此你在几秒之内可以运行成千上万个试。但是有时某些测试会p很长的时间。这Ӟ需要把q些耗时的测试和其他试分开。通常可以每天q行q种试一ơ,或者几天一ơ?/p>
3?试代码q不是我的工作?/p>
你的工作是保证代码能够正确的完成你的行为,恰恰相反Q测试代码正是你不可~少的工作?/p>
4?我ƈ不清楚代码的行ؓQ所以也无从测试?/p>
如果你实在不清楚代码的行为,那么估计现在q不是编码的时候。如果你q不知道代码的行为,那么你又如何知道你编写的代码是正的?
5?但是q些代码都能够编译通过?/p>
我们前面已经说过Q代码通过~译只是验证它的语法通过。但q不能保证它的行为就一定正?/p>
6?公司h来是Z写代码,而不是写试?/p>
公司付给你薪水是Z让你~写产品代码Q而单元测试大体上是一个工P是一个和~辑器、开发环境、编译器{处于同一位置的工兗?/p>
7?如果我让试员或者QAQQuality AssuranceQh员没有工作,那么我会觉得很内疚?/p>
你ƈ不需要担心这些。请CQ我们在此只是谈论单元测试,而它只是一U针Ҏ码的、低层次的,为程序员而设计的试。在整个目中,q有其他的很多测试需要这些h来完成,如:功能试、验收测试、性能试、环境测试、有效性测试、正性测试、正规分析等{?/p>
8?我的公司q不会让我在真实pȝ中运行单元测试?/p>
我们所讨论的只是针对开发者的单元试。也是_如果你可以在其他的环境下Q例如在正式的品系l中Q运行这些测试的话,那么它们׃再是单元试Q而是其他cd的测试了。实际上Q你可以在你的本行单元测试,使用你自q数据库?/p>
总而言之,单元试会让我们的开发工作变得更加轻松,让我们对自己的代码更加自信。无论是大型目q是型目Q无论是旉紧迫的项目还是时间宽裕的目Q只要代码不是一ơ写完永不改动,~写单元试׃定超|它已成ؓ我们~码不可~少的一部分?/p>