测试驱动开发笔记【初学者】

【基本步骤及流程】
     
  1. 根据问题进行初始的需求分析,提取出初始而不完备的【to-do】列表;
  
  2. 选择【 to-do】列表中的某个【to-do】, 编写相应的测试;
  
  3. 运行测试,发现无法通过;
  
  4. 作出最简单的的改进,并运行测试使之通过;
  
  5. 一小步一小步地重构代码、运行测试,并使之通过;
  
  6. 跳转至【2】。
  
  
  
  【关键要素】
  
  1.【to-do】列表: 需要完成的任务、当前要做的事情、标识完工。
  
  2. the effective test for the to-do chosen: 为 to-do 列表的 to-do 编写有效的测试;
  
  3. the simplest code for passing test: 使用最简单的方法使测试通过;
  
  4. code refactoring: 通过代码重构,使其符合良好的软件设计理念,并使测试通过。

【核心理念】 
  
  1. First Test Then Code: 【先测试后编码】的开发习惯
  
           始终保持【先写测试后编码实现】的开发习惯,这是测试驱动开发的最重要的宗旨。
  
  2. Teensy-weensy Steps: 【一小步一小步、化整为零】的前进策略
  
          ①   始终通过【一小步一小步、化整为零】 的策略来保证均匀地向前推进,不贪求局部快速,但求全局的前进步调。
               
          ②   通过 teensy-weensy steps 可以将复杂的开发、重构过程化解为简单的、容易实现的步骤。
               
   
    【核心理念解析】
    
   1. 测试驱动的开发,其主要意图就是使代码总是处于测试的监督之下。
    
            当进行代码重构和维护时,能够清晰地看到新的代码 对原有系统的影响,能够充满自信地进行重构和维护。
   
   2. 关于【一小步一小步前进,化整为零】的策略:
     
            ①    并不一定总是遵循【一小步一小步】的方式,而是使你【总是能够】一小步一小步的前进,最终达到终点;
                          
            ②   在测试驱动开发的理念中,新添一个小测试,无法通过测试、通过测试,都是向目标前进,都是进步。
      
            ③   如果急切地推进,违背【一小步一小步】的策略,当出现错误而无法通过测试时,就会僵在那里,而无法前进。             
             
           First make it works, Then make it right.
  
  
  
      【基本问题与解答】
      
   1. 如何开始【TDD】 ?  
   
              利用传统的问题分析技能,进行简单而初始的需求分析, 并形成初始的【 to-do】 列表;
                
              该【to-do】列表通常是对问题直观的理解得到的,是不完备的,在【测试-编码-重构】过程中会逐步加以完善。
      
   2. 完成初始【to-do】列表后的第一个步骤?
   
              以第一个测试开始,而不是编写第一个类开始。非常重要,谨记,要克服【先编码后测试】的惯性。
   
   3. 选取【to-do】列表中的哪个【to-do】?
   
              通常选择最容易实现的那个【to-do】,有时也凭直觉,但始终遵循【从最简单的地方入手】的原则。
   
   4. 如何为选定的【to-do】编写有效的测试?
   
              ①  一开始总是编写最直观最简单的测试;
                 
              ②  在代码重构阶段,可能会改变对象接口,从而需要对测试代码进行重构,   使测试仍然执行原有的测试功能,同时更加有效。
   
   5. 如何作出简单的改进尽快使测试通过?
                
              ①  通过构造空实现及存根方法,使测试尽快编译通过,但功能测试将失败;
                
              ②  使用蛮力的硬编码,使用能够想到的最简单的方法,不择手段。
  
   6. 如何重构代码,使测试通过?
   
              这是测试驱动开发的难点;要掌握良好的重构技术和软件设计素养才能更好的做好这一步。
                
               一个比较容易的方法是,一小步一小步地重构,重构之后立即运行测试。            
   
   7. 如何标识完工?
   
               每当通过代码重构使选定【to-do】的相应测试通过时,就从 to-do 列表上划掉它;  直至【to-do】列表上的所有【to-do】都被划掉为止。
                          
   8. 如何标识当前正在做的事情?
   
               在选定【to-do】上作某种标记,比如下划线,圈圈等。
                          
  
                          
      【高级话题及思考】
                
   9. 如何确保【to-do】列表能够完全地覆盖问题所要求的功能及约束 ?
    
           ①  当在开发过程中发现新的需求时,就将它添加到 to-do 列表中;【TDD】的需求分析是渐增式的。
                 
           ②  在所有【to-do】完成之后,还要进行综合测试审核,以保证确实完全地覆盖了问题所要求的功能及约束。
                  
                   【TDD】并不是要消除传统的测试阶段,而是使最后的单元测试、集成测试、验收测试等更容易进行, 降低测试和维护成本。
   
   10. 如何确保【TDD】所获得的软件总体设计是良好的、可扩展性强的?
   
                   【TDD】并非不注重软件设计;它在代码重构过程中引入了软件设计,  从而使软件通过渐增式的【局部最优设计】最终达到【全局最优设计】;这看上去类似【贪心策略】。
   
   11. 在【TDD】中,如何处理需求与测试之间的关系 ?
   
                   【TDD】将需求转化为【to-do】列表,然后进一步转化为测试集合。
                           
                    它将项目任务【以需求为中心】转化为【以测试为中心】,因此,必须保证测试集合的有效性,
                             
                     否则,即使通过了所有的测试,也毫无意义;测试集合必须能够完全表征所有的需求。
   
   12. 在【TDD】中,如何处理测试与设计之间的关系 ?
   
                    【TDD】并没有指明设计与测试之间的关系和先后顺序;
                           
                     测试代码也可能需要重构,以改善测试效果;测试代码的重构将带来产品代码的重构和变化。     
                  
                     测试驱动的开发需要运用大量的重构技术;  而在重构过程中引入良好的软件设计,实际上对软件设计的要求也是比较高的。                       
   
   13. 在【TDD】中,如何界定【一小步】?
   
                    【TDD】并不意味着非要机械地按上述步骤完成;这些步骤仅为初学者设计;
           
                     迭代步骤和节奏,可以根据自己的实际设计和编程水平而有所变化。       
   
   14. 【TDD】适用于哪些场合 ?如何将它运用于大型项目 ?
   
                     ①   对于小型项目而言,【TDD】完全能够胜任;
                                
                     ②   对于大型项目而言, 开发人员个体可以使用【TDD】来完成自己的模块任务;
                                
                     ③   【TDD】中测试、编码、设计工作如何分离和分工呢 ?
   
   15. 【TDD】如何保证测试是有效的 ?         
    
                   测试管理是【TDD】中一个关键点;如果测试不是有效的,就不能保证代码实现了所要求的功能。
                
                   必须有效地将需求转化为测试,使测试能够完全地表征需求。

