你什么时候在TDD中编写“真实”的代码?

johnny 08/19/2017. 11 answers, 20.464 views
tdd

我在培训视频中看过的所有例子都有简单的例子。 但是我没有看到我是如何在绿化后做“真实”的代码的。 这是“重构”部分吗?

如果我有一个相当复杂的对象和一个复杂的方法,并且我编写我的测试,并且最低限度让它通过(在它首次失败之后,红色)。 我什么时候回去写真正的代码? 我在重新测试之前写了多少实际代码? 我猜想最后一个更直观。

Edit:感谢所有回答。 你的所有答案都非常有帮助。 对于我所问或所困惑的内容似乎有不同的想法,也许有,但我所问的是,如果我有建立学校的申请。

在我的设计中,我有一个我想要开始的架构,用户故事,等等。 从这里开始,我收录了这些用户故事,并创建了一个测试用户故事的测试。 该用户说,我们有人参加学校并支付注册费。 所以,我想到了一种使失败的方法。 在这样做的时候,我为X类(也许是学生)设计了一个测试类,这将会失败。 然后我创建了“学生”班。 也许“学校”我不知道。

但是无论如何,TD Design正在迫使我去思考这个故事。 如果我可以让测试失败,我知道它为什么失败,但这是以我能够通过的。 这是关于设计。

我把它比作递归思考。 递归不是一个硬性概念。 实际上,在你的脑海中实际记录它可能会更困难,但实际上,最难的部分是知道什么时候递归“休息”,什么时候停止(当然是我的意见)。所以我必须考虑停止什么首先递归。 这只是一个不完美的类比,它假设每个递归迭代都是“通过”。 再次,只是一个意见。

在实施中,学校很难看到。 数字和银行分类账是“容易的”,因为您可以使用简单的算术。 我可以看到a + b并返回0,等等。对于一个人的系统,我必须更加努力地思考如何implement它。 我有失败,传递,重构的概念(主要是因为学习和这个问题)。

在我看来,我不知道的是缺乏经验。 我不知道如何注册一个新学生失败。 我不知道如何让某人输入姓并使其被保存到数据库中失败。 我知道如何为简单的数学做一个+ 1,但是对于像人这样的实体,我不知道我是否只是测试以确定当某人在某个名称中输入名称时是否返回数据库唯一ID或其他内容数据库或两者或两者皆不。

或者,也许这表明我仍然感到困惑。

5 Comments
187 hobbs 07/25/2017
TDD人们回家过夜后。
14 Goyo 07/25/2017
你为什么认为你写的代码不是真实的?
2 johnny 07/26/2017
@RubberDuck比其他答案更多。 我相信我会尽快提及。 这仍然是一种外国,但我不会放弃它。 你说的话有道理。 我只是试图让它在我的上下文或常规业务应用程序中有意义。 也许是一个库存系统或类似的。 我必须考虑它。 我很感谢你的时间。 谢谢。
1 Edmund Reed 07/26/2017
答案已经触及头部,但只要所有的测试都通过了,并且你不需要任何新的测试/功能,就可以假定你的代码已经完成了。
3 Borjab 07/26/2017
在“我有一个复杂的方法有一个相当复杂的对象”这个问题中可能存在问题。 在TDD中,您首先编写测试,然后从相当简单的代码开始。 这将迫使您编写一个需要模块化的测试友好结构。 所以复杂的行为将通过组合更简单的对象来创建。 如果你以一个相当复杂的对象或方法结束,那么当你重构

11 Answers


RubberDuck 07/27/2017.

如果我有一个相当复杂的对象和一个复杂的方法,并且我编写我的测试,并且最低限度让它通过(在它首次失败之后,红色)。 我什么时候回去写真正的代码? 我在重新测试之前写了多少实际代码? 我猜想最后一个更直观。

你不“回去”写“真实的代码”。 这都是真正的代码。 你所做的是返回并添加另一个测试, forceschange你的代码,以使新的测试通过。

至于在重新测试之前你写了多少代码? 没有。 如果没有失败的测试,您可以编写zero代码,这会forces您编写更多代码。

