敏捷开发之测试驱动开发和结对

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简单
沟通
反馈
• 对于我们产品、对于我们的开 发过程的每一步开发的进度, 每一步测试的结果,对任何人 而言都是透明的。 • 不断反馈的过程就是不断建立 信心的过程。
勇气
• 勇于去创新,勇 于去改变,勇于 接受改变
敏捷开发方法
完整团队 项目墙
每日晨会 测试驱动开发
敏捷开发方法
结对编程(codereview等) 持续集成
重构 迭代总结
敏捷开发方法需要全用吗?
不需要
Agent
1 2 3 4 5 6
• 敏捷开发概述 • 测试和开发之间的关系 • 测试驱动开发 • 结对 • 总结 • Q&A
测试的抱怨
1.需求变化
5.可测试性差
2.文档更新不 及时
4.开发质量低
3.时间太少
敏捷对测试挑战
敏捷对开发过程带来了曙光 敏捷确给测试带来了挑战
我们的问题
时间少
变化多
产品质量要求高
我们的问题
每一个程序员都知道应该为自己的代码编写测试程序,但却很少这样做。
当有人问为什么的时候,最常听到的回答就是:"我们的开发工作太紧张了"
但这样却导致了一个恶性循环,越是没空编写测试程序,代码的效率与质量 越差,花在找Bug、解决Bug的时间也越来越多, 实际效率大大降低。 由于效率降低了,因此时间更紧张,压力更大。你想想,为什么不拉上一根 水平线呢? 难道,我们不能够将后面浪费的时间花在单元测试上,使得我们的程序一开 始就更加健壮,更加易于修改吗?
How to do TDD?
1、写一个空方法。 2、写一个测试程序(单元测试用例)。 3、让程序编译通过。 4、运行测试程序,发现不能运行。(红条) 5、让测试程序可以运行。(绿条) 6、消除重复设计,优化设计结构。(绿条) 7、重构
确定业务
1、用户可以选择付费月份为1、2、3个月 2、用户选择1个月最多可用1个红包 3、用户选择2个月最多可用2个红包 4、用户选择3个月最多可用3个红包
Alibaba 的测试情况
80%开发人员认为测试就是测试人员的事情 测试就是不断的发现bug 无建立好的持续集成框架 80%的项目无考虑可测试性,部分是提交了测试 之后再考虑 单元测试覆盖率低 有codereview,但无结对
今天,我们开发所必须要做的
意识到提高产品的质量也是开发的重要责任 引用敏捷开发的测试驱动开发和结对,提高产品 质量 帮助测试人员建立持续集成框架、验收测试的标 准 可测试性的设计
为什么要敏捷?
提高产品的质量
敏捷开发和传统开发流程的对比
敏捷开发“前”的产品开发过程(瀑布模型)
敏捷开发和传统开发流程的对比
敏捷开发“后”的产品开发过程(迭代模型)
敏捷开发的价值观
• 我们要用最简单的方式做我们 的事情,无论是设计、开发实 现还是测试 • PD和开发、测试 之间 • 用户和PD之间 • 开发和开发之间 • PD和用户之间
4、优化程序
public int getNumOfCoupsCanUse(int months, int totalCoups) { if (months < 1 || months > 3) { return 0; } return (totalCoups >= months) ? months : totalCoups; } 运行测试:
重构程序
/** * 根据选择充值月数和拥有的最大红包数,取得可用红包数 * * @param months 充值月数 * @param totalCoups 拥有的最大红包数 * @return 可用红包数 */ public int getNumOfCoupsCanUse(int months, int totalCoups) { if (months >= 1 && months <= 3) { return (totalCoups >= months) ? months : totalCoups; } else if (months == 6) { return (totalCoups >= 3) ? 3 : totalCoups; } else { return 0; } } 运行测试:
3、完成程序
public int getNumOfCoupsCanUse(int months, int totalCoups) { if (months == 1) { return totalCoups >= 1? 1:0; } else if (months == 2) { return totalCoups >= 2 ? 2 : totalCoups; } else if (months >= 3) { return totalCoups >= 3 ? 3 : totalCoups; } else { return 0; } } 运行测试:
Why TDD?
确保每个方法都是可用的且已被测试过 确保及时发现出现问题的模块 添加或修改代码更容易 频繁地运行测试 迭代式递增开发 不断重构以改善设计
Why TDD?
TDD还能改善和验证设计: 以客户端的视角编写测试 为客户端提供了示例代码 更注重接口的设计 为了使测试容易,需要实现松散耦合 更少的Debug时间
测试驱动开发的精髓
将测试方案设计工作提前,在编写代码之前先做这一项工作;
从测试的角度来验证设计,推导设计;
将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验 证其正确性,实现软件开发过程的"小步快走"。
What is TDD?
Test Driven Development(测试驱动开发) 测试先行。 持续重构。 测试驱动开发是一种在极限编程(XP)中处于核 心地位的技术。
开发会创建更少的文档,更多的时间关注开发,放在
沟通,让用户满意的产品上。 敏捷的过程中可能需要每个星期就发一个版本 需求和设计有更加频繁的改变
测试和开发资源的对比
Google 1/10 Alibaba 1/3 Microsoft 1/1
Google 的测试文化
所有工程师对质量有着同等重要的责任 测试的任务不仅是发现bug,更重要的是帮助开 发人员一起提高产品质量 有效地进行验收测试、持续集成、测试驱动开发 、自动化测试、结对。 开发在设计的同时就考虑可测试性。 重沟通,每周会沟通做了什么功能,存在什么风 险 以任务而非角色安排工作,共享同样的目标,共 享同样的任务。
Agent
1 2 3 4 5 6
• 敏捷开发概述 • 测试和开发之间的关系 • 测试驱动开发 • 结对 • 总结 • Q&A
从一句大师的话开始
编写单元测试是在进行验证, 更是在进行设计。同样,它更 是在编写文档。
心灵震憾
一段时间的学习,让我的内心受到了深深的震撼。我们原来的方法居然如此 的笨。 以前我面对测试先行这一名字时,最大的疑问就是"程序都还没有写出来, 测试什么呀!"。 后来一想,其实这是一个泥瓦匠都明白的道理,却是自己在画地为牢。我们 来看看两个不同泥瓦匠是如何工作的。
业务变更:增加6个月选择
1、用户可以选择付费月份为1、2、3、6个月 2、用户选择1个月最多可用1个红包 3、用户选择2个月最多可用2个红包 4、用户选择3个月最多可用3个红包 5、用户选择6个月最多可用3个红包
更改测试
public void testGetNumOfCoupsCanUse() { CouponManagerImpl cm = new CouponManagerImpl(); assertEquals(0, cm.getNumOfCoupsCanUse(1, 0)); assertEquals(1, cm.getNumOfCoupsCanUse(1, 1)); assertEquals(1, cm.getNumOfCoupsCanUse(1, 5)); assertEquals(2, cm.getNumOfCoupsCanUse(2, 5)); assertEquals(3, cm.getNumOfCoupsCanUse(3, 5)); assertEquals(1, cm.getNumOfCoupsCanUse(3, 1)); assertEquals(1, cm.getNumOfCoupsCanUse(6, 1)); assertEquals(3, cm.getNumOfCoupsCanUse(6, 5)); // 边界检查 assertEquals(0, cm.getNumOfCoupsCanUse(0, 5)); assertEquals(0, cm.getNumOfCoupsCanUse(4, 5)); assertEquals(0, cm.getNumOfCoupsCanUse(7, 5)); } 运行结果:


来自百度文库
工匠师傅的“测试驱动开发”
这个就是 线
工匠一:先拉上一根水平线,砌每一块砖时,都与这根水平线进行比较,使 得每一块砖都保持水平。 工匠二:先将一排砖都砌完,然后拉上一根水平线,看看哪些砖有问题,再 进行调整。
你会选择哪种工作方法呢?
有可能你会骂工匠二笨吧!这样多浪费时间呀! 然而我们自己想想,我们平时在编写程序的时候又是怎么做的呢? 我们就是按工匠二的方法在干活的呀! 甚至有时候比工匠二还笨,是整面墙都砌完了,直接进行"集成测试",经常 让整面的墙倒塌。 看到这里,你还觉得自己的方法高明吗?
1、写一个空方法
public class CouponManagerImpl { /** * 根据选择充值月数和拥有的最大红包数,取得可用红包数 * @param months 充值月数 * @param totalCoups 拥有的最大红包数 * @return 可用红包数 */ public int getNumOfCoupsCanUse(int months, int totalCoups) { // TODO 完成该方法 return 0; } }
2、写一个测试程序
public class CouponManagerImplTest extends TestCase { public void testGetNumOfCoupsCanUse() { CouponManagerImpl cm = new CouponManagerImpl(); assertEquals(0, cm.getNumOfCoupsCanUse(1, 0)); assertEquals(1, cm.getNumOfCoupsCanUse(1, 1)); assertEquals(1, cm.getNumOfCoupsCanUse(1, 5)); assertEquals(2, cm.getNumOfCoupsCanUse(2, 5)); assertEquals(3, cm.getNumOfCoupsCanUse(3, 5)); assertEquals(1, cm.getNumOfCoupsCanUse(3, 1)); // 边界检查 assertEquals(0, cm.getNumOfCoupsCanUse(0, 5)); assertEquals(3, cm.getNumOfCoupsCanUse(4, 5)); } } 运行结果为:
敏捷开发
之测试驱动开发和结对
ITBU-技术部 徐宗敏 2010年3月18日
Agent
1 2 3 4 5 6
• 敏捷开发概述 • 测试和开发之间的问题 • 测试驱动开发 • 结对 • 总结 • Q&A
为什么要敏捷?
需求经常在变化
为什么要敏捷?
需求失真
为什么要敏捷?
kickoff
发布
没有足够的时间
Agent
1 2 3 4 5 6
• 敏捷开发概述 • 测试和开发之间的关系 • 测试驱动开发 • 结对 • 总结 • Q&A
小时候结对学习
小时候结对学习的关键词
长大了要结对编程
结对编程的关键词
结对中需要做的
需求review 设计review
Code review 进度review
结对的好处
相关文档
最新文档