我们试图在我的公司中多次引入开发人员自动化测试。我们的质量检查团队使用Selenium来自动化UI测试,但是我一直想介绍单元测试和集成测试。过去,每次尝试时,每个月的第一个月或第二个月每个人都会感到兴奋。然后,几个月后,人们只是停止这样做。

一些观察和问题:我曾经在其他公司工作的大多数同事都尝试过并未能实施自动测试策略。我仍然没有看到一个实际使用它并且不仅仅谈论它的现实软件公司。因此,许多开发人员将自动化测试视为理论上很棒的东西,但实际上却行不通。我们的业务团队希望开发人员即使花费30%的额外时间也可以做到这一点(至少他们这样说)。但是开发人员对此表示怀疑。
没有人真正知道如何正确地进行自动化测试。是的,我们都已经在互联网上阅读了单元测试示例,但是将它们用于大型项目则完全是另外一回事。罪魁祸首是嘲笑/存根数据库或其他不重要的东西。与编写实际测试相比,您最终花了更多的时间进行模拟。然后,编写测试要比编写代码花费更多的时间时,那就是您放弃了。
在以数据为中心的复杂Web应用程序中使用单元测试/系统集成测试的例子很好吗?有开源项目吗?我们的应用程序以数据为中心,但也具有大量的域逻辑。我在某个时候尝试了存储库方法,发现它非常适合单元测试,但这是以能够轻松优化数据访问为代价的,它增加了另一层复杂性。

我们有一个由20位经验丰富的开发人员进行的大型项目。这似乎是引入单元测试/集成测试的理想环境。

为什么对我们不起作用?您是如何在公司工作的?

评论

您的技术栈是什么?

WebForms几乎不可能正确地进行单元测试。您可以使用MVP(模型/视图/演示器)模式将表示逻辑移动到可测试的组件。

@MasonWheeler:在两种情况下,您都构造了一个了不起的论据,它反驳了最初未被接受的前提:也就是说,存在单元测试以证明正确性。
@ MasonWheeler-使用该参数,您永远不要尝试任何质量检查,因为您永远不会证明没有错误。那甚至不是目标。好的自动化UI和单元测试策略只是使质量检查摆脱死记硬背的测试,并使他们专注于探索性测试。

令我震惊的是,有几个人说,他们几个月以来从未见过自动化测试。我曾在德国大约五家大公司工作,担任顾问,如果您不编写测试,他们会解雇您。自动化测试不是一个理论主题,它在世界各地都得到了成功的实践,并且可以显着提高代码质量(如果操作正确的话)。

#1 楼

进行单元测试最困难的部分是让学科首先/尽早编写测试。大多数开发人员习惯于仅钻研代码。当您试图弄清楚如何编写代码测试时,它也会减慢开发过程的速度。但是,随着测试能力的提高,速度会加快。由于编写了测试,因此代码的初始质量更高。

开始时,请尝试编写测试。一开始就不必担心模拟/存根。保持测试简单。测试是代码,可以/应该重构。尽管按照这些原则进行测试很难,但也可以是设计。 TDD确实致力于使用大多数设计模式(以我的经验,尤其是工厂模式)。

确保测试具有一定的可见性。将它们集成到发布过程中,在代码审查期间询问它们。发现的任何错误均应进行测试。这些都是TDD的亮点。

这里有一些我认为有用的资源:

http://misko.hevery.com/attachments/Guide-Writing %20Testable%20Code.pdf

http://www.agitar.com/downloads/TheWayOfTestivus.pdf

编辑:

在编写测试时要牢记。您没有尝试指定有关代码实现的任何内容,仅是行为。编写代码时,您一直对其进行测试。尝试使用调试语句等执行它。编写测试将使它正式化,并提供您所拥有测试的记录。这样,您可以放心地检查功能,而不会意外跳过在开发过程中记住的测试用例。

评论


引入此功能作为诊断功能的另一种方法...又称开机自检(POST),几乎可以交付客户代码...而不仅仅是一堆简单的测试,这就是测试和功能。

– JustinC
13年2月4日在16:39



另外,请避免使用TDD反模式。

–加里·罗(Gary Rowe)
13年2月5日在17:16

Misko Hevery在youtube上也有一些很棒的视频,内容涉及编写可测试的代码,我认为这是无价的。 youtube.com/watch?v=acjvKJiOvXw

– Despertar
13年7月6日在1:24

