2009-01-15 62 views
1

我注意到多年来,我倾向于编写一个充满代码的屏幕,然后测试以确保它完成应该的任务。在测试之前,您倾向于写多少代码?

一些这种技术的好处是

语法错误是新代码的结果, 所以你不必花太多时间去找原因。

它是便宜设立临时状况,让你if语句测试的的else子句 ,这样你就可以确保获得错误信息, 等的正确的,当他们是廉价的测试。

你如何倾向于代码?
你以这种方式得到什么好处?

编辑:就像我的大多数问题,我真的没有设置好上下文。我没有真正谈到单元测试级别的粒度。我指的是在执行时确保代码的本地代码完全符合我的意图。

回答

3

我倾向于编码,直到我有一些应该产生明确定义的可观察行为的东西。通常,这是一个公共API函数,有时是一个完整的类。这也鼓励我将问题分解成具有定义明确的可观察行为的小函数。我的大部分功能都比全屏小。如果一个函数太复杂而无法测试,那么它可能无法从其他角度设计。

14

我想说我总是写一个单元测试,然后我写出相应的代码来传递它,但我会说谎。

+0

为什么?纯语义。关键是决定代码应该先做些什么。无论你是正确的测试验证所需的行为或代码,以获得所需的行为第一次真的没有什么区别。 – 2009-01-16 12:18:37

+2

首先编写测试有助于设计,因为它会迫使您针对您正在构建的API编写代码。它可以完全改变你实现面向公众的API的方式。 – 2009-01-16 12:53:55

0

取决于项目的规模/规模。如果它是一个简短的程序(很容易编译和运行),我会在任何时候添加任何新功能的时候提前对它进行测试。这让我快速捕捉大多数错误。

在一个大型项目(公司规模)中,我会像这样孤立地测试我的作品,如果可以的话。否则,请关注这些日常构建的测试。

总之,尽可能频繁地测试,只要编译/运行时间不需要那么长时间就可以考虑占用办公刀剑!

0

我倾向于测试程序的每个功能。不是每个功能,而是一系列形成功能的功能。 这种方式的好处是,我没有太多的开销来测试每个功能,但是彼此之后进行测试。

0

我现在的项目应该是单元测试,然后是开发,大部分是,但是有时写测试的人和实现的人并不总是在同一页面上。

所以我喜欢有一个单元测试来检查所需方法的主要功能,然后让这个人执行代码来编写几个单元测试来检查代码的各个边。

1

这听起来很愚蠢,但我通常会在每次“处理任务”后测试我编写的代码。意思是,如果我打开一个文件,我测试例程。如果我连接到数据库并取出单个记录,我测试该例程。或者有时我写一个测试,只是为了看看它们是否工作,而只是练习课程的所有方法。

我不认为我使用硬性规则或快速规则,但大多数情况下,当我编写代码来执行任务时,我测试“验证”它做它应该做的事情。

1

正如我所愿。有时这意味着几百行,特别是如果我将一个大型系统添加到现有框架中,而应用程序甚至在没有其中一部分的情况下甚至无法运行。

我想我会遵循测试的原则,只要我可以。显然,这并不意味着编写循环的一半,但是当我完成循环时,我会在继续之前尝试一下。自上次测试以来发生的变化越少,就越容易找出导致错误情况的变化。 :)

1

我通常按照您的描述进行操作,但在测试之前我没有写完整页。我发现如果我编写一些代码然后编写测试,我通常必须重构代码以使其更易于测试。这看起来有点浪费,所以在编写单元测试之前我只写了几行代码。我发现我越来越接近严格遵守TDD。

1

当你没有提到在哪种语言环境中,你的代码...

正如我在Smalltalk工作,语法检查在编辑器中,而I型,每当我接受的方法,所以那不是问题。 (对于那些不知道Smalltalk的人来说:它不是基于文件的,而是面向对象的;这意味着你一次一个地向类对象添加方法对象,并且系统会按照原样编译“接受“编辑)。

对于小算法或者不需要大框架/设置的小方法,我添加一点评论来测试该方法,并且可以通过点击来执行。还有一个测试运行者提取所有这些并将其作为单元测试运行。 对于更大的内容,每隔几个方法就会更新一个TestCase类,并随时点击测试运行器按钮,从而阻止我进入红灯。