注意模式?

让我们通过(另一个)简单的例子,希望它有所帮助。

 Assert.Equal("1", FizzBuzz(1)); 

容易啪嗒。

 public String FizzBuzz(int n) {
    return 1.ToString();
} 

不是你会称之为真正的代码,对吧? 让我们添加一个强制进行更改的测试。

 Assert.Equal("2", FizzBuzz(2)); 

我们可以像if n == 1那样做一些傻事,但我们会跳到理智的解决方案。

 public String FizzBuzz(int n) {
    return n.ToString();
} 

凉。 这将适用于所有非FizzBu​​zz号码。 接下来的输入是什么会迫使生产代码改变?

 Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
} 

然后再次。 写一个不会通过的测试。

 Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
} 

现在我们已经覆盖了所有三个倍数(也不是五的倍数,我们会记下它并返回)。

我们还没有为“Buzz”写一个测试,所以让我们来写一下。

 Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
} 

而且,我们知道还有另一种情况需要处理。

 Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
} 

现在我们可以处理所有5的倍数,也不是3的倍数。

直到这一点,我们一直忽略重构步骤,但我看到了一些重复。 现在我们来清理它。

 private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

凉。 现在我们已经删除了重复并创建了一个命名好的函数。 我们可以写的下一个测试会迫使我们更改代码? 那么,我们一直在避免数字可被3和5整除的情况。现在让我们来写它。

 Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

测试通过,但我们有更多的重复。 我们有选项,但是我会多次应用“提取本地变量”,以便重构而不是重写。

 public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

我们已经涵盖了每一个合理的投入,但是unreasonable投入呢? 如果我们传递0或负数会发生什么? 编写这些测试用例。

 public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

这开始看起来像“真正的代码”呢? 更重要的是,它在什么时候停止成为“虚幻代码”并转变为“真实”? 这是思考的问题...

所以,我可以简单地通过寻找一个我知道在每一步都不会通过的测试来做到这一点,但我有很多练习。 当我在工作时,事情并非如此简单,我可能并不总是知道什么测试会强制改变。 有时我会写一个测试,并惊讶地发现它已经通过了! 我强烈建议你在开始之前养成创建“测试列表”的习惯。 这个测试列表应该包含您能想到的所有“有趣”输入。 您可能不会全部使用它们,您可能会随时添加案例,但此列表可用作路线图。 我的FizzBu​​zz测试列表看起来像这样。

  • 六(3的非平凡倍数)
  • 九(3平方)
  • 十(非平凡的5倍)
  • 15(3和5的倍数)
  • 30(不重复3和5的倍数)
5 comments
3 maple_shaft♦ 07/27/2017
评论不适用于长时间的讨论; 这个谈话已经转移到聊天
40 GManNickG 07/27/2017
除非我完全误解了这个答案:“如果n == 1,我们可以做一些傻事,但我们会跳到理智的解决方案。” - 整件事很傻。 如果你知道前面你想要一个执行<spec>的函数,那么为<spec>编写测试,并跳过你编写明显失败<spec>的版本。 如果您在<spec>中发现错误,请确保:先编写一个测试,以确认您可以在修复之前进行测试,并在修复后观察测试通过。 但是没有必要伪造所有这些中间步骤。
15 user3791372 07/28/2017
指出这个答案和TDD总体上的主要缺陷的评论已被转移到聊天。 如果您正在考虑使用TDD,请阅读“聊天”。 不幸的是,“质量”的评论现在隐藏在一个聊天负载中供未来的学生阅读。
nbro 07/28/2017
如果你想改善这个答案,我会更精确地讨论这个“测试列表”的内容。 我会明确地谈论“边界值”和“班级分区”。
2 hvd 07/30/2017
@GManNickG我相信重点是要获得适量的测试。 事先书写测试可以很容易地错过什么样的特殊情况应该被测试,从而导致测试中没有被充分覆盖的情况,或者基本上相同的情况在测试中被毫无意义地覆盖。 如果没有这些中间步骤就可以做到这一点,太好了! 然而,并不是每个人都可以这样做,这是需要练习的。