“确保测试获得一定程度的可见性”-这对于成功至关重要。如果没有人可以看到您的测试执行情况,他们将看不到该值。应将测试作为连续集成的一部分自动进行检入,然后进行报告。我在Tesults(tesults.com)工作,其存在的原因是因为测试可见性提供了巨大的影响。

–技能M2
17年1月13日在10:37

#2 楼

我在很多方面都同意您的团队。


大多数单元测试的价值值得怀疑。由于绝大多数测试似乎太简单了。
编写好的可测试代码比仅工作代码要困难得多。开发人员社区中有很大一部分人相信只是让它正常工作,而不是代码/设计质量本身。还有更大比例的人甚至不知道什么是质量代码。
编写单元测试代码要比实际代码本身花费更多的时间。许多开发人员功能。
维护单元测试需要太多时间。较小的更改可能会产生较大的连锁反应。自动化单元测试的主要目标是找出更改是否违反了代码。但是,99%的最终结果是测试而不是代码。

面对上述所有问题,仍然没有比这更好的方法来进行代码更改,并且比自动执行测试具有一定的信心,即不会意外地破坏某些东西。

通过不使用单元测试的教科书,可以在某种程度上缓解上述某些问题。水平。以我的经验,大多数编码错误不是因为一个类中的代码编码不正确,而是因为编码人员不了解他们的类应该如何与其他类一起工作。在这种类型的测试中,我看到了很多优点。但是再一次,这些测试比单元(类级别)测试更难编写。

真正归结为开发人员是否相信该过程。如果这样做的话,他们将编写良好的单元测试,及早发现错误并成为支持者。如果他们不这样做,那么他们的单元测试将大体上是无用的,并且不会发现任何错误,并且他们的单元测试的理论将被证明是正确的。顺便说一句,就是我本人已经有几个月没有见过全面的自动化单元测试方法了,但是尽管我们对真正需要测试的部分有所选择,但是自动化单元测试的想法仍然存在。这种方法倾向于受到批评的人少得多,并且被所有开发人员所接受,而不仅仅是少数方法。

评论


我倾向于同意这一点。我们已经养成了只有在出现问题后才进行测试的习惯(即使该突破是在开发过程中)。永远不要预先花太多的时间来获得很少的回报。

–伊兹卡塔
13年2月4日在15:57

@Izkata我见过的另一种成功的方法是在其他系统验证了系统之后,编写相对少量的调用顶层Frobinate()方法的高级测试(而不是在其下方调用的数十种较小的方法)意味着作为烟雾测试,任何较低级别的更改都不会破坏任何东西。通常,这些测试使用的数据与所提供的键盘用户测试的一部分相同,因此客户可以看到系统正在执行他们想要的操作。之后,代码覆盖工具可以标识尚未覆盖的边缘情况。

–丹在火光中摆弄
13年2月4日在16:16

我没有说“全面自动化测试”,而是说“全面自动化UNIT测试”。巨大差距。我至少在模块级别使用自动化测试已有十年了。单元测试是在类级别。我相信,在测试应该相互合作而不是个人合作的课程时,我会付出更多的努力。但是,即使在那儿,我们仍然使用实用的方法,并有选择地选择编写自动测试的位置/位置。

–扣篮
2013年2月5日23:34

没有良好的单元测试覆盖率,您将如何重构?还是不进行重构,如何防止代码逐渐退化为不可维护性?

–kevin cline
13年1月1日在22:16

@Leonardo他们没有-他们太害怕改变任何东西。或者,他们把所有的技术债务都积saved了下来,几周/几个月以后就搁置起来,一次全部解决。

– GraemeF
13年3月3日在9:59

#3 楼


主要的罪魁祸首是对数据库或其他不简单的事物进行模拟/存根。

每个人都很好地说明了如何将单元测试集成到您的环境中。如何迫使人们做得足够多,以使他们看到实际的价值并坚持下去。但是,如果这样做非常麻烦,并且/或者没有好处,那么它就不会坚持下去。

存根数据库应该很简单。而不是将接口放入某些数据库支持以提供其结果,而是放入一个简单的硬编码对象。如果您无法做到这一点,那么您的设计/架构就会出现问题。您的代码假定它要去数据库,或者您没有接口抽象来更改它。

这不仅仅是测试/质量问题。一旦您要更改数据库提供程序,或者改为访问云,或者支持未连接的移动应用程序,您的设计就会失败。如果您不能支持最简单的灵活性案例,那么您当然不能支持您的业务不可避免地需要的更复杂的事情。

评论