所以我会说,测试每10行左右完成一次。我承认,这样做需要一个高度反应和增量的IDE - 否则,它不能这么容易完成,我会在测试之前回复说一个大致的字母大小的页面代码。我不认为可编译性是“测试”,因此语法正确性不计算在内。

编辑:为了您的娱乐,这里是从集合类一个具体的例子:
对于那些谁也不知道Smalltalk中:
 引号字符串评论;
  +/-是创建测量值的操作员;
  /创建分数;
  {...}是数组创建;
最后的测试用例可以在编辑器中直接执行(所谓的doIt)。

sum 
    "sum up all elements. 
    This is implemented using a variant of the normal inject:into: pattern. 
    The reason for this is that it is not known whether we are dealing with number 
    (i.e. if 0 is a good initial value for the sum). 
    Consider a collection of measurement or physical objects, 0 would be the unitless 
    value and would not be appropriate to add with the unit-ed objects." 

    | sum sample | 

    sample := self anElement. 
    sum := self inject: sample into: [:accum :each | accum + each]. 
    ^sum - sample. 

    " 
    TestCase should: [ { } sum ] raise:Error. 
    TestCase should: [ '' sum ] raise:Error. 

    TestCase assert: ({ 1 } sum = 1). 
    TestCase assert: ({ 1. 2. 3. 4. } sum = 10). 
    TestCase assert: ((1 to:10) sum = 55). 
    TestCase assert: ('abc' asByteArray sum = 294). 

    TestCase assert: ({ 10 +/- 2. 
          20 +/- 4. 
         100 +/- 10 } sum = (130 +/- 16)). 

    TestCase assert: ({ (1/9). 
          (1/7). 
         } sum = (16/63)). 
    " 
1

我不使用TDD,但首先构建什么是有效的测试存根,即成为实际的应用程序。

例如,在WinForms应用程序中,我先构建按钮,然后测试它们。然后当我建立这个类时,我测试了这个类的方法被UI调用。然后,如果我要将实际的工作放到后台工作器中,那么我会在它内部没有任何东西的情况下构建它,然后测试Start/Progress/Complete处理器是否都会触发,并由类处理创建BGW。

然后我开始将功能放到方法中,因此已经有了一个经过测试的测试工具。为此我必须建立一个单独的线束,这是非常罕见的,因为每个增量都很小,并且在添加下一级复杂度之前进行测试。

好处是,我不必一次只持有太多的复杂性,没有它所依赖的基础已经得到充分测试的基础上添加的很少。

我从来没有发现单元测试是任何类型的问题 - 我真正想要的是在比这更高的级别进行自动测试。

0

我越老,我在运行/测试之前编写的代码越少。

部分原因是技术进步的结果:我开始在COBOL编码表上编写代码,当冲床女孩进来时每周两次转换成穿孔卡。我通常甚至不会尝试编译一个新程序,直到它基本完成并进行了桌面检查,通常是几千行和几周。现在,当我在玩我的游戏时,我在测试之前不写任何代码,我在编码之前编写测试。虽然我很虚弱,但并不总是知道如何编写测试,所以有时我会告诉自己,我只是在做这件事情而非常务实。然而,出乎意料的是,这样的结果往往是一个糟糕的主意:我作为TDD的结果编写的代码往往更容易测试,更容易修改,并且大多只比稍后进行测试的代码更好。

但这就是我,YMMV。

0

通常,只要我完成一个函数,我编译它,切换到REPL,并用一些临时组成的数据(也是边缘情况)来测试它。有时候(比我想要的更多)几个调试周期(编辑 - 编译 - 测试)是获得所需行为所必需的。当然,如果您可以将函数单独编译到提供REPL的正在运行的运行时中,则这种开发风格才是可行的,否则您将花费​​太多时间等待完整编译。我用SLIME使用SBCL。

2

就我个人而言,我发现在编写测试之前,我会倾向于编写明显的接口并拖动公用程序资源(无论是C#库,CSS,还是其他)。

我认为在热心和经验之间要平衡。

0

我尝试使我的代码第一次运行var单元测试。

有时我会先写测试,有时候我会先写方法/类。

我喜欢感觉良好我的自我,
所以我想给自己积极 反馈经常
所以我尝试 “证明”的新方法后不久,我的作品写了它

相关问题