GenericJon 07/24/2017.

“真实”代码是您为了通过测试而编写的代码。 Really 。 就这么简单。

当人们谈论编写最低限度的绿色测试时,这意味着你的真实代码应该遵循YAGNI原则

重构步骤的想法就是清理你写的内容,只要你满意就满足要求。

只要你写的测试实际上包含了你的产品需求,一旦他们通过了,代码就完成了。 想想看,如果你的所有业务需求都有测试,并且所有这些测试都是绿色的,那还有什么要写的? (好吧,在现实生活中,我们并不倾向于拥有完整的测试覆盖率,但理论是正确的。)

5 comments
44 Derek Elkins 07/24/2017
单元测试实际上不能满足你的产品要求,即使是相对微不足道的要求。 最好的情况是,他们对输入输出空间进行采样,这个想法是你(正确地)推广到完整的输入输出空间。 当然,你的代码可能只是一个大switch ,每个单元测试都可以通过所有测试,并且不会出现任何其他输入。
8 Taemyr 07/25/2017
@DerekElkins TDD强制要求失败的测试。 没有失败的单元测试。
6 jonrsharpe 07/25/2017
@DerekElkins这就是为什么你不只是编写单元测试的原因,也是为什么有一个普遍的假设,你试图做的不只是假的!
35 Derek Elkins 07/25/2017
@jonrsharpe通过这个逻辑,我永远不会写无关紧要的实现。 例如在RubberDuck的答案(仅使用单元测试)中的FizzBu​​zz示例中,第一个实现明显“只是虚构了它”。 我对这个问题的理解恰恰是在你认识不完整的代码和你真正相信能够实现这个要求的代码之间的这种二分法,即“真实代码”。 我的“大switch ”旨在成为“写出最低限度使测试绿色”的逻辑极限。 我认为OP的问题是:TDD中的哪个原则可以避免这种大switch
2 Luaan 07/25/2017
@GenericJon在我的经验中,这太过乐观:)其中之一就是那些喜欢盲目重复工作的人。 与“复杂的决策”相比,他们会因为一个巨大的转变陈述而感到高兴。 如果失去工作,他们或者需要一个能够通过技术调用他们的人(而且他们最好有充分的证据证明它实际上失去了公司的机会/金钱!),或者做得非常糟糕。 在接管了许多此类项目的维护工作后,我可以说,只要客户满意(并支付),很简单的代码就可以维持数十年。

Carl Raymond 07/24/2017.

简短的答案是“真实代码”是使测试通过的代码。 如果您可以通过真实代码以外的其他方式进行测试,请添加更多测试!

我同意很多关于TDD的教程都很简单。 这对他们有效。 对于计算3 + 8的方法来说,太简单的测试实际上没有其他选择,只能计算3 + 8并比较结果。 这使得它看起来像你只是复制代码,测试是毫无意义的,容易出错的额外工作。

当你擅长测试时,它会告诉你如何构建应用程序,以及如何编写代码。 如果您在进行明智的,有用的测试时遇到困难,您应该重新考虑一下您的设计。 一个设计良好的系统很容易测试 - 这意味着明智的测试很容易考虑并且实施。

当你首先编写你的测试,看他们失败,然后编写使他们通过的代码,这是一个纪律,以确保你所有的代码都有相应的测试。 当我编码时,我不会狂妄地遵循这个规则; 通常我会在事后写测试。 但先做测试有助于保持诚实。 有了一些经验,即使你不是先写测试,你也会注意到当你将自己编码到一个角落时。

