方法:为另一个开发人员编写单元测试


28

我当时在考虑软件开发和编写单元测试。我有以下想法:

假设我们有一对开发人员。每对负责一部分代码。一对中的一个实现了一个功能(编写代码),第二个为此编写了单元测试。测试是在代码之后编写的。以我的想法,他们互相帮助,但工作却分开。理想情况下,它们将处理两个相似大小的功能,然后交换以进行测试准备。

我认为这个想法有一些好处:

  • 测试是由某人编写的,可以看到更多有关实施的信息,
  • 工作应该比配对编程要快一些(同时具有两个功能),
  • 测试和代码都有负责的人,
  • 代码至少要经过两个人的测试,并且
  • 也许搜索正在测试您的代码的人编写的代码中的错误将为编写更好的代码和避免偷偷摸摸的行为提供特殊动机。

在代码和测试开发之间添加另一个开发人员进行代码审查也许也是个好主意。

这个想法有什么弊端?它已经被描述为某种未知的方法论并用于软件开发吗?

PS。我不是专业的项目经理,但是我对项目开发流程有所了解,并且知道一些最受欢迎的方法-但是这个想法对我来说并不熟悉。


17
您只是在单位级别描述下游质量检查。如果有成对的人在做某事,您是否尝试过使用TDD进行实际的成对编程?
jonrsharpe

9
如果测试编写者先进行测试(编写框架代码),而另一个则实现该功能,则这样做会更好。第一个控制设计,另一个控制繁重的工作。如果第一个知道自己在做什么,而第二个不介意一直跟随他的领导,那可能会很好。我不知道这种合作方式的名称。我会说..声称!开始称之为Franiis开发。
Martin Maat

14
这种批评是没有道理的,您的建议也无法解决该问题。
jonrsharpe

5
@franiis我见过同事写assert true为测试并称其为一天,因为每个测试都通过了。缺少一个重要步骤:测试应该首先失败,并且应该通过更改代码而不是测试来通过。
埃里克·杜米尼尔

6
@franiis TDD是围绕迭代构建的。编写失败的测试。编写使测试变为绿色的代码。重构。编写失败的测试。编写使测试变为绿色的代码。重构。似乎您缺少“重复进行,直到您的测试满足所有需求为止”这一部分。但是您似乎遇到的最大问题是,“测试”被视为您必须拥有的东西,因为有人这样说,而不是将测试作为对开发人员有用的工具。如果您不能让人们关心他们的代码的质量(和正确性),那就是您的问题,这就是您应该开始的地方。
a安

Answers:


30

使用成对的方式来分散编写生产代码和编写其相关的单元测试的工作量的通用方法并不罕见。我什至在获得成功之前就已经以这种方式个人配对。但是,编写生产代码的人和编写测试代码的人之间的严格界限不一定会产生结果。

当我使用类似的方法时,两人首先要进行交谈并获得对该问题的共识。如果您使用的是TDD,则可以先进行一些基本测试。如果您不使用TDD,也许您将从方法定义开始。从这儿开始,这对夫妇的两个成员都在生产代码和测试代码上工作,一个人专注于每个方面,但是他们在讨论如何改进生产代码以及背后的测试代码。

我看不出给每对两个功能带来的好处。您最终会得到一些类似于TDD的功能,而某些功能则与TDD无关。你失去焦点。您没有获得实时同行评审的好处。配对没有任何主要好处。

结对编程的实践不是关于速度,而是质量。因此,尝试使用由更快驱动的改进技术是违背自然的。通过通过并行代码审查和测试开发来构建更高质量的软件,您最终可以节省下游时间,因为至少有两个人知道每个更改,并且您正在消除(或减少)同行审查和测试的等待周期。


谢谢,我的想法是假设两个功能都以相同的方式开发(但是开发人员会互换角色)-只是为了澄清,而不是为了捍卫该概念。我喜欢您的答案,并且喜欢速度与质量。
弗兰尼斯

以我的经验,返工成本超过了这种方法的好处。我宁愿使用“乒乓”或其他方法来权衡这些义务。
neontapir