硬编码来自模拟对象的小存根的数据库返回值是将测试与数据库中可能更改和破坏代码的任何内容隔离开的好方法(例如,列重命名)。在某些情况下这是适当的,但是易于使用的临时测试数据库对于保持稳定很重要,除非您希望在某天更改它时将其破坏。如果在换出数据库时代码中断,那是测试应捕获的代码错误(如果要避免这种情况,则需要在多个数据库下运行测试套件。)

–user2348
13年2月4日在19:39

@fennec-单元测试不是用来测试数据库的,它们是用来测试依赖于数据库值才能起作用的代码的。

– Telastyn
13年2月4日在19:43

一切顺利,直到您对操作数据库的代码进行单元测试。 :P对于很多人来说,是很多代码。

–user2348
13年2月4日在19:59

@fennec-将接口存根以确保您的写入正在编写正确的对象,这比简单得多要复杂得多。只有当您的类试图直接通过接口发送SQL时,这种情况才会变得很难(阅读:您的设计很糟糕)。

– Telastyn
13年2月4日在22:13

@Telastyn也许是我误会了,但是最终有些类需要变得笨拙并编写SQL或编写文件或发送数据或与GPU进行接口。大多数抽象在某种程度上都有不可避免的泄漏。他们只是务实而未必可怕。

–学徒队列
13年2月6日在22:18

#4 楼

您需要从小的,易于自动化的,高价值的东西开始。摘下一些甜美,低垂的水果,您将可以出售该过程。显示它如何在某个深夜或一个周末电话中为某人节省了费用。然后,您可以从那里扩展。

要很好地进行自动化测试,您需要一个既有资源又有传播者的人,并且需要高层管理人员的支持。

像其他敏捷项目一样对待自动化测试开发。定期制作完成的测试。

添加评论:这更多的是管理问题。在记录该代码之前,该代码是否被视为“完成”?在签入之前?在包含并通过单元测试之前?

如何做到这一点实际上取决于您的角色。你是同行吗?如果是这样,请向他人展示如何使您的代码更易于重用和维护。你是领导吗?选择代码问题最多的程序员,并帮助他们添加测试以避免这些问题。你是老板吗将其设置为“在单元测试通过并通过之前,代码才完成的标准。

评论


“拿出一些甜美,低垂的水果,您就可以出售该过程。”:我认为他们已经到了这个阶段(他们看到了使用单元测试的潜在优势),这就是为什么他们被说服了尝试一下。问题在于,如何系统地将低水平的成果扩展到进行单元测试。我从事的唯一一个系统地使用单元测试的项目具有比实际产品代码更多的单元测试代码。如果团队不准备花更多的时间在单元测试上而不是实际的应用程序代码上,那么IMO可能就不起作用了。

–乔治
13年2月4日在13:01



那更多是管理问题。在记录该代码之前,该代码是否被视为“完成”?在签入之前?在包含并通过单元测试之前?您如何处理此问题实际上取决于您的角色。你是同行吗?如果是这样,请向他人展示如何使您的代码更易于重用和维护。你是领导吗?选择代码问题最多的程序员,并帮助他们添加测试以避免这些问题。你是老板吗将其设置为“在单元测试通过之前,代码不会完成的标准。”

–跳过霍夫曼
13年2月4日在14:00

@SkipHuffman您的评论应作为对当前答案的编辑添加。

– radu florescu
2013年2月4日14:02



#5 楼

遵守这些基本规则。测试:


必须定期运行!您可以在每次签入之前/之后或每天早晨在每个构建上运行测试。自动触发优于手动触发。因为从理论上讲,您可以让团队中的每个人负责确保他们运行测试,如果它不是自动化的,则可能发生的次数不够多!而且,如果您没有足够频繁地运行测试,那么它们俩都发现错误太晚而无法进行大量测试,因此导致了问题2:

如果现在定期运行的测试不会妨碍您。我们所说的测试是:

a。为他们提供的价值而决不能花太长时间(主观地)运行!快速进行测试。不要让人们检入测试,这将浪费您的时间来让他们运行!

b。一定不可靠。尽可能避免多线程测试。像其他代码一样,将工程实践应用于您的测试:特别是-代码检查您的测试!

c。一定不要比测试的实际代码更难修复和维护。如果对您的代码库进行细微的更改,您的编码速度实际上将非常糟糕,需要您修复10个不同的测试。


最后,规则3。测试不仅不能像规则2那样提供负值,还必须提供正值。测试...


实际上必须告诉您在失败时要关心的事情! (请不要进行带有模糊错误消息的测试,或者仅仅是给您带来可笑的抱怨,例如“您忘记在Windows 2008计算机上运行测试”!)。