4 comments
6 Steve Jessop 07/26/2017
就我个人而言,我写的测试将是assertEqual(plus(3,8), 11) ,而不是assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) 。 对于更复杂的情况, other than在测试中动态计算正确的结果并检查相等性other than ,您总是寻找一种证明结果正确的方法。
Steve Jessop 07/26/2017
所以对于这个例子的一个非常愚蠢的做法,你可能会证明plus(3,8)已经返回了正确的结果,从中减去3,从中减去8,并将结果与​​0进行比较。这很明显相当于assertEqual(plus(3,8), 3+8) ,这有点荒谬,但是如果被测代码构建的是比一个整数更复杂的东西,那么经常会得到结果并检查每个部分的正确性正确的做法。 或者,类似于for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
...因为这避免了很大的恐惧,因此在编写测试时我们会在实时代码中对“如何添加10”这个主题犯同样的错误。 因此,测试小心避免编写任何代码,在测试中plus()可以将10添加到任何事物上。 当然,我们仍然依赖程序员验证的初始循环值。
3 Warbo 07/28/2017
只是想指出,即使你是在事后编写测试,看他们失败仍然是一个好主意。 找到一些似乎对你正在工作的任何东西都很关键的代码部分,稍微修改一下(例如用+替换+,或者其他),运行测试并观察它们失败,撤消更改并观察它们通过。 很多时候,我做了这个测试并没有真正失败,这使得它比无用的更糟糕:它不仅没有测试任何东西,它给了我一些虚假的信心,那些东西正在被测试!

Victor Cejudo 07/25/2017.

有时TDD的一些例子可能会引起误解。 正如其他人之前指出的,您编写的用于测试通过的代码是真实的代码。

但不要认为真正的代码看起来像魔术 - 这是错误的。 你需要更好地理解你想要达到的目标,然后你需要相应地选择测试,从最简单的案例和角落案例开始。

例如,如果您需要编写一个词法分析器,您首先使用空字符串,然后使用一堆空格,然后是一个数字,然后用空格包围的数字,然后是错误的数字等等。这些小的转换会导致您正确的算法,但是你不能从最简单的情况跳到一个非常复杂的情况下选择愚蠢到完成真正的代码。

鲍勃马丁在这里完美地解释它。


CandiedOrange 07/25/2017.

重构部分在你累了并想回家时清理干净。

当您即将添加一项功能时,重构部分就是您在下一次测试之前更改的内容。 您重构代码以为新功能腾出空间。 当你know这个新功能将会是什么时,你可以这样做。 不是当你只是想象它。

在创建GreetMom类之前(添加测试之后)添加将打印“Hi Mom”的功能之前,这可以像将GreetImpl重命名为GreetWorld一样简单。


graeme 07/27/2017.

但真正的代码将出现在TDD阶段的重构阶段。 即应该成为最终版本的一部分的代码。

每次进行更改时都应该运行测试。

TDD生命周期的座右铭是: RED GREEN REFACTOR

RED :写测试

GREEN :诚实地尝试获得尽可能快地通过测试的功能性代码:重复的代码,含糊不清的命名变量,最高等级的黑客等等。

REFACTOR :清理代码,正确命名变量。 干起码

5 comments
5 mcottle 07/25/2017
我知道你对“绿色”阶段的看法,但这意味着为了使测试通过可能是合适的。 根据我的经验,“绿色”应该是一个诚实的尝试,以使工作代码符合要求,但它可能并不完美,但应该像开发人员第一遍管理一样完整并“可以交付”。 在一段时间后,重构可能是最好的,在你进行了更多的开发之后,第一遍的问题会变得更加明显,DRY的机会也会出现。
graeme 07/25/2017
@mcottle我认为这些都是同一个任务的一部分。 完成它,然后清理它。 进一步的重构应该随着时间的推移而发生,作为其他任务的一部分。
1 Bryan Boettcher 07/25/2017
@mcottle:你可能会惊讶地发现,一个只读存储库的多少实现可以在代码库中被硬编码。 :)
6 Kaz 07/25/2017
为什么我会写垃圾代码并将其清理干净?当我可以用我可以输入的几乎一样快的速度写出漂亮的生产质量代码时? :)
1 Kaz 07/27/2017
@TimothyTruckle如果需要50分钟才能找到最简单可能的更改,但只有5分钟才能找到第二个最简单的可能更改? 我们是否第二简单或继续搜索最简单?

Timothy Truckle 07/27/2017.

你什么时候在TDD中编写“真实”的代码?

red阶段是您write代码的地方。

refactoring阶段,主要目标是delete代码。

