所以......我需要培训团队测试 - 可以在课程计划中使用C&C

dfe*_*aro 11 unit-testing

所以 - 管理层正在努力推动在所有应用程序中进行单元测试 - 并最终进入完整的TDD /持续集成/自动构建模式(我希望).在这一点上,我们只关心让每个人使用单元测试开发应用程序.我想从基础开始.

我不会说谎 - 我在任何单位测试方面都不是专家,但我确实有足够的理解来开始基础知识的倡议,并允许我们成长为一个团队.我真的很想从你所有的专家那里得到一些评论和批评我的攻击计划.它是一个由小型商店中约10名开发人员组成的团队,这为利用敏捷开发方法和最佳实践提供了一个很好的机会.

首先 - 该团队主要由中级开发人员组成,他们有几个初级开发人员和一个高级开发人员,所有人都没有接触过单元测试.培训将是一个半月会议,每次大约30-60分钟(可能最终运行一小时,我猜,也许更频繁地使用它们).我们将继续这些会议,直到有理由阻止他们让别人赶上他们自己的"家庭作业"和经验 - 但推动将始终如一.

无论如何 - 这是我提出的课程计划.好吧,前两个至少.您的专家就课程的实际内容或结构等提出的任何建议都会很棒.评论和批评非常感谢.非常感谢.

如果这篇文章"太多"无法在此处发布或通读,我深表歉意.我认为对于希望首先进入单元测试的SO用户来说,这将是一个很好的主题.也许你可以跳到"课程计划"部分 - 再次感谢所有人.

CLIFF注意事项 - 我发现这篇帖子非常冗长和丑陋,所以这里有悬崖笔记 - 第1课将是'你好世界单元测试' - 第2课将打开我最近的应用程序的解决方案,并展示如何应用每个"世界你好"在现实生活中的例子......非常感谢大家对您给了我迄今..反馈只是wantd强调的是第2课其实要具有现实生活的生产单元测试它,因为许多建议我这样做,当它是我的计划从开始=)

单元测试课程计划

概观

为什么单元测试?看起来像是一堆额外的工作 - 为什么呢?

•成为自己命运的主人.我们的大多数用户都没有真正的UAT,不幸的是,他们倾向于在生产中进行一次测试.通过单元测试,我们可以大大降低与此相关的风险,特别是在我们创建足够的测试数据并考虑尽可能多的顶级输入时.虽然不是防止所有错误的"银弹" - 这是你的第一道防线 - 一条巨大的前线,可与SB冠军巨人队相媲美.

•单元测试实施良好的设计和架构实践.这是"暴力的精神病患者维护你的代码并知道你住在哪里".你根本无法编写经过单元测试的低质量代码

•你有多少次没有重构臭代码,因为你太害怕破坏某些东西?自动化测试消除了这种恐惧,使重构变得更加容易,从而使代码更易读,更易于维护.

•底线 - 维护变得更容易和更便宜.编写单元测试所花费的时间现在可能成本很高 - 但是它节省你的时间已经被证明是一次又一次更有价值.这是自动测试代码的首要原因.它给了我们信心,使我们能够对系统进行更加雄心勃勃的改变,否则我们可能不得不降低需求,甚至根本不采取任何措施.

术语审查

•单元测试 - 测试最低级别的单个工作单元.EG - 测试单个函数可以流经的所有可能的代码路径.

•集成测试 - 测试您的单元如何协同工作.例如 - 运行一个"作业"(或一系列函数调用),使用已知输入执行大量工作 - 然后在最后查询数据库并断言值是您对这些已知输入的期望(而不是必须眼球在某个网页上的网格,例如进行功能测试).

•伪造 - 假冒是一种对象,其目的是用于您的测试.它允许您轻松地测试您不想测试的代码.您不必调用您不想要的代码(如数据库调用),而是使用假对象来"伪造"该DB调用,并且可能从XML/Excel文件或模拟框架中读取数据.o模拟 - 一种你对其发表断言声明的假货.o Stub - 一种用作占位符代码的伪造,因此您可以跳过数据库调用,但不要对其进行断言

教训

第一课 - Hello Worlds