3
结对编程的实践不是关于速度,而是质量。Pair TDD是关于质量的,它带来了完成的速度,从而降低了开发成本。这只是我们的行业在学习泥工对于千禧世代的了解:如果您先花一些时间先设置弦线和泥工规则,再铺设砖块,则比用以下方法可以在更少的时间,更少的精力和更少的成本下建造更好的墙。您放下砖块,然后尝试用水平仪和槌进行调整。并获得帮助。
洛朗LA RIZZA

@LaurentLARIZZA似乎正确。我想有一种更好的说法是“结对编程的实践不是现在的速度,而是未来的质量和速度”。尽早发现问题,提高工作稳定性并共享知识以消除孤岛,这绝对是一种前瞻性做法。所有这些现在都有一定的成本,将来经常会得到回报。
Thomas Owens

@ThomasOwens:好吧,质量的成本只是感知的,不是真实的。一旦测试通过(并整理了代码),测试所描述的方案即已完成并得到保护,您可以放心它可以按预期工作。完成了,您可以继续。如果您不确定该代码是否有效,那么您只是承担了以后必须执行检查的债务。债务成本,而不是没有债务。我的意思是,您所说的“未来”是您的第一次测试通过后。
洛朗LA RIZZA

37

您的想法的主要问题是您不能只为任何代码编写测试。该代码必须是可测试的。

即您需要能够注入模拟,分离出您要测试的位,访问已更改且需要确认的状态等。

除非您很幸运或先编写测试,否则编写测试意味着可能会稍微重写代码。如果您不是最初编写代码的人,那么这将意味着延迟,会议,重构等。


谢谢。但是对TDD的普遍批评是,有时/经常编写代码来使测试“绿色”-不好。如果测试未测试代码的某些方面,则可以在代码中将其省略。稍后编写测试可能会有所帮助(我接受编写代码后可能需要进行一些更改,但是开发人员将来应该学习编写更多可测试的代码)。
弗兰尼斯

1
@franiis可以肯定,主要问题不是您在编写测试后,而是这样做与不是编写代码的同一人的组合。
伊万

但是,如果使用例如配对编程,则将减少耗时。如果两个开发人员在一个终端上工作,那么他们将不能以任何方式同时在两个功能上工作,我的想法应该允许这样做(即使范围有限)。由2人组成的微型团队的会议应该不是真正的负担。
弗兰尼斯

25
@franiis:“如果测试未测试代码的某些方面,则可以在代码中将其省略。” –这就是重点。这些测试以可执行示例的形式对需求进行编码。如果没有测试,那么就没有要求,也就没有代码
约尔格W¯¯米塔格

3
@JörgWMittag所说的另一面是:如果您的测试“不测试某些重要的代码”,那么您需要修复测试。在您的系统中,这与传统TDD中一样。
bta

15

在单元级别,我在这里看到的主要问题是,在编写代码时,我想对其进行编译,运行并立即删除最明显的错误-即使当代码不完整并且我知道该单元,功能部件或功能是仅部分实施。为了运行单元代码,我需要一些调用实现的程序,通常是单元测试或至少是部分单元测试。这不一定是“ TDD风格的书”,这样的测试可以在被测代码之后或之前编写。

当我的单元的一个版本“功能完整”并且没有我可以自己找到的所有错误时,将其移交给第二个人并让他/他编写其他单元测试或查看我的代码是有意义的。但是对我而言,一旦编译器未显示警告就立即将其移交是没有意义的,以防万一我知道我必须详细解释测试器的情况还为时尚早,自从我仍在编写那段代码后的两个小时内,情况有所不同。恕我直言,在详细程度上为此所需的通信开销不会受到收益的平衡。

因此,是的,让第二个开发人员编写其他单元测试是有意义的,但不是专门编写单元测试的。


7

似乎有可能发生以下任何一种情况-所有这些都是不希望的:

混乱

正如Ewan概述的那样,CUT可能需要进行更改以使其可测试。更改的原因对于开发人员而言并不总是很明显(可能会引起分歧),这正是为什么首先编写测试的原因。