red阶段,您可以as quick as possibleat any cost做任何事情来使测试通过。 你完全无视你曾听过的好的编码实践或设计模式。 让测试绿色是最重要的。

refactoring阶段,你清理你刚刚制造的混乱。 现在,您首先看看您刚才所做的更改是“ 转换优先级”列表中最重要的一种,如果存在任何代码重复,则可以通过应用设计模式将其删除。

最后,通过重命名标识符并将magic numbers和/或文字字符串提取为常量来提高可读性。


它不是红色重构,而是红绿色重构。 - Rob Kinyon

感谢您指出这一点。

所以这是您写真real codegreen阶段

red阶段,您编写executable specification ...

2 comments
Rob Kinyon 07/27/2017
它不是红色重构,而是红绿色重构。 “红色”是你将你的测试套件从绿色(所有测试通过)变为红色(一次测试失败)。 “绿色”就是你将你的测试套件从红色(一个测试失败)转换为绿色(所有测试都通过)的地方。 “重构”就是在保持所有测试通过的情况下获取代码并使其变得漂亮的地方。
Timothy Truckle 07/27/2017
@RobKinyon谢谢,更新了答案。

Robert Andrzejuk 07/27/2017.

你一直在写真Real Code

在每一步中,您都在编写代码以满足您的代码将为您的代码的未来呼叫者(可能是您或未...)满足的条件。

你认为你并没有编写有用的( real )代码,因为在那一刻你可能会重构它。

代码重构是重构现有计算机代码的过程 - 改变代理 - 而不改变其外部行为。

这意味着即使您正在更改代码,代码满足的条件也不会改变。 并且您为验证您的代码而执行的检查( tests )已经存在,以验证您的修改是否改变了任何内容。 所以你写的整个时间代码就在那里,只是以不同的方式。

另一个原因你可能认为这不是真正的代码,因为你正在做一些示例,其中最终的程序已经被你忽视了。 这是非常好的,因为它表明你有关于你正在编程的domain知识。
但很多时候程序员都处于一个newdomain ,对他们来说是unknown 。 他们不知道最终的结果是什么,TDD是一种逐步编写程序的technique ,记录我们关于这个系统应该如何工作的knowledge ,并验证我们的代码是如何工作的。

当我读TDD的书(*)时,对我而言,最突出的特点是:TODO列表。 它向我表明,TDD也是帮助开发人员一次专注于一件事的技术。 所以这也是对你的问题的回答aboout How much Real code to write ? 我会说足够的代码一次集中处理一件事情。

(*)Kent Beck编写的“Test Driven Development:By Example”

1 comments
2 Robert Andrzejuk 07/27/2017
Kent Beck的“Test Driven Development:By Example”

Zenilogix 07/31/2017.

您不会编写代码来使测试失败。

你编写测试来定义应该是什么样的成功,最初应该失败,因为你还没有写出可以通过的代码。

关于编写最初失败的测试的关键是做两件事:

  1. 涵盖所有案例 - 所有名义案例,所有边缘案例等
  2. 验证您的测试。 如果你只看到他们通过,你怎么能确定他们会在发生故障时可靠地报告失败?

红绿重构背后的一点是,首先编写正确的测试让您有信心知道您为通过测试所写的代码是正确的,并且可以让您重新确信测试会尽快通知您有些事情会中断,所以你可以立即回去修复它。