违反规则3的一种流行方法是测试错误的事物。有时是因为测试太大或没有重点。但是通常这是由于没有测试客户会关心的事情以及测试无关的实现细节而产生的。 (但是有时测试实施细节也可以进行有效的测试-IMO只是通过实践来决定哪个。)结论:这些基本规则将您指引到可持续测试学科的总体方向上拼命渴望。测试时,请问问自己该测试是否真正可持续和可维护。请记住:


如果测试不可持续,它们将被废弃,从而浪费精力
如果测试不可持续,则停止测试,团队停止更好地测试!最后一点:

测试实际上很难。您应该期望,当您开始编写测试时,您团队的测试基本上会失败。不要气disc。每当您发现旧的测试很糟糕并且不可持续时,就不要扔掉。

#6 楼


1.真的有效吗?


是的,如果操作正确,是可以的。关键是测试人员需要在工程师实施新功能后调整和扩展其自动化脚本。


找一位顾问(知道如何正确完成工作的人)。或者,投入更多时间。另一种方法是拥有更大的测试团队,他们会手动执行相同的测试(容易出错)。


因此,引入单元测试/集成测试应该是一个很好的环境。为什么对我们不起作用?您是如何使其在公司中发挥作用的?有很多很棒的文章介绍了测试(单元测试和集成测试)的积极好处,最后归结为错误给您的公司带来了多少成本。例如,我在一家质量至关重要的公司工作,因此不可避免地要进行单元和集成测试。您可以轻松地找到很多文章,这些文章告诉您仅单元测试可以将错误数量减少30%! (实际上,它在20-90%的范围内,平均为30%,但仍然很多。)

要使其在您的公司中运行,请雇用顾问或分配此任务交给高级工程师(这将需要他一段时间)。然后,强迫所有人遵守规则。

评论


我必须指出,实际上,“一切都正常”。但是,这对所有人都没有很大帮助,但对所有人口中的极少数人而言。为了使一个过程真正能够声称它有效,它在完成“排序”时也必须起作用。

–扣篮
13年2月4日在15:32

我将指出,将每个人的情况过分概括为您自己的情况(即,我不会称他们为“经验丰富的开发人员”。.质量很重要)不仅表明您缺乏经验的广度,而且效率也不高。每个行业都有自己的“作品”定义;以及需要在单元,集成和系统级别进行什么程度的测试。许多“异常优秀”的开发人员已经意识到,与自动化集成测试相比,单元测试几乎没有什么优势。他们还意识到这可能仅适用于其特定行业。

–扣篮
2013年2月4日15:43



如果他们拒绝进行单元测试,我不会称他们为“经验丰富的开发人员”。这仅仅是没有真正的苏格兰人的谬论。在没有单元测试的情况下,软件行业已经发展了数十年,而如今在没有它的情况下,该行业中的大多数仍在发展。这可能是一个好主意,但这不是强制性的。

–诺亚·赫特(Noah Yetter)
13年2月4日在17:28



“不浪费时间在单元测试上”:我将其表述为“不浪费时间在无用的单元测试上”。盲目地对所有内容进行单元测试可能会浪费大量时间。

–乔治
13年2月7日在22:39

@Dunk我真的很讨厌整个测试优先的TDD现象,但是我不同意您的第一个陈述。您要么做正确的事,要么不做正确的事。您可以很好地进行一个单元测试,也许可以看到它的优点,但是您永远不会看到任何一件做得很好的事情。

–埃里克·雷彭(Erik Reppen)
13年7月6日在4:14

#7 楼

在上面的答案中,我尚未看到明确解决的一件事是,单元测试本质上是一种公共物品,也是一种私人费用。我在这里写了一篇关于它的博客文章。

归结为,尽管一组测试使团队或单个开发人员受益,但编写测试在大多数情况下是一项成本。

简而言之,除非以某种方式强制执行测试,并且上面的答案列出了执行此操作的多种不同方式,否则没有个人开发人员可以这样做。

在我工作过的一家公司中,编写单元测试是提供功能的必要部分。除非单元测试是提交或新功能的一部分,否则不接受新代码-对开发人员给出的每个“任务”都有简短的代码审查。在您的工作场所实施类似的政策可能是值得的。

#8 楼

