`

<测试驱动开发实用指南>读书笔记

    博客分类:
  • Book
阅读更多

里面的一些测试技术都很老了, 比如junit, 现在都注解了.
本来是想跟着里面的电影列表的例子来实践一把的, 不过对swing不熟悉, 而且没有源代码可以下载的, 遇到了一些书面上没有提到的代码, 导致中间没法继续下去.
前面几章的一些理论还是不错的, 有些以前自己已经知道了, 现在再看一遍, 有一种顿悟的感觉.
如果能拿java最擅长的web应用做例子就完美了, 毕竟做swing应用的人比较少, 至少在国内是如此.

写测试的步骤
1.开始先编写一个测试, 在测试开头增加一条想让它为true的断言
2.然后为使断言为true创造条件
3.最后需要为创建我们所需要的实际代码.
4.在测试通过之后, 开始消除为使测试通过而引入的重复以及其他的一些坏味道代码.

关于重复的一个例子
比如要计算5和3的平均值, 我们可以在真实代码中直接返回4, 当这个结果通过计算得出结果却返回一个常量时, 这就是一种形式的重复.
要去掉重复, 首先这样做:
public int getAverage(){return (3+5)/2;}

不过这里仍然存在重复: 3, 5与提供给参数是重复的, 因此需要通过一个参数用来保存累加的结果:
private int total;
public void add(int i){total +=i;}
public int getAverage(){return total/2;}

这里因为重构的时候而引入了一个常量2, 这也是一种重复, 需要通过记录每次累加测试来去掉:
private int number;
public void add(int i){total +=i; number ++;}
public int getAverage(){return total/number;}

为了对我们的修改增加一些自信, 我们可以增加一些新的测试.

在每次小的改动之后运行测试可以给我们信心和保证, 其结果有了下一步工作的勇气, 每次一小步一小步地推进, 劝告那些完美主义者不要一步到位, 循序渐进, 不要妄想一口吃成胖子.

在消除重复的过程中, 我们还有另外一种思路, 就是通过再编写一个测试, 然后通过重构保证两个测试通过.
但是无论采用哪种思路, 都需要编写另外一个测试, 这样既可以驱动归纳工作的进行, 也可以进一步验证

重构
重构与TDD两个密切相关的两个方面:
尽可能采用简单的方法来让测试获得通过, 然后通过重构来对代码进行整理, 其中大部分工作是消除那些为使测试通过引入的重复
当采用TDD之后, 那么就有了放手重构的安全网.

重构的时机:
当存在重复的时候
当觉得代码或者代码所表达的意图不够清晰的时候
当觉察到代码可能存在坏味道或者有坏味道的倾向的时候

在你要让某个测试通过的时候, 带上编码的帽子, 一旦测试通过, 你就换顶帽子执行重构来进行清理.

关于意图
当我们在编写测试代码的时候, 我们会强迫自己考虑类的接口而不是其实现, 我们就有机会站在使用这个类的用户的立场来判定什么才是最有意义的, 而不是陷入具体的实现细节中去.

code smell
注释:如果你看到一条注释或者觉得有必要编写一条注释的话, 那么请首先要考虑重构或重写代码.
数据类:对某个类数据成员的操作处理应该移到该类的内部, 而不是将其遗弃在该类之外, 让其他的类对其"蹂躏"修改, 这个也体现了封装的原则. "上帝的归上帝, 凯撒的归凯撒"
交往不当:这种情况是指一个类对另一个类的内部细节知道太多.要处理这种情况, 需要对方法进行迁移, 让那些彼此了解的代码处于同一位置. 这样一旦这些内部细节发生变化的时候, 其影响的范围会仅在该类的内部, 而不会出现扩散.
对于继承也会有类似的问题, 子类过多的了解祖先类的实现细节, 超出它所了解的, 这样就应该把继承改成委派(delegation), 或者将这种关系松散化, 达到去耦的目的.
类尺寸过大:应该采用抽取出子类或者采用多态来减小之
方法过长:一般情况下是完成的工作太多了.

重构手段(手法千千万, 常用就这几种)
extract class:当一个类变的太大或者行为逻辑组织分散时, 另一种抽取的原因是由于我们需要某种行为的多种实现.
比如电影列表类有一个功能需要输出一个电影列表, 那么我们可以将这个功能拆分到一个单独的类中去, 这样就能够很容易的进行替换和改进.
extract interface: 记住一点就好, 接口最好是小而专.关于接口的命名, 尽量采用通过添加-able, -ible结尾的形容词, 但是有时候这种命名没有 , 这可以使用添加前缀I, 比如MovieListable没有意义, 我们可以采用IMovieList.
extract method: 通过给一块完成某种功能的代码加注释或者通过空行来清晰代码都是一种潜在的坏味道, 需要通过提取方法将代码拆分到各自的方法中.
replace type code withsubclasses: 当我们的类使用类型代码来表示子类型的时候, 可以使用该手段来打破那些根据类型编码进行判别的复杂条件判断和switch语句.
replace conditional with polymorphism: 当发现switch语句的爱好ihou可以考虑创建子类来处理各种不同的情况. 从而去掉switch.
form template method: 我的最爱, 甚至达到滥用的程度:(
introduce explaining variable:当我们的表达式复杂而且难以立即时, 我们可以提取其中的某些部分, 把中间结果保存在命名清楚的临时变量中.
replace constructor with factory method:当存在多个用于创建类的不同类型的实例的构造方法时, 使用起来不是很容易区分, 则需要通过使用静态工厂方法, 给每个构造方法起一个有意义的名字.
replace inheritance with delegation: 当子类是特殊种类的超类, 或者子类对超类进行扩展而不是复写超类的部分功能时, 才使用继承.

设计模式应该是重构的目标, 应该通过重构逐渐引入设计模式.

如果发现了给参数赋值的代码, 那么应该使用临时变量取而代之.

在开始编码的时候, 我们应该强迫自己采用最简单的做法.

注释
注释存在的目的是为了掩盖代码的臭味.
正当的注释:
未完成的代码(TODO)
重构尚无法足够清晰
使用了某种非同寻常的算法
使用某种别人发布的算法
性能调整
类注释(解释这个类为什么存在以及用途, 要避免编写有关这个类的使用教程)

真正的TDD应该
测试方法应该尽量简短而切中要害
编写一点测试, 编写一点代码(test a little, code a little)
不要一口气把所有的测试都写完, 然后再编写代码, 而要编写一个测试, 让其通过, 在编写一个测试, 再让其运行通过, 以此类推.
万事开头难, 应该从编写最简单的测试开始.

测试模式
设定前置条件
执行相应的功能
检查后置条件是否满足

TestCase
应该将TestCase视为一种需要需要以完全相同的设置方式来组织测试的方法, 而不是用它来组织给定类的测试.
每当你发现setUp中的有些代码使用某些测试方法, 而有些代码不使用其他测试方法时, 那么就应该认为这个TestCase应该被重构为两个或者多个TestCase.

何谓简单的测试对象
:
正确的处理null值
空集或null对象的行为
递归或迭代结构以及递归或迭代计算的基本情况(没明白)

应该尽量使用assertEquals()
尽量在assert中给出相关的message, 没有message也是一种bad smell, 偶没这个习惯:(
尽量保持测试方法中的断言最少, 这样可以保证测试专一, 简洁, 容易理解
编写测试从assertXxx()开始.

测试代码的数量与应用代码一样多, 要是能多上一半就更好了
力争每个测试方法中有只出现一个断言
测试做得好, 调试器用的少
TDD事前需要做大量的工作, 这个工作的收益主要体现在减少了后期调试程序的工作量
一旦你找到了TDD的感觉, 你就会比直接写代码和调试器来进行开发的工作速度快得多.

XP
xp中的四种变化量:成本, 时间, 质量, 范围
其中任何一个的价值依赖于其他三个的价值, 你最多只能控制四个中的三个, 而绝对无法同时控制四个.

xp的价值观:沟通, 简单, 反馈, 勇气
沟通在xp中具有至高无上的重要性, 其外在表现形式:
结对编程
每天早上一次站立会议
在开放的环境工作
客户与开发团队一起工作
大量使用白板
把都感兴趣的信息放在显著的位置

改进设计
在编程的时候, 你先编写一个测试(刚刚能够失败就行), 然后编写一小段代码(刚刚能够保证测试运行通过就行), 这一过程会产生设计或结构低劣的代码, 所以下一步就是通过重构来使代码重新恢复渐渐.

极限编程就是让程序员们来编写程序, 谋生, 并且从中获得乐趣.

要想拥抱变化, 我们就需要采用一种渐进的开发方式, 每次只改变系统的一小部分, 而不是在一次大的交付中搞定所有的一切.

agile model
敏捷建模的两个基本目的:为理解某一问题而建模(诸如如何设计系统的某一部分);为了传达团队正在完成的工作而建模.

敏捷模型大部分都是临时性的, 当这些模型完成他们的使命之后, 继续留存已经没有价值.

敏捷模型是一种刚刚够好(just good enough)的模型
2
0
分享到:
评论

相关推荐

    vxworks读书笔记

    这份读书笔记虽然笼统,但涉及了VxWorks的核心特性和开发中的重要概念。对于熟悉和使用VxWorks的工程师来说,这些知识点是理解和驾驭这个操作系统的基础。通过深入学习和实践,开发者能够更好地利用VxWorks的强大...

    有关软件测试的经典著作

    此外,该书还可能探讨了敏捷开发环境下的测试实践,如持续集成和持续测试,以及如何通过TDD(测试驱动开发)和BDD(行为驱动开发)来提升测试效率。 在阅读这些经典著作时,读者可以学到如何构建一个全面的测试策略...

    (STM32F407)ADS1118调试笔记

    总的来说,"(STM32F407)ADS1118调试笔记"涵盖了从硬件连接、SPI通信、寄存器配置到软件实现的整个流程,对于那些正在使用STM32F407并试图集成ADS1118的开发者来说,这是一个实用的指南。通过阅读这份文档,开发者...

    行业文档-设计装置-一种将笔记本电脑触摸板增强为数字键盘的方法.zip

    在"一种将笔记本电脑触摸板增强为数字键盘的方法.pdf"这份文档中,应该会详细介绍这种技术的实现原理、设计过程、用户界面示例以及实际测试结果,读者可以详细阅读以获取更深入的理解和具体的操作指南。通过这样的...

    STK672-080电机驱动DXP资料及其相关资料.rar

    2. **应用笔记**:这些文档通常包含了一些实用的示例电路、编程指南和故障排除技巧,帮助工程师在实际项目中快速上手和解决常见问题。 3. **设计实例**:可能会有已经设计好的电路图或PCB布局,供开发者参考。这些...

    window操作指南

    ### Window操作指南知识点详解 #### 一、系统信息与配置管理 **知识点1:winver** - **功能**: 显示当前Windows版本信息。 - **应用场景**: 当需要了解系统具体版本时,可以使用此命令。 **知识点2:wmimgmt.msc**...

    Python-GoodThingList就是好物清单使用文档见Issues

    7. **测试驱动开发**:如果项目包含了单元测试,你可以通过运行这些测试来验证GoodThingList的功能是否正常,理解测试框架如unittest或pytest也是有益的。 8. **用户界面设计**:虽然GoodThingList主要通过命令行...

    AndroidNote::fire:Android进阶笔记,包含常用的技术框架,博客社区,书籍等

    7. **MVVM(Model-View-ViewModel)架构**:现代Android开发的推荐架构模式,强调解耦和测试驱动开发。 ### 二、博客社区 笔记中可能会包含一些推荐的Android开发者社区和博客资源,如: 1. **Medium**:众多技术...

    程序员面试宝典(c++).zip

    此外,面试宝典还会涉及软件工程和项目管理方面的知识,比如版本控制(如Git)、测试驱动开发(TDD)、敏捷开发方法论等。这些知识不仅显示了候选人的专业素养,也是现代软件开发团队中不可或缺的技能。 在系统设计和...

    PN532芯片 SmartNFC开发板资料包括文档及软硬件参考设计资料.rar

    SmartNFC开发板则是基于PN532芯片设计的,为开发者提供了一个方便的平台,用于快速进行NFC技术的研发和测试。 开发板资料通常包含以下几个重要部分: 1. **PN532芯片规格书**:这是了解PN532芯片功能、性能指标和...

    ASM 1351.zip

    设计套件中可能还包括示例代码、应用笔记和其他实用指南,以帮助开发者理解如何正确地集成和使用ASM 1351。 ASM 1351作为一个重要的集成电路,很可能是一个USB控制器,因为ASMedia公司以其USB 3.0控制器而知名。USB...

    亲测可证,虚拟串口+串口助手实现本机的数据通信检测

    在实际操作中,应仔细阅读这份文档,按照指南设置虚拟串口和串口助手,确保两者能正确通信。 更多软件点击进入.url和淘宝优惠券.url可能是提供其他相关工具或优惠信息的链接,但它们不是本次数据通信检测的核心部分...

    MAX31855温度检测_MAX31855.zip

    为了更好地利用这个资源,用户应仔细阅读数据手册,理解MAX31855的工作原理和功能,参考应用笔记解决实际问题,同时可以根据提供的示例代码快速开发自己的软件驱动,确保硬件连接无误后,进行系统调试和测试。...

    普中51-单核-A2开发板资料.zip

    这部分资料可能是专门为初学者准备的指南,涵盖了单片机学习的基础知识和注意事项,对于刚接触51单片机的人来说,这是一份非常实用的入门教材。 六、《4--开发板原理图》 开发板的电路原理图是理解硬件设计的关键...

    SI446X 全部文档

    4. **软件开发工具**:可能包括SDK、API参考和编程指南,用于编写驱动程序和应用软件。 5. **设计实例**:展示了如何将SI446X集成到具体产品中的案例,对初学者尤其有帮助。 6. **数据表**:列出了芯片的详细电气...

    电子设计资料_基于51单片机的电子万年历的设计资料.zip

    这份文档可能包含了详细的项目介绍、电路设计图、代码注解和步骤指南,是整个项目的核心部分,学习者可以通过阅读这份文档了解设计思路和实现方法。 7. **新建 文本文档.txt** 可能包含了额外的说明、笔记或调试...

    TwinCAT2.0从入门到精通_V2.02_20151118

    4. **项目开发阶段**:建议先阅读第 3 章,了解 TwinCAT 开发环境,并根据所使用的 IO 模块和设备,详细阅读第 7 章的相关内容。 5. **项目结束阶段**:可以查阅第 4 章,了解操作系统和硬件相关的信息。 #### 五...

    DFFFDFDFDFDFDFD

    - **用途**:适合简单的音频录制需求,如录制简短的语音笔记或简单的音频文件。 ### 3. Nslookup - 域名解析查询 - **功能**:用于查询域名对应的IP地址等信息。 - **用途**:网络管理员常用此工具进行DNS服务器的...

Global site tag (gtag.js) - Google Analytics