根据我自己的经验(C#/ .NET),纯粹的测试优先是一种难以达到的理想,因为您无法编译对尚不存在的方法的调用。 因此,“测试第一”实际上是先编写接口和存根实现,然后针对存根编写测试(最初将失败),直到存根完好无损。 我从来没有写过“失败的代码”,只是从存根中构建出来的。


Zan Lynx 07/27/2017.

我认为你可能会在单元测试和集成测试之间感到困惑。 我相信也可能有验收测试,但这取决于你的过程。

一旦你测试了所有的小“单元”,然后你测试它们全部组装,或“集成”。 这通常是整个程序或图书馆。

在我编写集成的代码中,测试了一个包含各种测试程序的库,它们读取数据并将其提供给库,然后检查结果。 然后我用线程来做。 然后我用中间的线程和fork()来完成它。 然后我运行它并在2秒后杀死-9,然后启动它并检查其恢复模式。 我模糊它。 我以各种方式对其进行折磨。

所有这些都是测试,但我没有一个漂亮的红色/绿色显示结果。 它要么成功,要么挖掘几千行错误代码来找出原因。

这就是测试“真实代码”的地方。

我只是想到了这一点,但也许你不知道什么时候你应该写单元测试。 当您的测试执行您指定的所有操作时,您已经完成了单元测试。 有时候,在所有的错误处理和边缘情况下,你都可能会失去这些信息,所以你可能想做一个很好的快速路径测试测试组,直接通过规范。

1 comments
Peter Mortensen 07/27/2017
(它是所有格,它是=“它是”或“它有”。例如,参见How to Use Its and It's 。)

user3791372 07/27/2017.

在回答问题的标题时:“你什么时候在TDD中编写”真实“代码?”,答案是:“几乎没有”或“非常缓慢”。

你听起来像个学生,所以我会像给学生建议一样回答。

你将学习大量的编码“理论”和“技术”。 他们非常适合在高价学生课程上花费时间,但对你来说没有多大好处,你无法在一半的时间里读一本书。

编码员的工作仅仅是为了生成代码。 代码工作得很好。 这就是为什么编码人员在你的想法,纸面上,合适的应用程序等中计划代码的原因,并且你打算在编码之前通过逻辑和横向思考预先解决可能的漏洞/漏洞。

但是你需要知道如何打破你的应用程序才能设计出体面的代码。 例如,如果您不了解Little Bobby Table (xkcd 327),那么您在使用数据库之前可能不会清理您的输入,因此您无法围绕该概念保护数据。

TDD只是一种工作流程,旨在通过在编写应用程序之前创建可能出错的测试来最大限度地减少代码中的错误,因为编码可能会成倍地增加困难,导入的代码越多,并且您忘记了曾经想到的错误。 一旦你认为你已经完成了你的应用程序,你就可以运行测试和繁荣,希望你的测试能够发现错误。

TDD并不是像一些人认为的那样写一个测试,用最少的代码传递,编写另一个测试,用最少的代码传递,等等。相反,它是一种帮助你自信地编写代码的方法。 这种连续重构代码的理想是非常愚蠢的,但它在学生中是一个很好的概念,因为当他们添加一个新特性并且他们仍然在学习如何编码时,它们会让他们感觉很棒。

请不要掉下这个陷阱,看看你的编码角色是什么 - 编码员的工作仅仅是为了编写代码。 代码工作得很好。 现在,请记住,您将作为专业编码人员,并且您的客户不会在乎是否编写了100,000个断言或0。他们只是希望代码有效。 事实上,真的很好。

5 comments
3 johnny 07/25/2017
我甚至不接近一个学生,但我确实阅读并尝试应用好的技术并且很专业。 所以从这个意义上说,我是一个“学生”。 我只是问非常基本的问题,因为这就是我的方式。 我很想知道我为什么要做我正在做的事情。 事件的核心。 如果我不明白,我不喜欢它并开始提问。 我需要知道为什么,如果我要使用它。 TDD在某些方面看起来很直观,比如知道需要创建和思考的东西,但实现很难理解。 我想我现在有更好的把握。
4 Sean Burton 07/27/2017
这些是TDD的规则。 不管你想要什么,你都可以自由地编写代码,但如果你不遵循这三条规则,你就没有在做TDD。
2 user3791372 07/27/2017
一个人的“规则”? TDD是一种帮助你编码的建议,而不是一种宗教。 很遗憾,看到很多人坚持这样一个想法。 即使TDD的起源也是有争议的。
2 Alex 07/28/2017
@ user3791372 TDD是一个非常严格和明确定义的过程。 即使很多人认为这只是意味着“在编程时做一些测试”,事实并非如此。 让我们试着不要混淆这里的术语,这个问题是关于TDD的过程,而不是一般的测试。

Related questions

Hot questions

Language

Popular Tags