有很多原因导致引入自动化测试可能会失败。我认为这可以归结为这样一个事实,即程序员倾向于不改变他们的编码习惯,并且不具备完全接受单元测试的能力。现有的代码库。他们将尝试编写集成测试,以一次测试现有应用程序的许多功能。众所周知,这种集成测试太难了,维护起来也太昂贵。建议:为新的代码库引入自动化测试。

单元测试是可以自动化的良好测试。上面的所有内容(集成测试,组件测试,系统测试)也可以自动进行测试,但是一旦同时测试更多功能,成本效益比就会迅速下降。如果您在未经单元测试的功能上进行此类测试,则会放大这种负面影响。建议:在单元测试级别上引入自动测试,并在单元测试的坚实基础上构建自动集成测试。 。如果您对单元测试感到满意,则可以使用有效的单元测试。当人们开始进行单元测试时,他们倾向于将他们现有的代码和编码习惯改造成单元测试。具有讽刺意味的是,这是学习单元测试的最困难的方法。此外,单元测试还要求您更改编码方式(例如,应用SOLID原则)。大多数程序员很快就停止编写单元测试,因为他们认为学习曲线太陡了,并且发现将单元测试包裹在一个不太容易测试的设计代码周围是很尴尬的。忠告:从头开始学习新代码的单元测试,并处理您需要更改编码习惯的事实。

还有很多其他因素,但是我发现对于大多数程序员而言,更改其代码编写方式很麻烦。未经测试编写的代码看起来就不同了。如果您不能将代码压缩到可测试的设计中,则很可能无法编写有效的单元测试。这破坏了进行有效的自动化测试的基础。关于其他因素,我可以写很多东西,但我认为编码习惯和单元测试是最重要的。幸运的是,有些人比我更有经验,并且用自己的专业知识来写书。其中一本书是.NET中的Brownfield应用程序开发,由于您使用的是Microsoft技术堆栈,因此我真的可以推荐。

评论


在单元测试级别引入自动化测试,并在单元测试的坚实基础上构建自动化集成测试。 +1

–c69
13年2月4日在22:39

#9 楼

有趣的是,该业务比开发人员更具亲测性!在我看来,您面临的最大挑战将是克服开发人员对变革的抵制。他们需要重新定义他们对工作的理解,以包括单元测试。如果您强迫他们做一些新的事情,请确保首先争取获得几乎可以肯定的奖励的事情。有些事物比其他事物更适合于自动化测试。对于第一遍,我不会测试数据库或UI。来自数据库的输入可能很难设置和拆除。 UI输出测试往往会因外观和感觉的变化而很快被破坏,而外观和感觉的变化与您的测试完全无关。明确定义了输入和输出条件的代码。如果您遵循DRY原则(“不要重复自己”),您将编写一些小类或函数来解决应用程序特有的重复出现的问题。更改现有内部组件的风险。在更改已经使用了很长时间的内部组件之前,编写单元测试。这些测试证明保留了当前可以使用的功能。进行更改并且所有单元测试都通过后,您知道您还没有打破任何“下游”问题。如果确实发现下游问题,请为其添加单元测试!

罗恩·海菲茨(Ron Heifitz)会说:“解决人们所持有的价值观中的冲突,或者缩小人们所代表的价值观与他们所面对的现实之间的差距。适应性工作需要改变价值观,信念或行为。克服了人类对变更的抵制之后,可以根据需要扩展到更困难的测试区域。

评论


“克服开发人员对变更的抵制”:并非每一种抵制都是没有道理的,不应使用“抵制变更”这一论点来避免诚实的讨论。

–乔治
13年2月7日在22:41

#10 楼

关于自动化测试的一件事是,它要求您编写可测试的代码。这本身并不是一件坏事(实际上是件好事,因为它劝阻通常应避免的许多实践),但是如果您尝试对现有代码进行单元测试,则可能不是以可测试的方式编写。

单例,静态方法,注册表,服务定位器之类的东西都引入了很难模拟的依赖关系。违反Demeter定律意味着您的代码库太多部分对代码库其他部分的功能了解得太多,从而引入了其他难以破解的依赖关系。所有这些事情使得很难将模块与其余代码库隔离开来,并且如果您不能单独测试模块,那么单元测试将失去很多价值。如果测试失败,是因为被测单元出现故障,还是由于其依赖项之一发生故障,或者是因为通过从属数据源提取的数据不是测试编写者所期望的?如果您不能用模拟代替依赖,那么任何一种都是可能的。

我见过的大多数未考虑单元测试的代码库本质上都是无法测试的,因为编码人员倾向于专注于使代码按他们期望的那样工作而不是去做保持耦合松散和显式依赖关系所必需。考虑到单元测试而编写的代码看起来会非常不同。

