- 浏览: 184255 次
- 性别:
- 来自: 深圳
最新评论
-
mengfei86:
你们讨论的时候我刚上大学,。。。。、、现在都过去好多年了,。 ...
J2EE项目异常处理 -
di1984HIT:
文章不错,学习了
Ibatis读写CLOB数据 -
wulixiaodao:
main{
metodA();
}
详解spring事务属性 -
wulixiaodao:
Main{
Connection con=null;
...
详解spring事务属性 -
tao_gun:
感谢,有点懂了
详解spring事务属性
程序员为什么不写单元测试
袁光东
笔记曾经做过一次“程序员在项目开发中编写单元测试的情况”的调查。调查结果:
1. 严格的在项目中执行TDD 几乎没有
2. 为大部份业务方法编写单元测试,并保证方法测试通过。 占16.6%
3. 偶尔编写单元测试,一般情况下不写。 占58.3%
4. 为了应付项目检查而写单元测试,但并不保证方法是否测试通过。 占8.3%
5. 从来不编写单元测试。占16.6%
因为调查具有一定的局限性或片面性,调查结果并不十分精确。也基本能够反映国内程序员编写单元测试的状况。很少有程序员能够比较认真的去编写单元测试。那么到底又是什么原因呢?根据笔者参与的多个讨论,主要有下面几种原因使程序员不编写单元测试。
1. 为了完成编码任务,没有足够的时间编写单元测试。编写单元测试会导致不 能按时完成编码任务,推迟项目进度。
2. 单元测试的价值不高,完全是浪费时间。
3. 业务逻辑比较简单,不值得编写单元测试。
4. 不知道怎么编写单元测试。
5. 项目没有要求,所以不编写
6. 在项目的前期还是尽量去编写单元测试,但是越到项目的后期,就越失控。
测试常常是程序员十分厌倦的一个项目活动。测试能够为我们带来什么?了解这些非常的重要。测试不可能保证一个程序是完全正确的,但是测试却可以增强我们对程序的信心,测试可以让我们相信程序做了我们期望它做的事情。测试能够使我们尽量早的发现程序的bug.
一个bug被隐藏的时间的越长,修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据。指出:最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。
在这里,我们需要讨论的重点是单元测试。单元测试是一个方法层级上的测试,单元测试也是最细粒度的测试。用于测试一个类的每一个方法都已经满足了方法的功能要求。
在现代软件开发过程中,不管是xp还是rup都是十分重视单元测试。已经把单元测试作为贯穿整个开发周期的一项重要的开发活动。特别是在现代软件开发过程中,有经常集成和渐近提交的方法论。总结出了非常好的单元测试理论和实践:
在编写代码之前先编写单元测试,即测试先行
单元测试是代码的一部份,所有的代码必须有单元测试,并使测试通过。(像在Spring这些优秀的开源项目中在这方面做出了非常好的例子)
在修改代码之前先修改单元测试,并使它测试通过。
在编写代码之前先编写单元测试,会带来非常多的好处:
在编写代码之前先编写单元测试,并不是编写代码之前需要一次性为所有的类都事先编写单元测试。这需要有一个粒度的把握。最大的粒度应该控制在一个类级别上,最合适的粒度是控制在一个方法级别上。先为某一个方法编写测试代码,然后再为该方法编写实现代码,直到其测试通过后再为另一个方法编写测试代码,如此循环。单元测试在这里已经是一个契约规范了,它规范了方法应该做什么,实现什么。测试代码远远要比难以阅读和不会及时更新的需求文档更有价值。
测试先行,鼓励对需求的理解。如果没有理解需求,你是不可能写出测试代码的,当然你也不可能写出好的实现代码。
测试代码与其它文档相比会更有价值。当需求发生改变,实现代码也相应改变。而往往需求文档,设计文档得不到及时更新。测试代码相比那些过期的文档更具有价值。
测试先行可以编写出最大覆盖率的测试代码。如果在方法的实现代码编写完后再编写测试代码,这时开发人员总是编写一个正确路径的测试代码。它已经很难全面的去分析其它分支逻辑。
如果我们采用测试先行,那么就自动的完成了为所有的类都编写测试这个实践原则。为所有的类都编写测试会将为你带来非常多的好处:
我们可以很好的使用自动化测试来测试所有的类,特别是采用日构建的系统。
可以让我们放心的为类或方法添加新的功能。我们可以很容易的修改测试代码并验证修改后的代码是有用的代码。
可以让我们放心的对代码进行重构和进行设计优化。重构和设计优化通常会关联到多个类及多个方法。如果我们为所有的类都编写了测试,我们就可以在重构代码后很轻松的进行测试我们的修改是否正确。
为所有的类编写测试,可以让我们很容易的修改bug。当接到一个bug报告后,我们总是先修改测试代码,然后修改实现代码,使测试成功。这样不会因为修改一个问题而造成新问题的产生。
良好的单元测试策略给我们增强了对程序的信心,减少了bug的产生及bug的潜伏期。降低修改bug的代价。单元测试不会是项目开发周期的某一个生命周期,它贯穿于项目的整个生命周期,是一个非常重要的日常开发活动。
我们已经知道了单元测试是多么重要的。为什么程序员仍然不编写单元测试呢?为什么程序员总是有理由拒绝编写单元测试呢?
一、编写单元测试,增加了工作负担,会延缓项目进度?
这是笔者在多次讨论和调查中程序员拒绝编写单元测试的最多理由。“为了完成编码任务,没有足够的时间编写单元测试。编写单元测试会导致不能按时完成编码任务,推迟项目进度”。事实上真的是这样的吗?软件有着其特殊的生命周期,软件开发也具有特殊性。
首先,我们需要提供给用户的至少是一个能运行的产品。绝对不能是一堆不能运行的和充满了异味的哑代码。只有能够运行的,满足客户需求的代码才是真正有用的代码。这时代码就变成产品了。
很多程序员只关注编写代码的完成时间,而乎略了调试代码,集成及修改和维护时间。
很多程序员只关注编写代码的完成时间,而乎略了调试代码,集成及修改和维护时间。
如果没有单元测试,开发活动会是这样的情景。
以一个web应用开发为例:业务代码编写完成->打包->发布到服务器->进行功能测试->发现问题->修改代码->再打包……如此循环。
任何一个web程序员对于这种开发情景都不会感到陌生。往往不断的打包,发布,功能测试的时间是代码编写的10倍以上。通过集成系统来发现程序的bug,我们往往很难一下子准确的定位bug产生的地方。应用服务器提供的错误信息对于我们来说是非常有限的。
如果为每一个类都编写单元测试并让每一个方法测试通过,又会是怎么样的开发情景呢?
编写测试代码->编写业务代码->运行测试方法->修改代码让测试通过->所有的类都通过测试->打包->发布到服务器->进行功能测试->发现bug->修改测试代码->修改业务代码->测试通过->再打包…如此循环。
从上面的过程显而易见,我们需要花费更多的编码时间。因为需要为每一个业务类编写测试代码。但是它并不会导致我们总体需要花费更多的时间。我们只是可以非常轻松的在ide环境中运行测试方法。在代码尚未打包发布之前我们就已经确保了业务代码的正确性。当我们把所有通过测试的代码集成到应用服务器后,出现错误的机率要少得多。当集成测试后发现bug时,我们也总是先修改测试类。保证在集成之前所有的类都经过测试通过。这样功能测试的时间就成数量级的减少,所以总的花费时间要比没有单元测试要少得多。
另外,如果没有单元测试,会经常出现一些低级的错误,如拼写错误,空指针异常等。就因为一个小小的拼写错误而需要重新打包,发布一次。如果有单元测试,就可以避免这些低级的错误。
如果没有单元测试,把代码集成到应用服务器后再发现错误时,我们往往更多的是凭借自己的经验来判断问题出在哪里。对于没有经验的程序员来说只能是撞运气了。这就像是瞎子走路一样,两眼一把黑。如果每个类都有单元测试,就无需要这么痛苦了。
这使得我回想起当年做网络系统。当时的局域网络都是采用环状网络,还没有现在的交换机来组星形网络。环状网络的传输网络采用同轴细缆线,网络中的所有节点都在一条主干线上,网络的两端都会加上一个电阻来形成一个环。
环状网络的最大的缺点就是当任意一个节点有固障时,整个网络都不能连通。维护这种网络是非常麻烦的。通常采用得比较多的方法就是“切香肠”法。把最后一个电阻取下来,接到第二台电脑的网络节点的末端,检查两条线是否能连通。连通后再把电阻取下来到第三台电脑的网络节点的末端,连上第三台电脑。这样来依次检查整个网络的线路。
后来发展了星形网络,也是现在局域网普遍采用的。有一台交换机,每一台电脑连接到交换机,任意一个节点网络故障不会影响到其它节点,检查起来就非常方便了。没有单元测试的代码就像是环状网络,而有测试的代码就像星形网络。
其次,有可能我们第一次编写的代码是没有问题的,但是到后来需求改变而修改了其中某些类的代码,把它发布到了应用服务器去测试,所要修改的内容已经测试通过了。但是因为某些类的修改导致了其它类不能正常的工作。这种bug往往隐藏得非常深,因为只要不触动它,它就不会出现。可能会程序发布到生产环境之后才会被业务人员发现。如果每个类都有测试代码,我们在打包之前运行所有测试代码,就可以很容易的发现因为代码修改带来的连带性错误。
其三,在离bug产生越近,修正bug就越容易;在bug产生越远,修正bug的代价就越昂贵。假设我们去集成一个星期(甚至更长时间)前编写的代码,当发现问题时,我们已经忘掉了很多重要的实现细节,所以修改变得困难重重。
编写单元测试,并不会加重程序员的负担,反而提高了程序员对程序的信心,大大的减少了重复打包,发布,纠错误的时间。这些花费的时间远远要比编写单元测试花费的时间多几个数量级。编写单元测试,可以让你更容易和更放心的去修改代码,增加功能从而加快了项目的开发进度。
为什么我们总是要主观的去认为编写单元测试会延缓项目进度呢?与其痛苦的挣扎,还不如去尝试一下好的实践。
二、业务逻辑简单,不值得编写单元测试
程序员是聪明的,程序员也总是自认为是聪明的。认为一些业务逻辑比较简单的类不必要编写单元测试。我们必须承认,需求不断变化,我们也必须要有勇气去接受需求变化。编写单元测试的另一个目的就是拥抱变化,而不是拒绝变化。编写单元测试就是提高了我们对程序的信心。在敏捷软件开发中,代码为集体所有,项目组的任何一个人都可以去修改任何一个代码文件。每当我要去修改一个别人编写的代码时,我总是多么的希望有程序的单元测试代码,而往往都让我非常的失望。一般我都得花费很大的力气去猜想原作者的原始意图。也许你会说:“你可以去看需求文档啊!你不会去看注释吗?”。但实际情况是,当需求文档完成了它的使命后,开发人员就把它扔到了一边了,文档总是过期的。没有几个项目组能够使得需求,设计这些文档与最新实现代码保持一致。所以去看一个过期的文档是没有价值的。注释也同样,保持最新仍然是一个最大的问题,并且注释能够提供的信息是非常有限的。所以我最需要的就是看测试代码了。测试代码最能反映出方法最新的功能契约。由代码的编写者去写的单元测试要比由其它人去编写的单元测试要更完善,更准确。
很多问题恰恰就出在一些我们认为简单的代码中。除非是像一个JavaBean的getter和setter方法,因为这些方法可以通过IDE自动代码生成,没有必要为它编写测试。
在项目开发中,我们需要经常通过重构来优化代码及改进我们的设计,当我们对代码进行重构之后,怎么能够保证代码仍然是正确的?那就是运行所有被修改的代码的测试。如果测试通过,则说明我们的重构是正确。
我们不能回避代码的维护问题。代码维护包括修正bug和增加功能。维护工作可能会距离代码编写完成有很长一段时间。当需要修改一个bug而修改了代码,或增加一个新的功能而修改了代码时,又怎么能够保证修改后的代码仍然是正确的和没有隐患的呢?也许你会说,发布到应该服务器去测试就知道了。笔者曾经发生过因为维护而导致了更严重问题发生的情况。一个系统在生产环境正常运行很长时间了。某一天,业务人员要求修改某一个功能,笔者按业务的要求实现了要修改的功能,业务也测试了修改后的功能,然后发布到了生产环境。程序下发两个星期后,报了一个非常严重的生产问题上来,以前能够正常运行的功能突然有问题了,导致了大量的生产数据错误。这个问题是非常致命的,只能暂时停用系统。
最后我查明原因是,出错的模块与上次修改的代码有关联,上次修改时没有同时去修改现在出错的模块。要是我能够在修改代码后,运行所有的测试类,测试就肯定会报告不通过。也就不会把隐藏有这么严重错误的程序下发到生产环境去。
我们看看没有写单元测试是怎么进行集成的。如果某些结果与我们所期望的不一致时,我们可能会在程序中加上许多print语句,然后通过控制台来监视程序的运行过程。采用print语句并不能够保证我们的程序的正确性。最好的情况是,它只能保证一条正确的路径,不能保证其它的分支。另外当太多的print语句的信息在控制台上,也会让我们看不到想看到的信息,控制台的信息是有限的。在开发测试时,把调试信息打印在控制台还可以接受,但是在生产环境,如果还有调试信息出现在控制台,那是绝对不可以接受的。我们经常会忘记把调试的print语句及时的删除掉,从而影响程序的性能。最关键的是,print语句不能保证程序的正确性,也不能为你节省开发的时间。只会给你带来负面的影响。
三、不知道怎么编写单元测试
如果你相信单元测试的价值,那么去学习如何编写单元测试最终会让你获益的。
以java开发为例,junit这样的单元测试组件是非常易于学习和使用的。其它语言也有类似的单元测试组件。要相信这将是简单和能为你带来价值的。但是笔者见过许多程序员编写的单元测试完全没有起到它应有的作用。这也与不知道怎么编写单元测试有关。所以我们应该掌握一些编写单元测试的基本原则:
应该为什么编写测试:虽然我们说为所有的代类都编写单元测试,但是测试JavaBean的setter或getter方法无异于是自寻烦恼。编写这样的测试完全是浪费时间。而且还增加了维护的困难。
学会使用断言:断言就是让我们为方法设置一个期望值。当方法执行结果与期望值不一致时,测试组件就会报告测试不通过。我见过一些项目的单元测试不是使用断言,而是自己编写一个打印(println)工具类,可以详细的在控制台中打印出类的详细成员信息,及集合的详细信息。在单元测试中使用这个打印工具类来打印输出结果。这看起来好像非常不错。但是不应该使用这种方式来编写单元测试
使用打印工具类,需要程序员自已从控制台去观察程序的执行结果。当输出信息非常多时,控制台信息是无法向上翻屏的。所以不能够给我们提供更多的信息。所以这种方法也不能用于自动化测试。
使用打印工具类,造成了一种假像,测试报告我们的测试总是成功的!如果使用断言,当方法的执行结果与我们设置的期望值不一致时,则会详细的报告测试失败的情况。
使用打印工具来代替断言,造成测试的不充分,只会写出一个低测试覆盖率的测试。我们需要一个充分的测试。
最大化测试覆盖率:我们除了测试一个正确的路径外,我们还需要测试方法的每一个分支逻辑。需要编写尽可能多的测试程序逻辑的测试。写一个充分的测试。
避免重复的测试代码:测试类也是非常重要的,与应用代码一样。测试类包含的重复代码越多,测试类自身出现的错误也会越多。而我们需要做的编码工作也就越多。
不要依赖于测试方法的执行顺序:使用Junit来进行单元测试,它不能保证测试方法按照我们的意图的顺序来执行。当一个测试类有多个测试方法时,我们不能让一个测试方法必须在某一个测试之后执行才能成功。Junit不能为我们做这样的保证,我们不能依赖于测试方法的执行顺序。
针对接口测试:我们有“针对接口编程”的oo设计原则。同样对于测试,我们也需要针对接口测试。也就是说在编写单元测试时,测试对象总是使用接口,而不是使用具体类。
四、项目没有要求,所以不编写
的确在很多项目中,团队并没有要求程序员为每一个类编写单元测试。反而会要求我们编写很多复杂的文档。作为程序员我们需要明白:程序员是编写单元测试的最大受益者。
这不是项目经理的事,也不是QA的事,而是程序员自身的事。因为单元测试是程序代码的一部份。单元测试是最好的,最有价值的文档,它应该与代码一起交付给客户。
单元测试代码不是官僚,死板的文档。它是生动的,是程序员最有用的文档。单元测试能够提高程序员对程序的信心,能够使用养成良好的设计原则:“针对接口编程,而不是具体类”。因为要进行单元测试,所以我们需要让类独立于其依赖对象(使用Mock或stub)进行测试。这就迫使我们养成了良好的编程习惯。
单元测试是改进我们设计的保证。做为一个优秀的程序员,是会经常优化代码和设计,所以经常的进行重构。一个优秀的程序员绝对不能容忍异味代码。而单元测试就是我们进行重构的信心保证。
单元测试是一个日常开发活动,它贯穿于项目的整个生命周期。做一个负责任的程序员总是为自己的代码的质量负责的。是否经常改进你的设计,是否让别人很轻松的使用和修改你的代码。
为所有类编写单元测试应该是一个程序员应具有的素质。项目有没有要求,不应当成为不编写单元测试的理由。
五、为什么越在项目的后期,单元测试就越难以进行下去?
在很多项目的初期,项目中的大部分程序员都能够自觉的去编写单元测试。随着项目的进展,任务的加重,离交付时间越来越近,不能按时完成项目的风险越来越大,单元测试就往往成为牺牲品了。项目经理因为进度的压力也不重视了,程序员也因为编码的压力和无人看官而不再为代码编写单元测试了。
笔者所有亲历的项目都着像这么糟糕的情况发生。越是在项目的后期,能坚持编写单元测试的程序就在整个项目组中不会超过15%。为了追赶进度,绝大多数程序员都把没有经过任何测试的代码提交到版本服务器,项目经理也不再追问,照单全收。这样做的结果就是在后期,集成花费的时间越来越多,几个技术骨干人员只得日夜加班进行系统集成。好不容易集成完了之后,下发给测试人员测试时,bug的报告成数量级的增长。程序员就日以继夜的修改bug.还有非常多的bug被隐藏更深,一直潜伏到生产环境去。项目中,越来越多的人对项目失去信心,每一个人都在抱怨,数不清的bug,修正了一个bug,更多的bug报告上来。
每天都在修改bug,但是每天又会报告上更多的bug。于是开始有人想逃离了,有人请假,也有人离职。当项目总算结束时,每一个的内心都清楚,项目太烂了,还有很多的错误还没被测试出来,赶快逃离这个项目组吧!一半的人病倒了,或对项目的维护失去了信心。
为什么会这样?有没有宣导测试的重要性呢?
在项目初期应该进行宣导单元测试的重要性。
有没有做过相关的培训工作?在项目启动时,需要进行一些相关的培训,教授团队成员最基本的编写单元测试的技巧。
有没有做过相应的风险防范?越是工作资历越深的程序员,就越会拒绝编写单元测试,他们总是有太多的理由来拒绝编写单元测试。这些顽固的老程序员往往负责着核心的代码的编写。我们知道20-80定律吧。80%的错误是发生在20%的代码之中的,往往最严重的错误就发生在那些老鸟们的代码中。有没有在事先就做好风险防范,说服他们编写单元测试。
有没有做好测试相关的基础工作。有没有针对不同类型的程序编写测试基类,让编写测试变成一项非常简单的工作。有一些代码是依赖于特定的环境,如EJB访问,JNDI访问,web应用程序依赖Servlet API等。测试这些程序是非常困难的。应该编写一些测试基类和测试stub,让这些程序可以脱离于特定环境就像普通程序一样进行单元测试。让普通程序员轻松的编写测试代码进行程序测试。
可以实行日构建和测试覆盖率检查,没有通过测试的代码绝不允许放到版本服务器。检查测试的覆盖率。
在现代软件开发过程中,测试不再作为一个独立的生命周期。单元测试成为与编写代码同步进行的开发活动。单元测试能够提高程序员对程序的信心,保证程序的质量,加快软件开发速度,使程序易于维护。不管测试先行还是测试后行,没有单元测试那是绝对不行的。
弱者为失败找理由,强者为成功找方法!今天你单元测试了吗?
评论
107 楼
mazelmiler
2007-07-21
业精于勤![color=green][/color][size=18][/size]
106 楼
netpcc
2007-07-21
说到文档,JavaDoc并不是什么好的代表吧。
绝大多数JavaDoc都没有任何参考价值。里面全是废话。
就连JDK的JavaDoc也不怎么样。大部分的所谓说明都无意义。
就文档而言我是推崇MSDN的。从原理到step by step到具体某一典型需求的实现方法。详细的参考文档。无数的代码片断,以及完整的Sample程序。
而且MSDN虽然是英语文档,但是充分考虑到非英语母语人群。里面的英语非常易懂。
总之就一个词:专业
不过能做到这个程度的确实是凤毛麟角。
至于说直接读源代码,一方面对程序员要求太高,另一方面效率太低。我读一个50K的Heritrix的源代码都花了2个月的时间。很多细节都没有读到。要是大家都这么干的话,成本就到天上去了。
而C++的源代码,比如STL,Boost,cryptopp等,只有真正的高手才能读懂他们的源代码了。这样的人一个公司里能有多少?
绝大多数JavaDoc都没有任何参考价值。里面全是废话。
就连JDK的JavaDoc也不怎么样。大部分的所谓说明都无意义。
就文档而言我是推崇MSDN的。从原理到step by step到具体某一典型需求的实现方法。详细的参考文档。无数的代码片断,以及完整的Sample程序。
而且MSDN虽然是英语文档,但是充分考虑到非英语母语人群。里面的英语非常易懂。
总之就一个词:专业
不过能做到这个程度的确实是凤毛麟角。
至于说直接读源代码,一方面对程序员要求太高,另一方面效率太低。我读一个50K的Heritrix的源代码都花了2个月的时间。很多细节都没有读到。要是大家都这么干的话,成本就到天上去了。
而C++的源代码,比如STL,Boost,cryptopp等,只有真正的高手才能读懂他们的源代码了。这样的人一个公司里能有多少?
105 楼
lakemove
2007-07-20
并不是主观的不不写, 其实写单元测试也不简单.
比如叫你去测controller, 测dao, 即使有这个想法, 实施起来也比较难, 没有象rails那样方便的环境, 还有学习曲线在内.
对于我这边来说, 多数情况是, 靠巧合编程, 成了, 就跑一边看新闻/泡论坛/聊QQ去了, 如果没有异常反馈, 我可能永远再也不会看到那段代码了.
比如叫你去测controller, 测dao, 即使有这个想法, 实施起来也比较难, 没有象rails那样方便的环境, 还有学习曲线在内.
对于我这边来说, 多数情况是, 靠巧合编程, 成了, 就跑一边看新闻/泡论坛/聊QQ去了, 如果没有异常反馈, 我可能永远再也不会看到那段代码了.
104 楼
kakaxili
2007-07-20
的确是素质问题,因为代码写完正常通过就行了,剩下的维护成本什么的
是公司和维护人员的事。
这样很不好!
是公司和维护人员的事。
这样很不好!
103 楼
sungaofei
2007-07-20
程序员的素质一个方面,管理是最主要的问题。如果公司本身没有对测试给与重视,要求单元测试并且定期检查,配合奖惩措施,仅仅靠程序员的素质是没办法保证有良好的单元测试
102 楼
yiding_he
2007-07-17
daquan198163 写道
javaTo 写道
代码当然是要看的,但对于一段代码的清晰度,有良好的注释还是很重要的
/** * 保存Excel报表到指定的路径 * @param beans 公用报表Bean * @param destFileName 报表生成路径 * @throws FileNotFoundException * @see ExpenseGrowRate */ protected void transformer(Map<String, Envelope> beans, String destFileName) throws FileNotFoundException { // ... }
你这基本上是个反面教材
如果方法名和变量名取的好一点,这些注释都可以去掉
我觉得变量名没什么问题。但是就算变量名取得好,javadoc 文档也是要写的,不能省。本例中缺少了对异常抛出条件的说明,这是不应该的。
101 楼
galaxystar
2007-07-17
code review更重要
100 楼
klyuan
2007-07-16
抛出异常的爱 写道
.........不写注释?
不知道你们都怎么样开发产品的。
不过我知道如果不写注释的话api是不会自动生成的。
每个接口都要写注释
工具类也都必须写注释否则eclipse
不会把工具的作用弹出来的。
死抱着先人的理论不干活的人们脑子是否锈了?
软件是写出来的不是吹出来的。
自己在自己的项目中用用两种方式后再来显摆。
我认为gigix可以写代码不写注释
但普通公司不行。
原因只有一个:英文不是我们的母语。
PS:以上为跑题贴
不知道楼主的文章什么时候写完
不知道你们都怎么样开发产品的。
不过我知道如果不写注释的话api是不会自动生成的。
每个接口都要写注释
工具类也都必须写注释否则eclipse
不会把工具的作用弹出来的。
死抱着先人的理论不干活的人们脑子是否锈了?
软件是写出来的不是吹出来的。
自己在自己的项目中用用两种方式后再来显摆。
我认为gigix可以写代码不写注释
但普通公司不行。
原因只有一个:英文不是我们的母语。
PS:以上为跑题贴
不知道楼主的文章什么时候写完
近期烦其它的事情!我会写的!
99 楼
gigix
2007-07-16
这也不过是个权衡的问题。给方法、变量、参数起一个好的名字会费力气,是吧,因为英文不是我们的母语。那么每当修改这些东西的时候你就跟着一道改注释吧。一件事情在两个地方描述吧。如果你认为这样的成本是可以接受的,谁也不能批评你什么。
98 楼
daquan198163
2007-07-16
javadoc依赖注释么?
英文不是我们的母语这算什么理由?
英文不是我们的母语这算什么理由?
97 楼
抛出异常的爱
2007-07-16
.........不写注释?
不知道你们都怎么样开发产品的。
不过我知道如果不写注释的话api是不会自动生成的。
每个接口都要写注释
工具类也都必须写注释否则eclipse
不会把工具的作用弹出来的。
死抱着先人的理论不干活的人们脑子是否锈了?
软件是写出来的不是吹出来的。
自己在自己的项目中用用两种方式后再来显摆。
我认为gigix可以写代码不写注释
但普通公司不行。
原因只有一个:英文不是我们的母语。
PS:以上为跑题贴
不知道楼主的文章什么时候写完
不知道你们都怎么样开发产品的。
不过我知道如果不写注释的话api是不会自动生成的。
每个接口都要写注释
工具类也都必须写注释否则eclipse
不会把工具的作用弹出来的。
死抱着先人的理论不干活的人们脑子是否锈了?
软件是写出来的不是吹出来的。
自己在自己的项目中用用两种方式后再来显摆。
我认为gigix可以写代码不写注释
但普通公司不行。
原因只有一个:英文不是我们的母语。
PS:以上为跑题贴
不知道楼主的文章什么时候写完
96 楼
Godlikeme
2007-07-12
方法命名,建议使用 动词 加上宾语补足语
95 楼
daquan198163
2007-07-12
javaTo 写道
如果你想用方法名来说明某个方法的意思,估计你的很多方法名称就要写成句子而不是单词了
句子倒不必,一个短语足矣.
这有什么不妥么?
比如把transformer改成storeExcelToPath(Map<String, Envelope> commonReportBeans, String destPath)
94 楼
javaTo
2007-07-12
daquan198163 写道
javaTo 写道
代码当然是要看的,但对于一段代码的清晰度,有良好的注释还是很重要的
/** * 保存Excel报表到指定的路径 * @param beans 公用报表Bean * @param destFileName 报表生成路径 * @throws FileNotFoundException * @see ExpenseGrowRate */ protected void transformer(Map<String, Envelope> beans, String destFileName) throws FileNotFoundException { // ... }
你这基本上是个反面教材
如果方法名和变量名取的好一点,这些注释都可以去掉
假如我不写注释,你一眼就可以看出他的功能吗?最起码你要把他的源码看一遍才知道他是做什么的吧,如果这个方法很复杂呢,你可能就要看N遍才能理解,而如果这样写我只要10秒钟就会使用这个方法了。两者之间你愿意选择哪种呢?
如果你想用方法名来说明某个方法的意思,估计你的很多方法名称就要写成句子而不是单词了
93 楼
daquan198163
2007-07-12
javaTo 写道
代码当然是要看的,但对于一段代码的清晰度,有良好的注释还是很重要的
/** * 保存Excel报表到指定的路径 * @param beans 公用报表Bean * @param destFileName 报表生成路径 * @throws FileNotFoundException * @see ExpenseGrowRate */ protected void transformer(Map<String, Envelope> beans, String destFileName) throws FileNotFoundException { // ... }
你这基本上是个反面教材
如果方法名和变量名取的好一点,这些注释都可以去掉
92 楼
javaTo
2007-07-12
RyanPoy 写道
sg552 写道
现在的JAVAEYE,真的到了高手归隐,菜鸟横冲直撞的时代了!
你说菜我也不争论什么。就想问问。你说的高手是什么境界?
难道会用junit,ant的人就是高手了?难道高手就一定要用junit和ant了?如果是这样,那么我想你定是一位高手了。
RyanPoy说的对,你说的高手是什么境界?在你的概念里什么是高手?什么又是菜鸟呢?
如果说仅是在论坛上说了一些自己的见解也会被人说成是菜鸟(这可能是个充满贬义的词汇),那么JE好像太可怕了,最起码现在还是个言论自由的时代!
“菜鸟”同志们注意了,你们以后就别发帖,也别回帖了,否则会被那些所谓的高手称作是菜鸟!(真不明白有些人是不是出生就是高手)
91 楼
javaTo
2007-07-12
代码当然是要看的,但对于一段代码的清晰度,有良好的注释还是很重要的
类似上面这样的一个方法(现在暂且不说有没有为该方法编写测试),假如现在这里包含很复杂的业务逻辑,并且还依赖了另外的N个方法,如果没有注释,你觉得你要看多久呢?
对于测试代码,再写很详细的注释是没有多大意义的,难道你还会调用你的测试代码去写程序?
我并没有说为测试代码写详细的注释,请看清楚
/** * 保存Excel报表到指定的路径 * @param beans 公用报表Bean * @param destFileName 报表生成路径 * @throws FileNotFoundException * @see ExpenseGrowRate */ protected void transformer(Map<String, Envelope> beans, String destFileName) throws FileNotFoundException { // ... }
类似上面这样的一个方法(现在暂且不说有没有为该方法编写测试),假如现在这里包含很复杂的业务逻辑,并且还依赖了另外的N个方法,如果没有注释,你觉得你要看多久呢?
chenk85 写道
你还可以看看开源项目中的测试代码,这里面是不用注释的代码
对于测试代码,再写很详细的注释是没有多大意义的,难道你还会调用你的测试代码去写程序?
javato 写道
公司的底层数据库操作是自己的框架,再加一层service,那个注释写的,跟没写一样,看起来真叫累,所以现在我写代码注释都打的非常详细。
我并没有说为测试代码写详细的注释,请看清楚
90 楼
RyanPoy
2007-07-12
sg552 写道
楼上两位强淫……
开发不用JUNIT, 不用ANT。
实在是太强了。佩服佩服啊!!
开发不用JUNIT, 不用ANT。
实在是太强了。佩服佩服啊!!
开发不用junit和ant的人,我想还是很多的。虽然用这些东西有它的好处。但是,没有人规定一定要这样。更何况,光用junit,ant一遍一遍的测试,编译,打包,部署,好像也不是一个系统能够成功的充分条件吧。如果说在大局观上的分析设计不合理,光用junit,ant又有什么用了。
sg552 写道
现在的JAVAEYE,真的到了高手归隐,菜鸟横冲直撞的时代了!
你说菜我也不争论什么。就想问问。你说的高手是什么境界?
难道会用junit,ant的人就是高手了?难道高手就一定要用junit和ant了?如果是这样,那么我想你定是一位高手了。
sg552 写道
虽然话不投机三句多,让你会用JUNIT,ANT将增加对其他人的竞争力,
这点我同意。但是好像我也没有否认过junit和ant,实在不明白,为什么我说我不用junit、ant,你就说不能开发了。这么说,那些不用junit和ant的人都不能开发了?
sg552 写道
不过还是谢谢两位不用JUNIT,ANT的“高手”对我回帖的关注!~
谈不上关注,只是就事论事。
89 楼
gigix
2007-07-12
javaTo 写道
照你这样说以后就没必要写注释了!
问你一句,你平时看别人的代码是先看注释还是先看代码?
注释是帮助别人更好的理解你的代码,可能你会觉得自己的代码一看就懂,很清晰(那可能是你自认为的),
但是让别人去理解你代码的时候,最好的方式不是让他把你的代码从头看到尾,而只要说明这段代码的用处即可。
比如我们去学习一个新框架的时候,最快的方式是看他的api,而不是源代码。
问你一句,你平时看别人的代码是先看注释还是先看代码?
注释是帮助别人更好的理解你的代码,可能你会觉得自己的代码一看就懂,很清晰(那可能是你自认为的),
但是让别人去理解你代码的时候,最好的方式不是让他把你的代码从头看到尾,而只要说明这段代码的用处即可。
比如我们去学习一个新框架的时候,最快的方式是看他的api,而不是源代码。
所以你还是看代码,而不是看注释。
so what's your point?
88 楼
chenk85
2007-07-12
javaTo 写道
yanhua 写道
javaTo 写道
稍微复杂点的逻辑可能会写个测试,说是测试,其实就是加个main方法,而且这个main方法最后还可能被无情的删除。
如果说测试是一种责任,那么我不得不说一下我们公司,注释啊,同志们!
公司的底层数据库操作是自己的框架,再加一层service,那个注释写的,跟没写一样,看起来真叫累,所以现在我写代码注释都打的非常详细。
如果说不写测试是不负责任,那么不写注释的同志们就该拉出去痛打一顿!
如果说测试是一种责任,那么我不得不说一下我们公司,注释啊,同志们!
公司的底层数据库操作是自己的框架,再加一层service,那个注释写的,跟没写一样,看起来真叫累,所以现在我写代码注释都打的非常详细。
如果说不写测试是不负责任,那么不写注释的同志们就该拉出去痛打一顿!
听说过“将代码转为注释”吗?太多的注释和没有注释一样糟糕,最好让你的代码清晰明了,自释其义--这需要不断的重构你的代码,而重构需要单元测试做保障,所以……
照你这样说以后就没必要写注释了!
问你一句,你平时看别人的代码是先看注释还是先看代码?
注释是帮助别人更好的理解你的代码,可能你会觉得自己的代码一看就懂,很清晰(那可能是你自认为的),
但是让别人去理解你代码的时候,最好的方式不是让他把你的代码从头看到尾,而只要说明这段代码的用处即可。
比如我们去学习一个新框架的时候,最快的方式是看他的api,而不是源代码。
学习一个新框架是先看他的架构,然后再看测试吧。基本现在的开源框架都是用TDD方法开发,用ant或者maven构建。测试代码就演示了api应该怎么用,难道说你单单看api文档就能知道怎么用这个框架来写文档?在看了测试代码后再有什么不够清楚就再看api文档和源码吧。
前面几页的讨论都讲了很多测试代码代表了什么了,如果是用TDD开发的。你还可以看看开源项目中的测试代码,这里面是不用注释的代码,如果给你看,你可能会觉得很惊奇,竟然开源项目(spring,hibernate)代码中有代码没有注释的。那为什么没有呢?因为代码已经毫无保留地告诉了你一切。
发表评论
-
一个特殊的异常处理
2008-12-13 23:59 1400一个特殊的异常处理 文:袁光东 一、业务需求说明 前段时间接 ... -
Spring JavaConfig开发指南(下)
2007-06-03 10:56 6556... -
Spring JavaConfig开发指南(上)
2007-06-03 10:25 7774Spring JavaConfig开发指南 作者:袁光东 1. ... -
ThreadLocal与synchronized
2007-05-22 17:49 27377ThreadLocal与synchronized Java良好 ... -
倒底该怎么写DAO的单元测试?
2007-05-17 16:17 14046public void testAddUserInfo() ... -
详解spring事务属性
2007-05-10 22:55 20432Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我 ... -
Ibatis读写CLOB数据
2007-04-25 16:43 22857Ibatis是一个高效,方便,易于学习的数据访问组件,在性能上 ... -
细说框架风云 JSF能否拯救WEB江湖
2007-04-24 18:08 2059细说框架风云 JSF能否拯救WEB江湖 Java ... -
模板方法模式实现探讨
2007-04-23 18:30 4416模板方法(Template Method) ... -
Spring架构设计-增强MultiActionController
2007-04-20 12:04 4837Spring架构设计-增强MultiActionControl ... -
让Spring架构减化事务配置
2007-04-19 12:20 4689让Spring架构减化事务配置 注:原创文章,本文曾发表于it ... -
J2EE项目异常处理
2007-04-18 12:19 16408J2EE项目异常处理 ...
相关推荐
程序员为什么不写单元测试?[1]单元测试工具赛门铁克误杀门事件在一片争议声中落下了帷幕,但是它身后隐蔽的问题还远未结束,诺顿误杀彰显测试价值的回归,同时也向广大的程序员们敲响了警钟,不做单元测试的程序员在...
程序员为什么不写单元测试?[2]单元测试工具一个bug被隐藏的时间越长,修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据指出:最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。在...
1.2. **预防回归错误**:当修改代码或添加新功能时,单元测试可以确保原有功能不受影响。 1.3. **文档作用**:测试用例可以作为代码功能的文档,帮助理解代码预期行为。 1.4. **支持重构**:在代码重构过程中,单元...
《程序员修炼三部曲之单元测试》是一本深入探讨软件开发中单元测试技术的重要书籍,尤其对于.NET、AJAX、C#、Java和VB.NET等技术领域的开发者来说,更是不可多得的参考资料。单元测试是软件开发过程中的一个重要环节...
Java程序员在进行软件开发时,单元测试是必不可少的一环,以确保代码的正确性和稳定性。Junit4作为Java领域中最常用的单元测试框架,是每个Java开发者必须掌握的技能之一。这篇压缩包文件中的"Junit4教程.doc"文档,...
一大早,一个年轻的程序员问大师:“我准备写一些单元测试用例。代码覆盖率应该达到多少为好?”大师回答道:“不要考虑代码覆盖率,只要写出一些好的测试用例即可。” 一大早,一个年轻的程序员问大师: “我准备...
在RTT(Real Time ThreadX)操作系统环境下,单元测试的重要性不减。虽然RTT是实时操作系统,但其内核组件和用户应用程序同样需要经过严格的测试。通过单元测试,开发者可以确保每个任务、中断服务例程或内核服务的...
单元测试通常由程序员自己执行,通过功能测试(黑盒测试)和代码测试(白盒测试)来验证模块的正确性。黑盒测试关注的是软件功能是否符合需求,而白盒测试则侧重于程序的内部逻辑是否正常运行。 黑盒测试是一种不...
这解释了为什么在软件发布前才进行测试会有那么多问题。大多数错误都未被发现,而且修正已发现错误的代价如此之大,以至于你必须有选择地进行处理,因为根本不可能全部修复。 使用PHPUnit进行测试与你曾经的做法...
JUNIT软件测试软件测试技术JUnit和单元测试入门简介软件测试1、几个相关的概念白盒测试——把测试对象看作一个打开的盒子,程序内部的逻辑结构和其他信息对测试人员是公开的。回归测试——软件或环境的修复或更正后...
微软的VS开发工具为我们提供了强大的单元测试环境,在VS当中可以直接对类库项目进行测试,极大的方便了程序员的自我纠错能力。除了官方的解决方案之外,还有一种非常好的免费开源的第三方测试工具,那就是NUnit。它...
Unit是一个Java语言的单元...Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。
《单元测试之道Java版:使用JUnit》PDF 下载
单元测试是一种软件开发的最佳实践,它鼓励程序员对每个函数、类或模块编写独立的测试用例,以便在修改代码或添加新功能时确保现有代码的行为不受影响。CppTest库提供了丰富的断言机制,使得测试编写简单而直观,...
【程序员写单元测试】: 程序员参与单元测试编写有助于他们更好地理解代码逻辑,提高代码质量。未来,随着对软件质量要求的提升,不编写单元测试的程序员可能会面临更大的挑战。 总结:单元测试是保证软件质量的...
python,基于python的unittest单元测试C语言代码,单元测试(unit ...可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。