为什么代码质量不受欢迎?
我喜欢我的代码是正确的,即正确格式化,可读,devise,testing,检查错误等。事实上,我很狂热。 ( 也许甚至比狂热…… )但根据我的经验,帮助代码质量的行为很难实现。 (代码质量指的是你每天生产的代码的质量,整个软件质量和开发过程等主题都要广泛得多,而不是这个问题的范围)。
代码质量似乎不受欢迎。 我的经验包括一些例子
-
可能每个Java开发人员都知道JUnit,几乎所有的语言都实现了xUnit框架,但是在我所知道的所有公司中,只有很less的适当的unit testing存在(如果有的话)。 我知道,由于技术上的限制或者按期限来编写unit testing并不总是可能的,但是在我看到的情况下,unit testing就是一个select。 如果开发者想为他/她的新代码编写一些testing,他/她可以这样做。 我的结论是,开发人员不想写testing。
-
静态代码分析通常在小型项目中进行,但并不真正用于执行编码约定或在企业项目中发现可能的错误。 通常甚至像潜在的空指针访问这样的编译器警告被忽略。
-
会议演讲者和杂志会谈论很多关于EJB3.1,OSGI,云和其他新技术,但几乎不涉及新的testing技术或工具,新的静态代码分析方法(如SAT求解),有助于保持更高质量的开发过程,遗留代码的一些讨厌的野兽被带到了testing中……(我没有参加很多会议,对于敏捷主题的会议可能看起来不同,因为unit testing和CI等都有很高的价值)。
那么为什么代码质量如此不受欢迎/被认为无聊?
编辑:
感谢您的回答。 他们中的大多数都涉及unit testing(并在相关问题中进行了讨论)。 但是还有很多其他的东西可以用来保持代码质量(见相关的问题 )。 即使你不能使用unit testing,也可以使用每日构build,向IDE或开发过程添加一些静态代码分析,尝试配对编程或强制执行关键代码的评论。
堆栈溢出部分的一个明显的答案是,它不是一个论坛。 这是一个问题和答案的数据库,这意味着重复的问题试图避免。
代码质量有多less个不同的问题你能想到? 这就是为什么没有关于“代码质量”的5万个问题。
除此之外,任何声称会议发言人不想谈论unit testing或代码质量的人都显然需要去参加更多的会议。
我也看到了关于持续集成的足够多的文章。
有没有写testing的常见借口,但他们只是借口。 如果你想为他/她的新代码写一些testing,那么这是可能的
真的吗? 即使你的老板说“我不会浪费你的时间在unit testing上”吗? 即使你在一个没有unit testing框架的embedded式平台上工作, 即使你在紧迫的最后期限之下工作,试图达到一些短期的目标,即使是以长期代码质量为代价的。
不可以。编写unit testing并不总是可行的。 它有许多共同的障碍。 这并不是说我们不应该试图写更多更好的testing。 只是有时候,我们没有机会。
就个人而言,我厌倦了“代码质量”的讨论,因为他们倾向于
- 过于关心假设的例子,而且往往是某些个人的心血结晶,他们实际上并没有考虑到对其他人的项目或者与他正在开发的不同大小的代码库有多大的相关性,
- 往往会变得过于情绪化,并且用太多的人性特征灌输我们的代码(举一个例子,想一想“代码味道”这个词)
- 被那些编写可怕的臃肿,过于复杂和冗长的代码的人所主导,这些代码有太多的抽象层,或者谁来判断代码是否可以重复使用,“看起来我可以把这块代码用在未来的项目中“,而不是更有意义的”我实际上已经能够拿走这块代码,并在不同的项目中重用它“。
我当然有兴趣编写高质量的代码。 我只是倾向于被通常谈论代码质量的人closures。
代码审查不是一门精确的科学。 使用的度量标准在某种程度上是有争议的。 在该页面的某处:“ 你无法控制你无法衡量的东西 ”
假设你有一个具有35个参数的5000行的巨大函数。 你可以unit testing多less你想要的,它可能做它到底应该做什么。 无论input是什么。 所以基于unit testing,这个function是“完美”的。 除了正确性之外,还有其他许多质量属性可能需要衡量 。 性能,可扩展性,可维护性,可用性等。 你有没有想过为什么软件维护是一个噩梦?
真正的软件项目质量控制不仅仅是简单地检查代码是否正确。 如果你检查软件开发的V模型 ,你会注意到编码只是整个方程的一小部分。
软件质量控制可以达到项目总成本的60%。 这是巨大的。 相反,人们宁愿削减到0%,回家认为他们做出了正确的select。 我认为为什么这么短的时间致力于软件质量的真正原因是因为软件质量不是很好理解。
- 有什么措施?
- 我们如何衡量它?
- 谁来衡量呢?
- 测量它会使我失去什么?
许多编码者血汗工厂没有意识到“现在的小虫子”和“后来更多的利润”之间的关系。 相反,他们所看到的只是“现在浪费时间”和“现在利润较less”。 即使显示漂亮的graphics显示相反。
而且,软件质量控制和软件工程作为一个整体是比较新的学科。 到目前为止,很多编程空间都被networking牛仔带走了。 你听过多less次“人”可以编程? 任何人都可以编写代码,但并不是每个人都可以成为程序员。
编辑*
我遇到了这篇文章(PDF) , 这个文章来自那个说“你无法控制你无法衡量的东西”的人。 基本上他是说控制一切并不像他想象的那么理想。 这不是一个确切的烹饪方法,你可以盲目地适用于像软件工程学校想让你想的所有项目。 他只是增加了另一个参数来控制“我想控制这个项目吗?是否需要?
- 懒惰/被认为无聊
- pipe理感觉这是没有必要的 – 无知的“做正确的”态度。
- “这个小项目不需要代码质量pipe理”变成了“现在,在这个大项目上实现代码质量pipe理的代价太高了”
我不同意,但它是沉闷的。 坚实的unit testingdevise使得创buildtesting变得轻而易举,运行起来更加有趣。
Calculating vector flow control - PASSED Assigning flux capacitor variance level - PASSED Rerouting superconductors for faster dialing sequence - PASSED Running Firefly hull checks - PASSED Unit tests complete. 4/4 PASSED.
就像任何事情一样,如果你做了太多的事情,它会变得无聊,但花费10或20分钟写一些随机testing一些复杂的function经过几个小时的编码不会吸引你的创意生活。
为什么代码质量如此不受欢迎?
因为我们的行业不专业。
但是,有些人关心代码质量。 你可以从软件工艺运动的讨论组中find一些志同道合的人。 但不幸的是,大多数软件业者并不了解代码质量的价值,或者甚至不知道什么构成了良好的代码。
我想答案与“为什么代码质量不受欢迎?”这个问题是一样的。
我相信最主要的原因是:
- 开发商的懒惰。 为什么要花时间准备unit testing,查看解决scheme,如果已经实施?
- pipe理不当。 为什么要求开发人员处理代码质量问题,如果有成千上万的新function请求,程序员可以简单地实现一些东西,而不是照顾已经实现的东西的质量。
简而言之:除非出现问题,否则这只是其他主要经验丰富的开发人员和工程师所赞赏的无形资产之一。 在这一点上,pipe理者和客户一片哗然,要求为什么没有正式的stream程。
较长的回答:这种短视的方法不限于软件开发。 美国汽车业(或者剩下的)可能就是最好的例子。
当项目以一次性或抛弃式的方式开始他们的生活时,正式的工程stream程也是很难certificate的。 当然,在项目完成之后很长一段时间,随着不同的业务部门开始依赖自己的业务stream程,它需要自己的生命(并且变得突出)。
此时需要devise新的解决scheme; 但没有使用这些工具和良好做法的做法,这些工具就没有用处了。 他们成为一个耗时的障碍。 在IT团队支持业务的公司中,我经常看到这种情况,在这种情况下,开发往往是反动的而不是主动的。
编辑:当然,这些坏习惯和其他许多问题是像Thought Works这样的咨询公司能够像他们一样继续发展的真正原因。
我还没有提到的一个重要因素是任何过程改进(unit testing,持续集成,代码评审等等)都需要在组织内拥有一个支持该技术的倡导者,在组织内具有适当的影响力并愿意做工作说服他人的价值。
例如,我已经看到了一个真正认真对待代码审查的工程组织。 那家公司有一个软件副总裁,他是一个真正的信徒,他会坐在代码审查,以确保他们得到正确的处理。 他们顺便提一下,我所在的任何一支球队的生产力和质量都是最好的。
另一个例子是当我在另一家公司实施unit testing解决scheme时。 起初,没有人使用它,尽pipepipe理坚持。 但是,我们中的一些人真正努力地谈论unit testing,并且为想要开始unit testing的任何人提供尽可能多的帮助。 最终,一旦开始看到unit testing的优点,一些最受尊敬的开发人员签名。 之后,我们的testing覆盖率大大提高。
我只是想到了另一个因素 – 有些工具需要花费大量的时间才能开始,而启动时间可能很难。 静态分析工具可能会非常糟糕 – 您运行该工具,并报告2000个“问题”,其中大部分是无害的。 一旦正确configuration了工具,假阳性问题就会大大减less,但是有人必须花时间去承担工具configuration。
可能每个Java开发人员都知道JUnit …
虽然我相信大多数或许多开发人员都听说过JUnit / nUnit /其他testing框架,但是很less有人知道如何使用这样的框架编写testing。 从这些方面来说,很less有人对如何使testing成为解决scheme的一部分有了很好的理解。
我已经知道至less7年的unit testing和unit testing框架。 我在5-6年前尝试过在一个小项目中使用它,但是在过去的几年里,我才学会了如何做到这一点。 (即find一种适合我和我的团队的方式…)
对我而言,其中一些是:
- find适合unit testing的工作stream程。
- 在我的IDE中集成unit testing,并具有运行/debuggingtesting的快捷方式。
- 学习如何testing什么。 (比如如何testinglogin或访问文件,如何从数据库中抽象出自己,如何模拟和使用模拟框架,学习提高可测性的技术和模式。
- 有一些testing比没有testing更好。
- 稍后发现错误时可以写更多的testing。 编写certificate错误的testing,然后修复错误。
- 你必须练习才能做到这一点。
所以直到find正确的方法 是的,这是沉闷的,没有奖励,很难做,耗时,等等。
编辑:在这篇博文中,我将深入讨论unit testing的一些原因。
代码质量不受欢迎? 让我反驳这个事实。
像Agile 2009这样的会议在持续集成,testing技术和工具方面进行了大量的介绍。 像Devoxx和Jazoon这样的技术大会也有这些议题的公平份额。 连续整合和testing( CITCON ,每年在三大洲进行3次)甚至还有一个整个会议。 事实上,我个人的感觉是,那些谈话是如此普遍,以至于他们正在对我完全无聊。
根据我作为顾问的经验,关于代码质量技术和工具的咨询实际上很容易销售(虽然不是很高的薪水)。
尽pipe如此,尽pipe我认为Code Quality是一个很受欢迎的话题,但我还是赞同这样一个事实:开发人员不会(通常)做好或者足够的testing。 我对这个事实有一个相当简单的解释。
本质上,这归结为这些技术仍然是相当新的(TDD是15岁,CI小于10),他们必须与1)pipe理者竞争,2)开发者的方法“迄今为止工作得不错” (不pipe什么意思)。 用Geoffrey Moore的话来说,现代的代码质量技术在采用曲线上还处于早期阶段。 整个行业采用它们需要时间。
不过,好消息是,我现在遇到了刚刚接受TDD教育并且对此感兴趣的大学新生。 这是最近的事态发展。 一旦有足够的这些产品上市,行业将不得不改变。
当你考虑工程谚语“好,快,廉:挑二”时,这很简单。 根据我的经验,98%的时间是快速而廉价的,而另一方面则必须受到损害。
这是痛苦的基本心理学。 当你跑步达到最后期限时,代码质量就是最后一个席位。 我们讨厌它,因为它沉闷无聊。
这让我想起了这个Monty Python的短剧:
“令人兴奋的是,不,没有,这是沉闷的,沉闷的,沉闷的,我的上帝是沉闷的,这是非常沉闷枯燥乏味,闷闷无聊,甚至每一个DULL。
我会说很多原因。
首先,如果应用程序/项目很小,或者没有真正重要的数据,那么编写testing所需的时间就可以用来编写实际的应用程序。
质量要求达到了需要进行unit testing的水平。
还有很多方法不容易testing的问题。 他们可能依赖于数据库中的数据或类似数据,这就造成了设置模型数据以供给方法的麻烦。 即使你设置了模型数据 – 你能确定数据库的行为是一样的吗?
unit testing在发现没有考虑到的问题方面也很薄弱。 也就是说,unit testing在模拟意想不到的时候是不好的。 如果您没有考虑停电时会发生什么情况,如果networking链路发送仍然是CRC正确的错误数据。 为此编写testing是徒劳的。
我都赞同代码检查,因为他们让程序员分享其他程序员的经验和代码风格。
“有没有写testing的常见借口,但他们只是借口。”
他们? 让八个程序员一起在一个房间里,问他们一个关于如何最好地保持代码质量的问题,并且根据他们的年龄,教育和偏好,你将得到九个不同的答案。 20世纪70年代计算机科学家们会对unit testing的概念感到嗤之以鼻。 我不确定他们会错的。
pipe理需要花费更多的时间来节省时间。 由于他们实际上不能测量“错误不固定”,他们通常更关心满足他们的最后期限和交付date,而不是项目的长期质量。
代码质量是主观的。 主观主题总是单调乏味的。
既然目标是简单地做出一些有用的东西,那么代码质量总是排在第二位。 这增加了时间和成本。 (我不是说它不应该被认为是一件好事。)
99%的时间,没有第三方的质量差的代码(除非你正在制作太空间或火车转换软件)。
- 它工作吗? =混凝土。
- 漂亮吗? 在旁观者的眼中。
阅读Fred Brooks的“神话人月”。 没有银弹。
unit testing需要额外的工作。 如果一个程序员看到他的产品“有效”(例如,没有unit testing),为什么要这样做? 特别是当它不像执行程序中的下一个function那么有趣时,等等。大多数人在涉及到它时往往懒惰,这不是一件好事。
代码质量是特定于上下文的,无论人们试图做多less努力,都很难一概而论。
这与理论和应用的区别很相似。
我也没有看到定期写unit testing。 之所以这样做,是因为在项目开始的时候代码变得过于广泛,所以每个人都放弃编写unit testing,直到一切都稳定下来。 之后,每个人都很高兴,不需要进行unit testing。 所以我们有一些testing作为历史留在那里,但是它们没有被使用,并且可能与当前的代码不兼容。
我个人认为编写大型项目的unit testing是不可行的,尽pipe我承认我没有尝试过,也没有和做过的人交谈过。 在业务逻辑中有这么多的规则,如果你只是稍微改变一些东西,你就无法知道哪些testing要更新,除了那些会崩溃的东西。 谁知道,旧的testing现在可能不能涵盖所有的可能性,回忆五年前写的东西需要时间。
另一个原因是缺乏时间。 当你有一个任务分配的地方写着“完成时间:O,5个人/天”时,你只有时间来实施它并进行浅层testing,而不是想到所有可能的情况和与其他项目部分的关系,必要的testing。 实际上可能需要0.5天的时间来完成一些事情,几个星期才能完成testing。 除非你特别给出了创buildtesting的命令,否则没有人会明白这会造成巨大的时间损失,从而导致大声喧哗的评论。 不,对于我们复杂的企业应用程序,我想不出在五分钟内完成任务的好testing覆盖率。 对大多数应用程序模块来说,这需要时间,可能还需要很深入的了解
所以,我看到他们的原因是时间的损失,这没有产生有用的function,维护/更新旧的testing,以反映新的业务规则的噩梦。 即使有人想,只有经验丰富的同事才能写出这些testing – 至less有一年深入参与项目,但真正需要两三个testing。 所以新的同事不pipe理适当的testing。 而且创造不好的testing是没有意义的。
在一些神秘的密码丛林中,如果在一些x年前写的神秘的密码丛林中发现了一些非常重要的随机“特征”,而没有任何线索发生了什么错误,为什么会出错并且完全没有任何想法,当它应该在几个小时内结束。 当这样做的时候,没有人会因为拖延而感到满意。
在那里 – 看到了。
代码质量的现代写作中强调的许多概念忽略了代码质量的主要指标:代码必须首先发挥function。 其他一切都只是为此目的的一种手段。
有些人觉得他们没有时间去学习软件工程领域的最新潮stream,而且他们已经可以编写高质量的代码。 我不是在判断他们的地方,但是在我看来,如果人们无法阅读,理解和改变代码,很难长时间使用你的代码。
缺乏“代码质量”不会导致用户,销售人员,架构师和开发人员的代价; 它减慢了下一次的迭代,但我可以想到几个成功的产品,似乎是由头发和泥土制成。
我发现unit testing让我更有效率,但是我看过很多格式不好,devise不佳的代码,它们通过了所有的testing(通常是多次修补过的很长的代码)。 通过考试,你会得到一个有价值的斯柯达,而不是布里斯托尔的工艺。 但是,如果您的“低代码质量”通过testing并始终如一地满足用户的要求,那么这就是一个有效的商业模式。
我的结论是,开发人员不想写testing。
我不确定。 部分原因是,整个软件的教育过程并不是由testing驱动的,而应该是 – 而不是要求上交练习,给学生unit testing。 在math问题中运行支票是正常的,为什么不用软件工程呢?
另一件事是unit testing需要单元。 一些开发人员发现模块化和封装难以做好。 一个好的技术领导者将创build一个模块化的架构来定位一个单元的范围,因此可以很容易地进行单独的testing。 许多系统没有优秀的架构师来促进可testing性,或者没有足够的重构来减less单元间的耦合。
由于固有的耦合,也很难testing分布式或GUI驱动的应用程序。 我只有一支队伍做得很好,那个testing部门和开发部门一样大。
静态代码分析通常在小型项目中进行,但并不真正用于执行编码约定或在企业项目中发现可能的错误。
我所看到的每一套没有被自动化的编码规则在逻辑上都是不一致的,有时甚至是不可用的 – 甚至有人声称在几个项目中“成功”地使用了这些规则。 非自动编码标准似乎是政治的,而不是技术文件。
通常甚至像潜在的空指针访问这样的编译器警告被忽略。
我从来没有在容忍编译器警告的商店工作。
我经常遇到的一种态度(但从来不是已经成为质量上瘾者的程序员)是编写unit testing只是迫使你编写更多的代码,而没有获得额外的function。 而且他们认为那个时候将更好的function添加到产品中,而不是仅仅创build“元代码”。
这种态度通常会随着unit testing越来越多地捕捉到越来越多的错误而变得越来越严重,而且这些错误在生产环境中很难find。
当程序员忘记或者天真的时候,很多事情就会产生,像他们的代码一样,在以后的日子里(或者他们自己几个月/年后)就不会被其他人看到。
另外,评论并不像实际写一段漂亮的代码那么“酷”。
另外有几个人提到过,大多数开发工程师都是可怕的testing人员。 他们没有专业知识或思维来有效地testing自己的代码。 这意味着unit testing对他们来说似乎不是很有价值 – 因为他们的所有代码总是通过unit testing,为什么还要写它们呢?
教育和指导可以帮助这一点,testing驱动的发展也是如此。 如果您首先编写testing,您至less主要考虑testing,而不是试图完成testing,所以您可以提交代码…
你被大学生或外包工作人员更新换代的可能性与你的代码的可读性成正比。
人们对代码的“好”意味着什么没有一个常识。 很多人会下降到“我跑了”甚至“我写了”的水平。
我们需要对某个好代码有一个共同的认识,以及它是否重要。 对于第一部分,我写了一些想法:
http://agileinaflash.blogspot.com/2010/02/seven-code-virtues.html
至于是否重要,已经涵盖了很多次。 如果你的代码活得很长,那么这个问题就相当重要了。 如果它真的不会出售或不会被部署,那显然没有。 如果不值得这样做,不值得做好。
但是,如果你不练习写出良性的代码,那么在重要的时候就不能这样做。 我认为人们做了差劲的工作,而且什么都不知道。
我认为代码质量过高。 我做的越多,对我来说意味着越less。 代码质量框架喜欢过于复杂的代码。 你永远不会看到像“这个代码太抽象,没有人会理解”这样的错误,但是例如PMD说我的class上有太多的方法。 所以我应该把这个类切成抽象的类/类(这是PMD不关心我们做什么的最好方法),或者根据function来切断类(最糟糕的方式,因为它可能仍然有太多的方法)。
静态分析非常酷,但它只是警告。 例如FindBugs在投射方面有问题,您应该使用instaceof
来使警告消失。 我不这样做只是为了使FindBugs快乐。
我觉得太复杂的代码不是当方法有500行代码,但是当方法使用500其他方法和许多抽象只是为了好玩。 我认为,代码质量大师应该真正的在寻找代码太复杂的时候,不要太在意小的事情(你可以用正确的工具真正快速地重构它们)。
我不喜欢代码覆盖的想法,因为它真的是无用的,使unit testing无聊。 我总是testing复杂function的代码,但只有代码。 我在一个100%的代码覆盖的地方工作,这是一个真正的噩梦改变任何事情。 因为当你改变任何东西的时候,你不得不担心被破坏(写得不好)的unit testing,你永远不知道如何处理它们,很多时候我们只是发表评论,并添加todo
来修复它们。
我认为unit testing有其自己的位置,例如,我在我的网页parsing器中做了大量的unit testing,因为我总是发现不同的错误或不支持的标记。 testing数据库程序真的很难,如果你也想testing数据库逻辑, DbUnit真的很痛苦。
我不知道。 你有没有看到声纳 ? 当然,这是特定于Maven ,但指出你的构build和繁荣,大量的指标。 这是一个将促使这些代码质量指标成为主stream的项目。
我认为代码质量或testing的真正问题在于,你必须投入大量的工作,而且你什么也得不到。 减less错误==减less工作? 不,总有事情要做。 减less错误==更多的钱? 不,你必须换工作才能获得更多的钱。 unit testing是英雄的 ,你只会对自己感觉更好。
我在pipe理鼓励unit testing的地方工作,但是我是唯一一个写testing的人(我想做得更好,这是我做这件事的唯一原因)。 我明白,对于其他人来说,写testing只是更多的工作,你没有得到任何回报 。 浏览网页听起来比编写testing要冷。
有人可能会打破你的testing,并说他不知道如何解决或注释掉(如果你使用maven)。
框架不适用于真正的Web应用程序集成testing(unit testing可能通过,但它可能无法在网页上工作),所以即使您编写testing,您仍然需要手动testing。
你可以使用像HtmlUnit这样的框架,但是使用它真的很痛苦。 selenium打破了网页上的每一个变化。 SQLtesting几乎是不可能的(你可以用DbUnit来完成 ,但是首先你必须为它提供testing数据,5个连接的testing数据是很多工作,而且没有简单的方法来生成它)。 我不知道你的web框架 ,但我们正在使用的一个真正喜欢静态方法 ,所以你真的不得不努力testing代码。