我们正在研究已经生产大约5年的大型产品。该代码库在工作。效果不是很好,但是可以正常工作。新功能投入生产并通过少量质量检查进行了测试。错误已修复,等等。但是除我以外,没有人在编写单元测试。没有人通过编写单元测试来确保所有特殊错误(测试用例)再也不会发生,从而利用“跟踪”错误的能力。

我已经和管理层谈过了。我已经和开发人员谈过了。我已经与整个公司的所有人进行了交谈。每个人都说:“是的,我们必须编写更多的单元测试!”那是大约一年前。从那时起,我就不得不引入预提交代码审查(Gerrit)和持续集成(Jenkins)。

我举行了一些有关单元测试的会议,还展示了编写单元测试的好处。但是似乎没有人对此感兴趣。

问题1:如何激励我的同事编写单元测试?

问题2:如何保持遵循个人代码质量标准的动力? (有时真的很令人沮丧!)

PS:
一些令人沮丧的事实(在1年内达成):


总单元测试: 1693
总“示例单元测试”:大约50
我做的:1521

编辑:我期望太多了吗?这是我的第一个工作地点,我正在努力做到最好。

编辑2:根据所有答案,我为自己做了一个小清单。我已经与两位开发人员私下交谈,我们进行了坦诚交谈。

其中一个告诉我,就像Telastyn所说的那样,他对单元测试真的很不满意。他说他想变得“更专业”,但是他需要一个启动。他还说,我们与所有开发人员(9-11岁左右)进行的单元测试会议很好,但是太拥挤了。嗯一些批评家给我,但我会从中学到东西。 (请参阅以下有关tdd kata会议的回答!)

另一位表示他对编写单元测试不感兴趣。他认为自己的工作足以应付他的薪水。他不想付出更多的努力。我很无语。典型的9-5岁的“工人”。

下周,我将与其他开发人员交谈。

感谢您的宝贵回答(到目前为止!)和支持。我真的很感激!我学到了很多东西,非常感谢!

评论

您是前几年进行的其他172项单元测试,还是其他人在进行单元测试,您在轻视他们的贡献?

其他172个单元测试是由离开公司的开发人员完成的。伤心:(

请保持通话号码。去年发现了多少个错误,发现了多少个错误,以及有多少个被单元测试阻止了。与“做真实的工作”(用同事可能认为的话)相比,编写测试需要多少时间(一个人一年要花费1521)。他们是否认为UT是有益的,还是浪费时间。即给我看钱。

出于好奇,您的同事是否有其他调试策略? TDD对于证明某些功能可以按预期工作很有用,但对于未知问题则无济于事。他们可能只需要挂接到调试器即可。

将调试器挂接到测试目的是正确的,但是它不能确保代码在几天/几周/几个月内都能正常工作,这是真正的问题。

#1 楼

我注意到谈论TDD几乎没有用。人们喜欢看到原始结果。说“编写测试将减少开发时间”很可能是正确的,但这可能不足以使任何人信服。

我处于相似的位置(嗯,还不如您的糟糕),并且当人们开始使用我的代码时,它会自行解决(注意:我的代码已经过单元测试,而其他人则没有那么多)。当某事停止工作时,当地调查后自然会跟我问可能是什么原因。然后我们坐下来,进行单元测试,看看发生了什么。如果测试通过,则大多数时候问题出在未经测试的新代码中。如果没有,测试通常能够发现问题(或至少将我们指向正确的方向)。我们修复了该错误,再次进行了测试,每个人都很高兴。

长话短说,发生了这种情况,还有2个开发人员成为了TDD /测试狂热者(还有很多工作要做) ,但看起来很有希望)。

作为建议,您可以尝试一下TDD kata;使用测试优先方法(而不是测试)来实现的一项简单任务。根据任务的复杂程度,非测试方法通常应较慢,尤其是在需要进行增量更改的情况下:


罗伊的字符串计算器
银行OCR

编辑:OP的评论使我意识到他有一个更强有力的论据-回归也就是返回错误。此类情况是证明有益的单元测试的完美示例。人们喜欢数字-就像我说的那样,告诉“单元测试是好的”可能并不令人信服,但是像下面这样安排数据肯定可以是:


实现功能所花费的时间(没有测试书面;我认为这种情况经常发生,因此找到这样的例子应该相对容易)
用TDD实现功能的估计时间(甚至是采用方法后的测试;没关系-重要的是存在单元测试)
解决未经测试的代码与经过测试的代码上的错误所花费的时间


要警告您的一件事(这种错误很明显,但值得注意):结果偏见-确保您不选择示例在测试中发现错误的唯一方法是为该错误编写测试。通常,没有人知道错误会提前发生,但是很容易说“如果我们对X进行测试,这个错误将是微不足道的”-很容易在战争结束后为战争找到制胜法宝。

这些示例的结果应该是一个简单的问题-如果您可以花x个小时的时间来开发特征Y,为什么要坚持用2倍来完成呢?

评论


感谢您的输入。我想我要安排一个带有kata的TDD会议。每个会议有两名开发人员,所以我可能会帮忙。是的,该软件“有效”。但是,许多错误是“返回”错误。如果有人在模块A中修复了某些问题,则子模块A1在某些情况下将不再起作用。这些错误(大部分)在质量检查期间未找到。那真是浪费时间。编写单元测试:(也许)1小时。从客户那里获取错误报告,分析,计划,修复,代码审查,构建,修补程序交付等。大约.. 6-8h。

–下方
2012年7月18日在20:24

图片总值1000字。显示节省时间要比说这应该节省时间更具说服力。

–R0MANARMY
2012年7月18日在20:25

@lurkerbelow:返回错误(或者您愿意的话可以回归)是一个很强的参数。考虑一下如何安排在这些示例中花费过多时间的现有问题或错误,并说明编写测试可能会有所帮助。

–k.m
2012年7月18日在20:43

以我的经验,编写测试不会减少开发时间,至少不会减少开发时间。它增加了它。但是,它确实会产生更可靠,设计更好,更易于维护的软件。

–罗伯特·哈维(Robert Harvey)
2012年7月20日在5:44

@RobertHarvey:你是对的,“发展”在我这方面是糟糕的措辞选择。我无法提出任何更好的描述设计,实现,发布和维护软件的过程的信息。从长远来看,UT会缩短/简化此过程,这就是我的想法。

–k.m
2012年7月20日在22:37

#2 楼

首先,您必须知道他们为什么不编写测试。

紧迫的开发计划通常是造成这种情况的原因,但是您却说那没有。

下一个原因是,由于现有的大量未经测试的代码库,编写测试似乎似乎压倒性-永无止境的工作(如洗衣服和令人兴奋的事情)。因此,人性是要面对太多,因此我将其跳过。

另一个原因可能是,尽管他们认为测试是一个好主意,但他们对如何开始写作并不自信特别是如果他们从未在能写这些文字的地方工作过。

另一个强大的可能性是,即使他们为这个想法提供口头服务,他们的确没有看到更多工作的价值。

那么您如何处理不同的问题原因?

原因之一很简单,向他们展示如何节省开发时间的示例。

原因二-向他们展示您一年编写了多少测试,以及进行了哪些测试它涵盖的代码库的百分比。做数学运算,以显示如果他们这样做,明年此时可以进行多少测试。一旦他们每天看到一点点进展真正加起来,整个想法就不会那么令人沮丧。如果您可以将数据拉出系统,请向他们显示代码未测试部分中有多少错误是重复错误,以及使用单元测试在代码中出现了多少重复错误。

原因3是训练,而不仅仅是展示。让他们在培训课上写测试。

原因4,这是问题的关键。首先,选择一个痛点,这是多次返回的错误之一。当出现这种情况时,现在是时候向管理层建议,如果他们对此项目进行了单元测试,它就不会像坏钱一样不断回来。

解决原因4的另一种方法是让管理层将其纳入流程的一部分,并且除非测试也通过代码审查,否则代码不会通过代码审查。最好在这些痛点之一之后,或者最好在几天之内遇到几个痛点之后立即制定一项政策来接近他们。

