我应该何时/多久进行一次测试?
作为一个刚进入我的第一个专业项目节奏的新手开发人员,我正在尝试尽快养成良好的习惯。但是,我发现我经常忘记在构建结束时进行测试,推迟测试或者进行一系列测试,而不是一次进行一次。
我的问题是,在大型项目上工作时,我们喜欢什么节奏?适合的测试范围是什么?
解决方案
回答
在签入代码之前。
回答
当我为自己一起砍东西时,我最后进行了测试。不好的做法,但是这些通常是我会使用几次的小东西,仅此而已。
在一个较大的项目中,我在编写类之前先编写测试,并且在对该类进行每次更改后都运行测试。
回答
好吧,如果我们想跟随TDD的家伙,那么在开始编码之前;)
我和你的位置非常相似。我想更多地参与测试,但是我目前处于一个工作位置,我们正在努力"拿出代码",而不是"把代码拿出来",这使我不知所措。因此,我正在慢慢尝试将测试流程集成到我的开发周期中。
目前,我在编写代码时进行测试,试图在编写代码时破坏该代码。我确实很难进入TDD的心态。这需要时间,但这就是我想要的工作方式。
编辑:
我认为我应该对此进行扩展,这是我的基本"工作过程"。
- 计划我想要的代码,可能的对象设计,等等。
- 创建我的第一堂课,在顶部添加一个巨大的注释,概述我对该堂课的"愿景"。
- 概述基本测试方案。这些将基本上成为单元测试。
- 创建我的第一个方法。。还要写一个简短的注释,说明它是如何工作的。
- 编写一个自动化测试,看看它是否符合我的期望。
- 对每种方法重复步骤4-6(请注意,自动化测试位于F5上运行的庞大列表中)。
- 然后,我创建一些功能强大的测试来模拟工作环境中的类,显然可以解决所有问题。
- 如果在此之后发现任何新的错误,我将返回并编写新测试,确保它失败(这也可以作为该错误的概念证明),然后进行修复。
我希望这会有所帮助。正如我所说的,这是我的关注。
回答
我不断测试。在完成函数内部的循环之后,我运行程序并在循环顶部命中一个断点,然后执行该循环。所有这些只是为了确保该过程完全按照我想要的去做。
然后,功能完成后,就可以对其进行整体测试。我们可能想在调用该函数之前设置一个断点,然后检查调试器以确保其正常运行。
我想我会说:"经常测试。"
回答
我最近才将单元测试添加到我的常规工作流程中,但是我编写了单元测试:
- 表示每个新代码模块的要求(在我编写接口之后但在编写实现之前)
- 每次我认为"最好……在完成时"
- 当出现问题时,量化错误并证明我已修复它
- 当我编写明确分配或者取消分配内存的代码时-我讨厌寻找内存泄漏...
我在大多数版本上都运行测试,并且总是在运行代码之前运行测试。
回答
从单元测试开始。具体来说,请查看TDD(测试驱动开发)。 TDD背后的概念是,我们首先编写单元测试,然后编写代码。如果测试失败,请返回并重新处理代码。如果通过,则继续进行下一个。
我对TDD采用了混合方法。我不喜欢无所事事地编写测试,因此通常我会先编写一些代码,然后再进行单元测试。这是一个反复的过程,我们从未真正完成过。我们更改代码,运行测试。如果有任何故障,请修复并重复。
另一类测试是集成测试,该集成测试会在过程的后期进行,通常可能由质量检查测试团队完成。无论如何,集成测试都满足了对整体进行测试的需求。这是我们要测试的有效产品。这是一个较难处理的b / c,它通常涉及拥有自动化测试工具(例如,Robot)。
另外,看看类似CruiseControl.NET的产品来进行连续构建。 CC.NET是不错的b / c,它将在每次构建时运行单元测试,并在出现任何故障时立即通知我们。
回答
首先也是经常。
如果要为系统创建一些新功能,我将希望首先定义接口,然后为这些接口编写单元测试。要确定要编写哪些测试,请考虑接口的API及其提供的功能,拿出笔和纸,想一会儿有关潜在的错误情况或者证明其工作正确的方法。如果这太困难了,那么API可能不够好。
关于测试,请查看是否可以避免编写"集成"测试来测试多个特定对象并将其保留为"单元"测试。
然后创建接口的默认实现(不执行任何操作,返回垃圾值,但不引发异常),将其插入测试以确保测试失败(此测试表明测试有效!:))。然后编写功能并重新运行测试。
这种机制不是完美的,但是会涵盖许多简单的编码错误,并为我们提供了运行新功能的机会,而不必将其插入整个应用程序。
然后,我们需要结合现有功能在主应用程序中对其进行测试。
这是测试更加困难的地方,如果可能的话,应将部分工作外包给优秀的QA测试人员,因为他们有打破常规的诀窍。尽管如果我们也具有这些技能也会有所帮助。
老实说,正确进行测试是一个诀窍。我自己的经验来自于我自己的幼稚部署以及用户在愤怒中使用它时报告的后续错误。
最初,当我遇到这种情况时,我发现用户有意尝试破坏我的软件感到很恼火,我想将所有"错误"标记为"培训问题"。但是,在深思熟虑之后,我意识到(作为开发人员)我们的职责是使应用程序即使是白痴也尽可能地简单易用。赋予白痴权力是我们的角色,这就是为什么我们得到报酬。愚蠢的处理。
为了有效地进行这样的测试,我们必须进入尝试打破一切的思维定式。假定用户为按钮设置了衬套,并且通常试图以怪异而奇妙的方式破坏应用程序。
假设如果我们没有发现缺陷,那么在生产中就会发现它们,给公司带来严重的损失。对所有这些问题承担全部责任,并在生产中发现我们要负责(甚至部分负责)的错误时,要对自己负责。
如果我们完成了上述大部分操作,则应该开始生成更加健壮的代码,但是这有点艺术形式,需要很多经验才能擅长。
回答
要记住的一个好关键是
"Test early, test often and test again, when you think you are done"
回答
我们在这里不做TDD(尽管有些人主张这样做),但是我们的规则是,我们应该在进行更改时检查单元测试。它并非总是会发生,但返回到特定的变更集并查看是否编写测试很容易。
回答
我发现,如果等到编写一些新功能结束测试时,我会忘记许多我认为可能会破坏该功能的极端情况。如果我们正在做自己要学习的事情,那没关系,但是在专业的环境中,我发现我的流程是经典的形式:红色,绿色,重构。
红色:编写测试,使其失败。这样,我们就知道测试针对正确的变量进行了断言。
绿色:以最简单的方式使新测试通过。如果这意味着要对其进行硬编码,那就可以了。对于那些只想立即工作的人来说,这非常有用。
重构:现在测试通过了,我们可以放心地更改代码了。新更改破坏了测试?太好了,更改有一个我们没有意识到的隐含含义,现在测试正在告诉我们。
随着时间的流逝,这种节奏使我加快了开发速度,因为我基本上拥有一个历史记录编译器,可以处理我认为需要检查的所有内容才能使某个功能正常工作!反过来,这又带来了许多其他好处,而我将不会去这里...
回答
什么时候测试?重要的是,代码可以正常工作!
回答
这里有很多很棒的答案!
我尝试在有意义的最低级别进行测试:
- 如果单个计算或者条件运算很困难或者很复杂,请在编写代码时添加测试代码,并确保每个代码都能工作。完成后,注释掉测试代码,但将其保留下来以记录如何测试算法。
- 练习边界条件-代码更改其行为的输入值-捕获"一个错误"的错误。
- 测试有效和无效输入的各种组合。
- 查找可能会破坏代码的情况,然后进行测试。
- 使用与上述相同的策略测试每个模块。
- 测试整个代码体,以确保组件正确交互。如果我们一直在努力进行低级测试,那么从本质上讲这是一个"信心测试",以确保在组装过程中不会有任何损坏。
由于我的大部分代码是针对嵌入式设备的,因此我特别注意健壮性,各种线程,任务和组件之间的交互以及资源的意外使用:内存,CPU,文件系统空间等。
通常,我们越早遇到错误,隔离,识别和修复错误就越容易-并且花更多的时间来花在创建而不是追逐尾巴上。*
*我知道,-1是免费缓冲区指针参考!