【例外】                          
                           
        ①    有时,需要采取【以退为进】的策略,适当地降低设计的质量,回退到重复代码的状态,
          
                  以另一种重构来寻找突破口。
          
        ②    由于有了详尽的测试以及重构好的干净代码,通常只需要做实验来验证新想法是否可行,
                   
                   不需要绞尽脑汁对系统行为进行推理,害怕重构会破坏原有系统。        
   
        ③    在某些关键点上需要放慢速度,对设计思路进行仔细思量,来写出有效的测试,使接下来的系统构建具有良好的可扩展性;
            
                  即在编写测试之前进行设计考量;此时,可能需要丰富的实际设计经验来引导作出更好的决策。    
                  
        ④     极少量的情况下,会在亮红灯的情况下仍然贸然前进,编写新的测试;
        
        ⑤     编写用于调试的方法【比如 toString】及帮助类时,可以不写测试,而直接参与到重构过程中。

时间: 2024-12-08 23:55:14

测试驱动开发笔记【初学者】的相关文章

测试驱动开发实践

总是以为自己了解了测试驱动开发,其实做起来和了解根本不是一回事.原来觉得代码清晰得很,后来试验了一下才知道那是自己的错觉.这次,让我们抛却Eclipse的自动补全功能,来一场真正的测试驱动开发吧. 项目描述:这是一个很简单的项目,目标是扫描磁盘上所有特定格式的文件,将其路径存储下来,通过程序可以快捷搜索到文件路径并自动定位到该文件. 用户故事(简单点写了): 1.              扫描磁盘,将目录下的所有文件列出来,将特定格式的文件信息存储到磁盘. 2.              所有

测试驱动开发与Python