我们都喜欢认为,作为开发人员,我们要进行自我管理(LOL),但是雄心勃勃的人会关心管理向他们强调的一点,即他们应该关心的人,真正从事自我管理的专业人员是已经编写测试了。如果他们既不因提高产品质量而不在乎专业并采取最佳做法,也不在乎如何打动经理人而获得晋升(或不被解雇),那么您可能会考虑这是否是适合您的地方。如果您无法让管理层关注最佳实践,那么您将一路艰苦奋斗,您可能会评估这是否适合您的企业文化。尽管每个工作场所都有其问题(逃跑并不总是答案),但这个场所似乎并不适合您的专业水平。

#3 楼

我将从演示TDD的好处开始。尝试展示单元测试的好处。

作为普通人,开发人员会受到好处的激励。他们不想做只会增加工作量的事情。单元测试意味着更少的工作。这意味着更多地和朋友出去。这意味着要有更多的乐趣,因为您不必每天晚上花费到晚上11点。这意味着您可以放心地度过假期。

TDD的最大好处之一就是您可以将程序重构为更好的设计,或者只是更改名称...只要该设计不会破坏测试,您就可以100%确信所做的更改不会破坏任何东西。

TDD的另一个好例子是为遗留代码创建单元测试。这将是开始重构邪恶的最好方法之一。从长远来看,这将有助于提高您对代码库的了解,了解其优缺点,在代码中发现硬编码的业务逻辑,并为您提高前进的质量提供了良好的开端!

可供进一步阅读的参考资料:


为什么要编写单元测试
激励可见性和单元测试
Roy认为单元测试的艺术Osherove


评论


@lurkerbelow,好吧,现在您的下一个任务是监视这些位置上的错误-密切关注您的错误跟踪器和随之而来的代码更改。如果没有错误,那么您的同事就有意思了。如果有负载,那么你有一点。无论哪种方式,您都会得到一些经验证据。

– gbjbaanb
2012年7月19日在12:50

在我看来,您可以证明所做的更改没有破坏其他事实的事实是一种巨大的力量。工作软件的即时响应也很有用。不幸的是,有些人永远都不想尝试启动学习。具有讽刺意味的是,在我们的即时满足文化中,有限的初创公司无法满足即时满足的需求。

–珍妮佛S
2012年7月19日在13:18

#4 楼

这似乎是一个以身作则的大案例。

您正在与人性作斗争的两个内在方面:


有创造力的人不喜欢流程。
大多数人不喜欢对其质量进行外部负面评价。

很难通过讲授,管理声明甚至逻辑来与之抗衡。您必须赢取利用人性的另一个方面的优势。


人们模仿最好的员工的行为

如果最好的员工使用TDD及其它工程,这个过程将扩大。如果他们不这样做,那就不会。如果您需要说服任何人,那就是前1或2名员工。

评论


值得注意的是,如果您尚未处于包含TDD的文化中,您的同事就不会推动您变得更好。如果他们发现您的方法存在缺陷,他们会大声说出“这样它永远不会起作用”。要以身作则,您必须投入自己的时间和精力来改进方法。

–完美主义者
2015年2月25日在15:14

#5 楼

http://blog.jtimothyking.com/2006/07/11/twelve-benefits-of-writing-unit-tests-first

我想我把Jeff Atwood文章中的那个链接标记为书签以前[编辑:是,这里是]。老但相关。由于这些好处以及其他答案中肯定会列出的其他好处,您的程序员应该能够激励自己!这将使他们的工作效率更高,从而使他们的工作更加轻松。谁不想这样?

关于第二个问题:您的主人翁意识和对代码质量标准的自豪感应该使您与他们保持一致。考虑一下您想通过拥有这样的标准来实现什么以及谁可以从中受益。我的个人代码标准也可能令人沮丧,但是我始终觉得我正在通过实施它们来帮助世界/公司/团队。因此,我认为您并没有尝试做太多的事情-结果会因地方而异,但至少您正在付出努力。

#6 楼

问他们。

您说人们已经被告知,并同意他们应该编写更多测试。他们为什么不呢?

这可能不是(通常不是)简单动机的问题。他们可能会忘记他们。他们可能会感到时间紧迫。他们可能不知道如何编写好的测试。他们可能会认为您太好了,以至于他们不需要这样做。了解根本原因将帮助您更好地解决问题。

评论


从理论上讲,这是一个好主意,但是很难回答这个问题。因此,如果您知道单元测试是好的,那么为什么不使用它们呢?听起来像个混蛋,例如,我不知道怎么做,或者我没有时间,或者我很聪明,我的代码应该可以工作。这种情况通常会使人们感到防御,而您将获得较差的结果。