•Hello World单元测试 - 我将创建一个经过单元测试的"hello world"控制台应用程序.将在会议期间动态创建此应用程序,在Visual Studio 2008(测试项目,测试工具工具栏等)中显示我们将在使用过程中使用的工具,同时解释它们的用途.这将只有一个单元测试.(好吧,也许我不会'在飞行中'创造它'=),不得不考虑更多).还将解释Assert类及其目的和单元测试的一般流程.

•Hello World,有点复杂.现在我们的函数具有代码可以流经的不同路径/逻辑分支.我们将为此功能进行约3次单元测试.这将是我在会议之前提出的预先编写的解决方案.

•Hello World,依赖注入.(不使用任何DI框架).一个预先编写的解决方案,它构建了前一个解决方案,这次使用依赖注入.将解释DI是什么,并展示它是如何工作的样本.

•Hello World,Mock Objects.这是一个预先编写的解决方案,它构建了前一个解决方案,这次使用我们新添加的DI代码将模拟对象注入到我们的类中以显示模拟是如何工作的.将使用NMock2.0,因为这是我唯一接触过的.非常简单的示例,只显示模拟对象的使用.(也许把这个放在一个单独的课程中?).

•Hello World,(非自动化)集成测试.基于以前的解决方案,我们创建了一个集成测试,以便展示如何一起测试2个函数,或者将整个类一起测试(也许将这个函数放在一个单独的课程中?)

第二课 - 现在我们了解基础知识 - 如何在现实生活中应用它?

•最佳实践概述o规则#1-单一责任主体.单一责任负责人.单一责任负责人.在编写代码时,请谨慎地说明这是最重要的事情.一堂课应该只有一个目的; 一个函数应该只做一件事.这里的关键词是"单元"测试 - 而SRP将把你的类和功能封装成单元.o依赖注入是你的第二好朋友.DI允许您在运行时将行为"插入"您的类.除此之外,这就是我们如何使用模拟框架来使我们更大的类更容易测试.

o在编写代码时总是想'我将如何测试'.如果看起来"太难测试",那么你的代码可能太复杂了.重新考虑它直到更多逻辑单元的类/函数 - 拿一个做5件事的类,把它变成5个类,一个调用另一个4.现在你的代码将更容易测试 - 也更容易阅读和重构.

o测试行为,而不是实施.简而言之,这意味着我们在大多数情况下只能测试我们类的Public函数.我们不关心测试私有(实现),因为公共的(行为)是我们的调用代码使用的.例如......我是百万富翁软件开发商,去阿斯顿马丁经销商为自己买一台全新的DB9.销售人员告诉我它可以在3秒内完成0-60.你会怎么测试这个?你能解除引擎并执行诊断测试等吗?不......你会把它带到大路上并做160 MPH =).这是测试行为与实现的关系.

•审查现实生活中经过单元测试的应用程序.在这里,我们将回顾上面的每个"hello world"示例 - 但是现实版本,以我最近的项目为例.我将打开一个简单的单元测试,一个更复杂的单元测试,一个使用DI,一个使用Mocks(可能耦合到DI).这个项目相当小而简单,所以它非常适合.这还包括测试DAL以及如何设置测试数据库来运行这些测试.

Dav*_*ims 6

我喜欢你在这里表达的承诺和彻底,但我的感觉是你的采用计划需要更长的时间,而不是直接开始,配对并编写一些实际的生产测试.无论如何,您还需要基础架构 - 为什么不使用CI服务器和TDD框架来引导您的实际生产代码?(很多时候,这是一个比学习"断言"更大的痛点."尽早将这部分放在一边".然后坐下来解决与编码员的实际问题.选择一个简单的bug或小功能,并尝试确定失败的测试会是什么样子并尝试编写它们.

我喜欢Hello Worlds的棕色包午餐或其他东西.但我想不出有任何理由不直接进入并解决一些问题.


小智 5

让人们对其他人/示例代码进行单元测试感兴趣的效果不如人们在他们必须编写的一些新代码上"从测试用例开始"那样有效.涵盖从测试用例开始并三角测量到有效结果的基础知识(同时强调失败的测试是进展).

也就是说,我个人的经验是这样的事情在一对编程环境中做得更好.这对你来说是额外的工作,但是一对一,一些所有权和他们可以在最后引用的工作示例的组合将使采用变得更加容易.

在适当的环境下,稍后在某个时间点运行覆盖工具可以提供有趣,有竞争力和令人满意的标记进度的方法.以任何方式使这成为补偿/奖金的一部分是一个真正的坏主意.如果做得好,人们会采用它,因为它有效.


Jus*_*ard 5

我帮助我的公司为Java开发人员设计和运行测试驱动开发培训.我们最终将其作为一整天的培训,我们将其分解为与您在此处的方式类似.

  1. 为什么要测试?
  2. 简单的例子.
  3. 更复杂的例子.

我必须强调的一点是,人们需要通过实践来学习.

对于我的培训,我们建立了一个实验室环境,每个学生都可以从相同的代码快照开始,自己开发和运行测试,教练走遍训练室,帮助那些困惑或没有得到它的人.

对于"简单示例",我们在投影仪上有一个"烹饪节目"版本的代码,并逐步完成TDD流程.开发人员必须经历编写测试的过程,然后创建足以通过测试的实现,然后重复.在每个阶段,在学生有时间自己尝试之后,投影仪上会显示当前阶段的准备解决方案.

对于"复杂示例",我们创建了一组要求,然后允许学生使用TDD来提出他们自己的解决方案.我们甚至进行了一项练习,其中需要惊喜,突然在练习中突然改变.

我喜欢你的想法,通过定期检查,在更长的时间内做这件事.我们培训的一个缺点是缺乏后续行动.开发人员受益于培训,我敢肯定,但我认为很多人并没有将这种做法带回到他们的日常工作中.定期检查有助于灌输单元测试作为习惯问题.

有关更多想法,请查看我对此问题的回答.