很多人在第一次开始进行单元测试时就采取了幼稚的方法,他们认为他们可以为现有的代码库编写大量的测试,但是一切都会很好,但是由于上述问题。他们开始发现必须在单元测试中进行大量设置才能完全运行它们,并且结果常常令人质疑,因为代码中缺乏隔离性意味着您无法追踪导致测试失败的原因。他们也倾向于开始尝试编写“智能”测试,这些测试演示了系统如何工作的高度抽象的方面。这往往会失败,因为“聪明”的单元测试本身就是潜在的错误源。是由于测试模块中的错误还是由于测试中的错误而导致测试失败?测试应该非常简单,以至于不可能有漏洞被隐藏。实际上,最佳测试很少会超过2行,第一行指示被测单元执行某项操作,第二行则断言它所做的是预期的。

如果您的团队认真考虑采用单元测试,那么从现有项目开始是不明智的。如果不进行重大重构,您团队的现有项目可能无法测试。最好使用一个新项目作为学习单元测试的基础,因为您可以使用一个干净的平台。您可以设计新的代码库,以使依赖注入优于单例,注册表和其他此类隐藏的依赖关系,您可以将其编写为依赖接口而不是实现等。您还可以(并且应该)与要测试的代码一起编写测试,因为事后编写测试会导致单元测试,从而确保被测试的模块执行了您认为可能要执行的操作,而不是测试它可以执行的操作规格说明应该怎么做。

一旦您对单元测试有了信心,您的团队就可能开始意识到其现有代码中的缺陷,这些缺陷将成为单元测试的障碍。这是您可以开始重构现有代码以使其更具可测试性的时候。不要雄心勃勃,立即尝试做所有这些事情,或者尝试用一个全新的系统替换一个可以工作的系统,只需从找到易于测试的代码库中开始即可(没有任何依赖项或存在明显依赖项的地方),并为它们编写测试。我知道我说过与代码一起编写测试比在之后编写测试更好,但是即使后来编写的测试也具有作为起点的价值。编写测试,就好像您对类的工作方式一无所知,除了其规范要求的内容外。当您运行测试并获得失败时,则说明或实现均不正确。仔细检查两者,以确定哪个是错误的,并相应地更新测试或代码。

一旦您摘下了低挂的水果,您的真正工作就会开始。您需要开始在代码库中查找隐藏的依赖项,并一次对其进行更正。在这一点上不要过于野心勃勃,只需坚持一次执行一个模块,或者甚至只在一个模块中执行一个问题,直到解决测试障碍,然后您就可以继续进行下一个工作。

TL:DR:大多数人认为测试很容易,并且您可以轻松地将测试改编为现有代码。这两个假设都是错误的。如果您考虑到这两个事实而着手进行项目的单元测试,那么您更有可能成功。

评论


提示:将TL; DR:放在顶部-我必须阅读您的所有帖子才能开始阅读! (有点失误)

– gbjbaanb
2014年9月1日,9:46

#11 楼


贵公司中有没有在自动化测试方面拥有丰富经验的人?

如果没有,自动化测试计划可能会失败。就像许多其他编程技能一样,自动化测试是一项技能,如果您没有经验的人,很难说出自动化测试是好的自动测试,还是有实际价值的测试随机失败/需要频繁更新/实际上没有执行任何有趣的代码。


有人具有领导力吗?他们有能力要求改变吗?

如果没有人听,他们说考试不好就没关系。 (请注意,领导力不一定要形式化。拥有一支关心团队的团队也很不错。)融入开发周期吗?

开发人员很懒。您需要使自己希望他们完成的事情变得容易,而让他们不希望自己完成的事情变得更加困难。您应该确保测试库可以轻松完成与测试设置和拆卸相关的任务,尤其是与环境相关的设置,例如测试数据库等。 (在其中的一些评论中讨论了模拟数据库,但应谨慎使用。真实的数据库应该易于启动,并允许您测试组件和流程生命周期的交互,通常比单元测试更重要,更有效一个单独的数据访问器。)

您还应该确保您的IDE具有启动测试套件的好方法。您应该经常运行测试套件,以便人们注意到它何时失败,而不是让它在痛苦中徘徊。开发人员对反馈的回应也很好,例如一个自动集成系统,如果他们未通过测试,则会还原他们的更改。或者,更好的是积极的反馈:一个自动集成系统,该系统可以捕获错误,并避免您遇到麻烦。

评论