争夺

开发人员A可能已完成其代码并希望对其进行测试。开发人员B也可能正在开发中,因此可能会不愿保留其代码以参加单元测试。

上下文切换

即使开发人员B愿意搁置他们的开发来测试开发人员A编写的代码,活动的改变也要付出一定的代价。


数十年来,人们公认将人力增加一倍并不会减少开发时间。考虑到我上面概述的因素,很难看出这种安排将如何改善情况。


4

当与结对编程TDD结合使用时,这称为“ 乒乓模式”

  • A编写了一个新测试,发现它失败了。
  • B实现了通过测试所需的代码。
  • B写了下一个测试,发现它失败了。
  • A实现通过测试所需的代码。

等等。只要开车的人有需要,就会进行重构。

但是您似乎建议两个程序员使用不同的计算机进行编码。分开进行将需要具有非常低的级别规范。这违背了敏捷方法论。每个变更都需要进行协调。在TDD中,您正在进行低级设计,这不是问题。我认为您的方法将需要已经编码的某种骨架。

无论如何:即使没有100%的效率,您也可以通过测试新的工作方式来学到很多东西。您可以进行测试并分享您的真实生活经验


3

我参加这个聚会迟到了,但是我想补充一下。

它已经被描述为某种未知的方法论并用于软件开发吗?

您正在描述对等测试

假设我们有一对开发人员。

啊,对编程好

每对负责一部分代码。一对中的一个实现了一个功能(编写代码),第二个为此编写了单元测试。测试是在代码之后编写的。以我的想法,他们互相帮助,但工作却分开。

那不是结对编程。

理想情况下,它们将处理两个相似大小的功能,然后交换以进行测试准备。

绝对是对等测试。这是有关它的ACM论文。我已经做到了 我曾在同行评审过程的正式部分工作过。这很有用,但这当然不是测试的第一线,而且也不是经典的结对编程。

为此的另一个名称是Whitebox Testing。尽管该定义本身并不涉及谁在进行测试,而是与测试人员可以看到他们正在测试的事物的内部运作这一事实有关,而不是与黑匣子测试相反,因为黑盒子测试只能看到其中的内容并进行测试。什么结果。黑匣子通常是质量检查的工作。

测试的第一行牢牢掌握在编码人员手中。如果不是,您是要我不要自己测试我的代码,而我断然拒绝这样做。我从10岁起就一直在测试自己的代码。那时我可能还没有进行过漂亮的单元测试,但是我的代码已经过测试。每次我运行它都经过测试。

我对同行测试人员的期望是添加到我的测试中的测试。通过测试,可以使他们在查看代码时发现同伴发现的问题更加清晰。通过使用自动化测试来表达这些问题,可以更轻松地理解它们的含义。实际上,我与同龄人进行了技术交流,他们只是不明白我的意思,然后意识到向他们展示问题的最佳方法是编写单元测试。那就是对等测试。

现在,如果您想给我编写测试,然后再编写我的代码就可以了。没有什么像需求文档那么正式以至于可以进行编译。


感谢您的回复,并向我介绍了对等测试(我会阅读的内容)。
弗兰尼斯

1

我已经完成了DDT(开发驱动测试,也就是代码后的测试),结对编程和红绿重构TDD,每年都有。要逐点回答您的主张:

测试是由某人编写的,他可以看到有关实现的更多信息

编写测试的人员需要尽可能地了解实现,以便编写覆盖面广的测试而无需过度测试。典型的例子是使用三个输入进行测试,而其中两个将证明您要测试的内容。尽管他们可以通过阅读代码来使他们对代码有一定的熟悉度,但他们将无法完全理解原始开发人员经历了什么才能到达当前状态。因此,他们对代码的理解将不尽人意。

工作应该比配对编程要快一些(同时具有两个功能)

我不明白你为什么这么说。有人编写测试时,他们无法使用新功能。通过为某人提供两种不同类型的工作,您无法神奇地使某人的工作能力加倍。以我的经验,编写测试通常比编写生产代码,因此,在编写另一个功能时,您肯定不能高效,负责地对某些代码进行测试。