最近在看一本书<Test-Driven Development with Python>,里面非常详细的介绍了如何一步一步通过测试驱动开发(TDD)的方式开发Web项目.刚好这本书中使用了我之前所了解的一些技术,Django.selenium.unittest等.所以,读下来受益匪浅. 我相信不少开发都写单元测试,不过,一般是先写功能代码,然后,再写单元测试用例,在编写单元测试用例的过程中,可能需要调整功能代码,从而使单元测试用例通过.但是TDD就特别要求先写测试用例,后写实现代码.这一开始确

测试驱动开发(TDD)

在编写程序之前,先确定程序中的变量.控件等元素允许的值.若在编写程序时,变量.控件中的值与事先确定的值不相符,就说明程序的某处有bug,这种测试方法就是TDD(Test Driven Development,测试驱动开发).TDD与OpenGL ES一样,只是一套标准或一套API.Android SDK中提供了一套测试框架(JUnit),可用于对Android应用程序进行TDD测试.测试框架的特性如下: Android的测试框架基于JUnit.可在无需调用Android SDK API的情况下测

从换位思考到测试驱动开发转

在人于人之间的相处中,换位思考有利于人们理解彼此的需求,进而促成共赢的局面.把换位思考用到软件的设计中,能够提升软件的质量.这是我在Michael Feathers的培训里,领悟到的最巧妙的一个思维方式.如果你对Michael的名字不熟悉,那么他写的Working Effectively with Legacy Code这本书,你可能听说过. 如何在软件的开发中做到换位思考?在回答这个问题之前,让我们看看换位思考为什么能提升软件质量. 不用不知道,一用吓一跳 你代码敲得很High,把属于你的那部

测试驱动开发(Test-Driven Development)

1.背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦.国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从.最近兴起的一些软件开发过程相关的技术,提供一些比较高效.实用的软件过程开发方法.其中比较基础.关键的一个技术就是测试驱动开发(Test-Driven Development).虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用.下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解.掌握.应用

浅谈测试驱动开发(TDD)

1. 优势 TDD的基本思路就是通过测试来推动整个开发的进行.而测试驱动开发技术并不只是单纯的测试工作. 需求向来就是软件开发过程中感觉最不好明确描述.易变的东西.这里说的需求不只是指用户的需求,还包括对代码的使用需求.很多开发人员最害怕的就是后期还要修改某个类或者函数的接口进行修改或者扩展,为什么会发生这样的事情就是因为这部分代码的使用需求没有很好的描述.测试驱动开发就是通过编写测试用例,先考虑代码的使用需求(包括功能.过程.接口等),而且这个描述是无二义的,可执行验证的. 通过编写这部分代码

测试驱动开发(TDD)及测试框架Mocha.js入门学习

组里马上要转变开发模式,由传统的开发模式(Developer开发,QA测试),转变为尝试TDD(Test-driven development,测试驱动开发)的开发模型.由此将不存在QA的角色,或者仅存很少的QA用于系统模块间的集成测试. 因此代码的测试与开发都将由开发者(Developer)来保证. 这就需要借助优秀测试框架的帮助,尤其是支持TDD开发模式的自动化测试框架更为重要,因为我使用的编程是语言是Node.js,那么广泛使用的Mocha.js将成为我的首选. 在团队转型过程中,很多事情

简单了解测试驱动开发---单元测试

The idea is to begin development of a new software unit with its specification, followed by its implementation (which, by definition, must satisfy the specification). 测试驱动开发背后的理念是我们在开发之前定义一个标准(specification), 然后去实现它(implemention),当然实现要完全满足标准. 举一个现实生活

测试驱动开发基础

以下是我个人对测试驱动开发的一点理解,如有不足请指正 测试驱动开发的大致步骤是 写一个测试(基本上无法运行甚至编译) 小改动使之能够编译运行(建立需要调用的函数存根,不实现,或伪实现——直接返回定值) 逐渐使代码一般化(用变量代替常量定值) 通过改动,消除重复设计(提取为公用的变量或函数) 具体每一步我的理解如下(对应上述4步骤) 写测试时,只从主函数视角考虑,不考虑我要    调用的函数是否存在,而是直接写出我要调用XX函数,得到XXX返回值等 第1步的代码必然报错,此时针对报错进行修改,补上