我认为说开发人员是懒惰是不公平的。在您的经验中可能就是这种情况,但是肯定不是普遍真理。

–山姆
2013年6月27日下午6:15

#12 楼

首先,如果您的开发人员没有看到测试的价值,那可能是因为您的测试没有价值,不是因为您的开发人员对他们的价值或总体而言对测试的价值视而不见。在其福音传教士中,有一种趋势认为测试驱动的开发不会失败,它只会被懒惰的懒惰开发者失败。我认为这是错误的并且适得其反。

当我被介绍到测试驱动开发时,它的意思是有效地编写测试,以验证永不失败的方法永不失败。首先,这很好,因为您会获得漂亮的绿色检查和成就感。稍后,在重构代码之后,您会得到数十个令人发指的红色Xes,这些代码中没有什么比代码已更改,测试不再有效以及您浪费大量时间编写代码要多的了。 />
要避免这种情况。

从那时起,我就采用了另一种测试方法。我有一个接口,实现,测试三元组,而不是一个接口实现对。接口指定行为,实现执行行为,测试检查行为。

我想它似乎很明显,但是对我来说,它区分了必须证明指定的工作原理的代码和可以测试的代码(视需要而定)。您必须证明的代码是您提供给外部的接口;剩下的就是你一个人的问题。

在这种情况下,我会问开发人员,他们是否在代码中看到了适合进行此类测试的自然划分。有团队A实施和团队B使用的接口吗?在这种情况下,确保接口B符合预期的行为符合团队B的利益。要求B团队为其编写测试,然后告知A团队以确保其实现符合该测试;或者,如果没有,并且有意不与其他团队讨论意外更改,以便他们可以为此做好准备。

我认为这将说明测试。它本身并不是目的,尽管有可爱的绿色格子。它的存在是要明确一个开发者对另一个开发者的承诺,并确保将承诺保持为双方满意。

评论


我喜欢我能更好地阅读的代码,而不是像人们认为的那样需要对所有细节进行测试的代码。

–埃里克·雷彭(Erik Reppen)
13年7月6日在4:20

我觉得可爱的绿色勾是问题所在-它使测试成为某种游戏。

– gbjbaanb
2014年9月1日,9:48

#13 楼

在一个大型的现有项目中添加大量的单元测试是一项艰巨的工作。如果您已经找到了一个适合您的好的模拟框架,那么您应该已经解决了最棘手的问题。修复错误是最简单的错误。编写一个由于您的错误而失败的测试,然后修复该错误。同时,您可能会发现自己编写了一些更简单的测试并通过了。当然,您确实希望为此使用少量且易于测试的代码。

一旦人们开始习惯于为更简单的事情编写测试,您应该希望他们发现自己编写的代码更具测试性。

我还建议您衡量测试的代码覆盖率(我过去曾将cobertura用于Java)。您将需要一个连续的集成服务器来运行测试并定期(每天,每次签入)生成指标。如果您的开发人员热衷于此,那么他们将希望看到覆盖范围随着时间的推移而增加,并且可以看到您的某些
覆盖范围的缺口

#14 楼

我认为您可能需要长时间玩。要获得认可,您可以做的一件事是尝试对您编写的下一个功能进行彻底的单元测试,然后跟踪一段时间内的错误数量。您应该希望发现主要错误会在早期发现(特别是如果将其与Test-Driven Design结合使用),并且回归的数量应该很少。在一段时间(例如1年)后,将统计数据与具有类似复杂性的未经单元测试的功能进行比较。如果您可以证明新的错误和回归的数量明显减少,那么您已经为其提供了财务依据,并且产品团队更难以忽略。

我遇到了能够使用TDD和单元测试作为主要功能。在开发阶段结束后的5年内,没有一个bug被报告。当要求进行新的且有风险的增强功能时,我能够实现它并捕获单元测试中的所有回归。

#15 楼