测试和代码都有负责人

首先,测试就是代码。对企业而言,测试代码几乎与生产代码一样重要,因为它使企业无需担心即可更改软件。其次,这与编写测试和生产代码的人,甚至编写两个代码的人都没有什么不同

代码至少要经过两个人的测试

不,它仅由编写测试的人进行测试。除非您想花更多的时间进行测试,否则为什么要停在两个位置?

也许搜索正在测试您的代码的人编写的代码中的错误将为编写更好的代码和避免偷偷摸摸的行为提供特殊动机。

开发人员(甚至高级人员)有不同的想法,即什么构成“好的”代码。一个人的捷径是另一个人尽快获得工作代码的完全有效的方法。这是怪罪和游戏系统的秘诀。

红绿重构TDD(实际上是在编写生产代码,运行它,看到它失败,修改生产代码再次运行测试,看到它成功,然后重构,而不重构或交换任何内容之前编写一个测试)这些步骤)和代码审核工作。


(大概)会更快,因为您没有两个人在做“相同的工作”-他们每个人都在做自己的事情,然后中途交换。
雅各布·赖勒

@JacobRaihle配对不是两个没有交流的人并肩发展。那将是两个人从事的工作相同。配对是真正有效的,因为两个人合作的一个作品。以我的经验,开发速度大约与单个程序员一样快(即,一对程序员完成工作的速度是原来的两倍),由此产生的软件质量更高,知识也得到了共享。
l0b0

我试图解释“应该使工作快一些”的理由,这似乎使您感到困惑。配对通常在我的经验中比较慢,尽管我仍然认为这是值得的(最好是个人工作和OP测试交接)。如果对您来说更快,那就更好了。
雅各布·赖勒

1

我认为这个想法有一些好处:

乐透了他们。

测试是由某人编写的,可以看到更多有关实施的信息,

因此,您的意思是说第一个开发人员已经花了一些时间编写一些实现,但他不确定这样做是否可行。然后,另一位开发人员来编写测试,将其推理基于没有人知道它是否正确的代码,并希望与仅针对代码应做的事情编写测试相比,它带来了战术上的优势。如果实现不正确,我认为它将为编写测试带来零帮助。

工作应该比配对编程要快一些(同时具有两个功能)

两位开发人员完成初始开发后,没有人知道他们的代码是否正确。这仍然有待检查,没有人可以完成任何一项,也没有人可以预测何时完成。将此与TDD进行比较:首先编写测试,然后使测试失败,然后通过代码。该代码支持越来越多的场景。那是向前运动。

如果使它们并行进行,则可以在两个功能中重用的代码将被编写两次,并且成本将增加两倍。

测试和代码都有负责的人,

查看XP提出的集体代码所有权。您将有更多的人负责该代码。如果您的目标是在开发人员之间共享知识,那么为什么要隔离他们?

代码至少要经过两个人的测试

也与双TDD。配对时,两个人都必须同意编写的代码足够或不编写代码。如果那导致了一场战斗,那么团队中的某些人会出现自我定位问题。

也许搜索正在测试您的代码的人编写的代码中的错误将为编写更好的代码和避免偷偷摸摸的行为提供特殊动机。

搜索错误意味着在某些时候,您可以容忍它们进入。如果它们进入,则它们不会被注意到。首先拒绝编写测试就是授予错误进入许可。

偷工减料可能是无意的。这就是配对编程的目的。应该指示这对成员中的每个成员都有义务不要让其他人走捷径,因为好吧,我们都这样做。这就要求您将自尊心留在壁橱中,并在您离开办公室时收回。如果您希望自己的员工严谨严谨,那么您就不会考虑共同的情况并为失败做好准备。

XP明确表示,所有实践XP都是通过弥补彼此的缺陷来相互增强的。您不应该听别人批评XP的任何其他实践。没有人能做到完美,TDD也不完美,结对编程也不完美,集体代码拥有权也不完美,但是它们相互覆盖。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.