–R0MANARMY
2012年7月18日在20:28



我不想指出其他人的“错误”。也许我应该在私下聊天,例如喝啤酒或十杯。时间压力并不是重点。我们有足够的缓冲时间安排好行程。 (估计超过150%)

–下方
2012年7月18日在20:34

#7 楼

您可能会认为单元测试本身就是销售。我不知道您的公司如何运作,但是如果在产品发布期间出现问题,我们会一直进行到解决为止。周日凌晨2点是否发生都无关紧要。这对我们来说是非常罕见的,但是一旦这样做,它就糟透了。

首先,我要问他们半夜起床几次,以解决一些很容易被自动化测试发现的重大问题。这并不是说自动测试可以解决所有问题,但是应该可以帮助减少故障。

第二大卖家是质量检查周期。在我公司开始TDD之前,我们将每周对新版本进行质量检查。他们会从该发行版中产生大量错误,我们将修复这些错误并推出另一个发行版。重复直到完成。我们进行TDD的第一个项目直到几周后才要求进行质量检查。发现的错误数量非常少。与类似项目相比,降低了10%。无论如何,您是否有能力为团队编制这些统计数据?

另一个大卖点是采用TDD后代码看起来如何,更易于阅读,因为我们想使测试变得更容易。显示为单元测试编写的代码与未编写的代码之间的比较。

最后,向他们展示如何自信地重构代码。

当您不想编写测试时,请记住所有这些。 :)

#8 楼

我想详细介绍HLGEM的答案,尤其是以下部分:


下一个原因是,由于现有的未经测试的代码库很大,编写测试似乎势不可挡-永无止境的工作(例如洗衣和令人兴奋)。因此,人类本性是要面对的事情太多了,因此我将其跳过。


我发现我编写用于编写测试的代码比编写代码要好得多我编写的代码无意编写测试;问自己如何测试此功能?强制对每个功能进行更好的设计。 (较少依赖全局或半全局数据; IO与计算分离;函数仅做一件事;一致的错误处理;等等。)

尝试对未编写的旧代码进行测试考虑到测试可能会令人沮丧。

#9 楼

我使用了一些技巧:

a)设置自动构建。当某人破坏了您测试的内容时,请向他们展示测试如何检测到该错误以及该错误的严重程度。

b)使用测试进行复杂的项目(驱动)。这将显示该项目中几乎没有错误。我有一个复杂的服务器交互项目,可以完美地开始工作。它从未通过质量检查,所有集成测试均顺利进行了100%。该系统被称为高度稳定,并且整体管理对此感到满意。在这些情况下,您可以做的事情是如何通过单元测试实现的。

c)一次吸引一个人。听你的那个人。试一试错误,并展示测试如何揭示深层而棘手的问题。这会有所帮助。这绝非易事。但是一旦获得支持者,他只会帮上忙。这是多米诺骨牌效应。

评论


c)适合我的情况

– Nakilon
15年11月13日在17:15

#10 楼

在此过程中进行单元测试。如果生产中出现的错误太明显而无法进行单元测试,那么这家伙就应该承担责任。指派人员编写他们进行的每个测试。每周随机挑选案例并观察少数案例的执行情况。通过进行单元测试,人们会询问需求,并最终将需求与开发联系起来,并希望开发既可运行又可运行的软件:)

评论


感谢您的输入。您指出编写单元测试会迫使开发人员对需求等进行进一步思考。有时这确实是一个问题。功能A已实现且正在运行。 QA告诉开发人员,测试用例x无法正常工作,因为他没有想到可能的副作用。我们正在使用持续集成来执行我们的单元测试。如果有人签入,则将运行所有测试。因此,在交付给质量检查人员/客户之前,我们会发现可能的副作用。

–下方
2012年7月18日在20:44

单元测试不同于集成测试。我相信开发人员还负责集成测试,并且质量保证角色将是确保一切都井井有条(在他们可以执行的验证范围内)。当然,可能存在版本,遗失片段,向服务器分发代码等问题,这些问题无法及早发现,但与需求或单元测试无关。

– NoChance
2012年7月19日在9:02