我强烈认为,由于一些因素,很多团队都大大低估了单元测试的价值,许多因素已经在答案中突出了。工程对客户来说是充分的证明。这几乎总是适用于咨询公司和人为驱动的质量检查:如果客户不需要单元测试并且考虑到足够的实时演示,那么客户将完全失败,因为他将签署可能隐藏错误的代码。 >开发人员常常感到沮丧。成为程序员是一项艰巨的工作:完成一项任务并转到下一个任务是令人满意的,因此每个人都想着急并完成。直到他们被一辆带有重大错误的公共汽车撞到,而该错误在最初的质量检查之后几个月就出现了。在这种情况下,自动化和连续的质量检查不是管理人员的问题,而是开发人员的问题(他们仍然会因为工作而获得报酬,也许还会加班)。自动测试模型是完成测试的“人性化”功能。如果您正在使用前端测试Web模块,则尽管使用了Selenium之类的工具,您更有可能自己填写表格,查看结果并相信确定性。您会忘记稍后重新运行测试,或者您太懒了以至于无法再次执行旧的测试,这就是为什么有时在以后发现错误的原因。为了利用这一点,在银行环境中(根据我的个人工作经验),已经证明可以接受强大的代码模块化和严格的“修改旧代码”规则。
相反,如果开发人员负责开发高度自动化和大数据量的模块,则他更有可能编写详尽的单元测试并将其提交给测试批次。这是因为用从外部数据源(无论是否经过模拟)转换的数据填充大型XML有效负载并不是一件容易的事情。一些测试开发人员最终将为这种特定类型的测试构建一个小巧而有趣的前端。当我攻读硕士论文时,我正在使用每秒处理6000条以上syslog消息的日志总线,并且必须测量数据包丢失和损坏:我自然地为几乎所有组件(尤其是Syslog解析器)编写了单元测试和压力测试。 br />为了使开发人员更容易进行单元测试
,我相信他们必须被迫这样做。如果您是聪明的客户,则需要您的顾问在每个QA中运行完整的测试套件。如果您是优秀的团队领导者,则可以考虑将以下任务分配给聪明的开发人员:构建内部测试平台。使用内部效果平台反模式没什么可看的,而是一组帮助程序类,数据库模拟,配置,解析器,转换器,瑞士军刀来帮助开发人员立即构建测试。
当前的测试平台例如NUnit是通用的,允许您验证通用断言。正确使用依赖项注入和特定于项目的工厂可帮助开发人员减少用于测试的代码并变得更快乐。我还没有机会在一个完整的项目上进行实验,我无法提供现实的反馈。

#16 楼

自动化测试就像软件开发一样。不幸的是,您雇用的测试人员原本打算编写测试用例,计划,策略,遵循审核过程,手动测试和记录错误。

赋予他们自动测试职责后,它就包括大量软件开发。这里要注意的是,无论您使用什么工具(出于天生的考虑,不要争论这一点),自动化测试都需要每天进行维护和更新。随着开发人员更改代码,


您需要确保测试保持运行状态。
您需要确保未删除测试,因为它们没有运行
您的测试指标需要显示您在上一个版本和该版本上运行的内容。为了确保您的测试用例数量不会减少。
就像开发一样,也需要对测试用例进行审查,以确保人们不会陷入困境,将1个测试分解为2个只是为了增加数字(有时测试是外包的,因此此跟踪很重要)
开发人员与测试之间的更多“健康”交流非常重要
保持non-functional测试分开,不要期望他们每天运行它,这需要时间保持这些最新,并且很好。但是请不要放弃,请确保它们得到维护。他们不知道ifwhile循环之间的区别。坦率地说,因为没有课程教授自动化测试,所以他们只教授手动测试。
您的测试工程师太忙于手动测试您的构建并记录错误,因此他们松开了自动测试的轨道
您的测试经理不在乎指标来自自动化测试,只是因为它们显示了无效的数据(项目开始时),并且他们没有在日常的会议和会议中投入精力或优先级,以强调启动和运行自动化的重要性。
您选择为具有较短保质期的移动应用程序自动化测试。在撰写本文时,请稳定自动化测试套件,以使您的应用程序需求发生变化,而您应该专注于测试运行应用程序的Web服务。
您不了解自动化测试团队是开发团队,功能完善,代码完整,代码锁定和代码冻结。
您无需区分手动测试人员和自动测试人员。
他们两个都得到相同的薪水并向同一经理报告,理想情况下,他们应该向开发人员报告经理和他们的工资应该与开发人员的工资相匹配。
您实际上认为并相信junit不足以开发自动化测试:)。非常认真地进行测试,并了解开发人员作为自动化测试工程师非常重要。根据我为那些不了解的人工作的经验,无论您向他们解释多少,都可以理解其中的区别。

评论


对于单元测试和集成测试,应该编写测试的人员是开发人员,而不是单独的“测试工程师”。 (如问题所述,质量检查人员(即测试工程师)实际上已经在使用自动化UI测试。)

–PaŭloEbermann
13年2月6日在19:46

实际上,任何编写自动化测试的人都应该具有开发技能。

– Siddharth
13年2月7日在3:00