找回密码
 FreeOZ用户注册
楼主: DDD888
打印 上一主题 下一主题

[其他] 如果老板不同意我花时间写unit testing,该如何办啊?

[复制链接]
121#
 楼主| 发表于 24-12-2013 11:22:20 | 只看该作者

诚实的说,我现在非常忙,连两周圣诞节休假都要义务给老板写测试程序,不算工作啦
回复  

使用道具 举报

122#
发表于 24-12-2013 11:58:58 | 只看该作者
DDD888 发表于 24-12-2013 04:48
我感觉最完美的情况下,函数只有一行代码,阅读维护绝对舒服.绝对不能接受的是一个函数的代码超过一 ...

要写出足够清晰可读的代码,对功能块的划分,概括以及抽象绝对是重中之重。而这个工作的开始就是分函数。所以同意你这个观点。 不过一个函数一行代码稍微有点极端,我觉得只有在能够非常明显地增加代码表达力的时候才有必要为一行代码创建一个函数。
从05年开始,在我所带的团队里就有这么一条硬性规定,除非有充分的理由,否则不能写超过50行代码的函数。感觉效果不错。当函数的数量开始增加,自然就会思考进一步的功能划分,把大类拆分为小类,再然后会对类进一步进行职责划分,思考更加容易识别的名字。  要触发这一连串的良性连锁反应从函数入手是最容易的。

记得当年划分函数时往往从扇入扇出的角度入手;而如今划分函数则更多的从代码的表达力方面,扇入扇出完全不再成为考虑的依据。一个函数只要能增加代码的表达力,哪怕只有一次调用,也是值得的。
回复  

使用道具 举报

123#
发表于 24-12-2013 12:36:41 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 24-12-2013 12:38 编辑

Don't think of it in terms of line count. Line count is an arbitrary and unimportant metric. Think of it in terms of what the method logically does. The best rule would be:

A method should do one thing.
Or, to put it a better way:

A method should have only one reason to change.
(Still channeling Uncle Bob here, I've been hitting the Clean Code pretty hard lately.)

Combine this with other logical rules, such as:

A method should have only one level of abstraction.
A method should follow the Law Of Demeter.

from http://stackoverflow.com/questio ... methods-a-bad-thing
回复  

使用道具 举报

124#
 楼主| 发表于 24-12-2013 19:28:41 | 只看该作者
black_zerg 发表于 24-12-2013 12:36
Don't think of it in terms of line count. Line count is an arbitrary and unimportant metric. Think o ...

谢谢连接
回复  

使用道具 举报

125#
 楼主| 发表于 24-12-2013 19:44:12 | 只看该作者
另外我喜欢把每个函数单独放在一个cs文件里,用partial连入class里,这样一来读程序就更好读了
回复  

使用道具 举报

126#
发表于 24-12-2013 20:28:47 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 24-12-2013 21:20 编辑

我问你是否对js有兴趣是因为我闲着没事想做一个桌面风格的js框架,想法就是以后的所有桌面程序,可能都能用js写。
下面是一个概念的原型,你可以点点拽拽。
http://shenshowcase.appspot.com/static/demo/desktop.html
可惜找不到人一起来研究。

另外我建议看别的语言是因为在编程风格上可能会有些新感悟。我最近几年玩玩python,感觉很有意思,在思路上有蛮大启发。

我对自动测试的不以为然也应该和我感兴趣的方向有关。比如我做的地图控件 http://shenshowcase.appspot.com/static/map/demo/toolbar.html
我对每个功能都有一个html作为测试和showcase,但是我都是手工测的,你认为这个有自动测试的必要么,又是否值得这个工作量?  我这个地图控件现在一共有49个public类也就是49个文件,最后打成一个JS。每个类总有个三五个到十来个函数吧,如果都给拆吧拆吧,我起码会有两三百个文件,想想就晕,而且对我来说也不符合逻辑。

所以你上面的关于函数的心得把我震惊了,看来你会和woodheadz比较谈得来。感觉每人技术背景和经历不同,所以可能看法差很多,求同存异好了。
回复  

使用道具 举报

127#
 楼主| 发表于 25-12-2013 11:47:47 | 只看该作者
我发觉写unit test case要比写C#程序困难多了
回复  

使用道具 举报

128#
 楼主| 发表于 25-12-2013 11:49:42 | 只看该作者
black_zerg 发表于 24-12-2013 20:28
我问你是否对js有兴趣是因为我闲着没事想做一个桌面风格的js框架,想法就是以后的所有桌面程序,可能都能用 ...

我不觉得以后的所有桌面程序,可能都能用js写,写c#是享受啦,写js在ide,调试器方面都落后许多
回复  

使用道具 举报

129#
发表于 25-12-2013 12:17:19 来自手机 | 只看该作者
提示: 作者被禁止或删除, 无法发言
DDD888 发表于 25-12-2013 11:49
我不觉得以后的所有桌面程序,可能都能用js写,写c#是享受啦,写js在ide,调试器方面都落后许多

是么,我以前一直是java,一直想学c sharp,多指教
回复  

使用道具 举报

130#
 楼主| 发表于 25-12-2013 14:21:02 | 只看该作者
black_zerg 发表于 25-12-2013 12:17
是么,我以前一直是java,一直想学c sharp,多指教

太客气了,互相学习啦
回复  

使用道具 举报

131#
发表于 25-12-2013 23:36:02 | 只看该作者
black_zerg 发表于 24-12-2013 20:28
我问你是否对js有兴趣是因为我闲着没事想做一个桌面风格的js框架,想法就是以后的所有桌面程序,可能都能用 ...

从js的角度来讲,把大函数拆分成各自包含一定逻辑的小函数,可以把这些函数都放在一个文件里面,并不会影响你的文件的数目。还是49个文件。
再说,就算你真的有理由把各个小函数分开单独放一个文件,对于js来说,也不是问题。发布的时候总是要打包,再minify一下。到时又是变成一个文件了。
另外关于手工测还是自动测,这是你的个人项目,就看你个人的喜好了。
如果是打算开源的话,有test应该会更受容易欢迎一些。其他开发者,看到有test,能看到哪些方面被测到了,哪些方面没被测到,心里就有底。而不是仅凭你口头说已经手动测过了就相信了。
回复  

使用道具 举报

132#
发表于 26-12-2013 00:28:22 | 只看该作者
本帖最后由 caoglish 于 26-12-2013 00:29 编辑

现在有phantomjs,selenium, 所以图形界面也能测试。

css也都能进行抓图后对比测试。

在github上还有命令行的测试工具。

反正现在流行趋势就是想办法自动化测试,没有办法的也一定再想想办法去测试。

就算这个邻域过去没有自动测试方法,如果你能给想出来,那就是革命性的创作,更加值得一试了。

另外,有个预言 -- 凡是理论上能用javascript做出来的,最终都会用javascript来实现的。

javascript无论现在还是为了都是一个很重要的语言。javascript还真是一个歪打正着的语言,一直被看衰,从来没离开,
回复  

使用道具 举报

133#
发表于 26-12-2013 00:49:05 | 只看该作者
每段代码一定要用一个函数来命名,就算这段代码只用一次。在mian()中,或者开始文件中,只要有一个start()函数,或者是app.start()是最好的。


另外一个过程就算只用一次,如果太长,最好还是要拆分的,然后每段代码用函数来命名。这样易读也好该。就好象使用build pattern,一段一段的build。

当一个文件大到难以阅读的时候,就是可以拆分的时候了。吧能独立的函数全部独立出来。然后留下不能独立的函数就留下。

每个人都有重构的方法和原则,取其精华就可以了。 从《重构》这部书上,先学学那些基本方式,在这本书基础上进行加强就好了。

重构的过程中,单元测试还是非常重要而且有用的,可以快速确定你的修改过程中,没有影响到结果。所以重构时候,写测试,是个非常好的习惯。

现在写函数/方法的时候,可测试性也是在考虑范围之内的。

评分

参与人数 1威望 +50 收起 理由
cais + 50 我很赞同!

查看全部评分

回复  

使用道具 举报

134#
发表于 26-12-2013 02:47:36 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 26-12-2013 03:59 编辑

很难得有这么多同行谈经验,非常高兴! 我是一直对很技术有兴趣,但是这几年一直找不到什么人探讨。工作的时候还是吹牛最管用,难得在这里可以畅所欲言。

有关测试,主要是觉得测试反生产力,各位不知道有没有什么个人项目。如果有人能短时间写个很复杂的JS lib,又有全面实用的unit testing那就有说服力了。 javascript 上的界面自动测试我很不以为然。写点测试并不难,关键是这测试是否真的能测错。测试也是程序,也可能有错,一堆mock之后,mock的是否准确又很成问题。那么就又出现了如何给这些测试代码做测试的悖论。坦率说我觉得js上的界面自动测试就和小孩过家家差不多。 如楼主说 ‘我发觉写unit test case要比写C#程序困难多了’, 人的时间都是有限的。所以控制测试的成本,把节约的时间用设计重构上会不会比追求绝对完美的全覆盖测试更有效率呢?  这个观点其实我是听一个JS大牛的podcast听到的,我听了之后只有双手赞成。

另外我反对大函数无条件的分小函数,不是因为怕麻烦,而是因为这个违反逻辑。 如果一个函数只可能被一个上层函数调用一次,那这两个就是紧耦合,实质上就是一个不可分割的整体,把这个多余函数暴露出去是非常不合理的。把一个函数分小碎片,对其他开发者来说就都是噪音,因为他本来根本就不用管你的实现,只需要知道有这么一个方法就可以,这么五六个函数对他都是多余负担。  可能我是java面向接口训练出来的,设计一个类首先是考虑要做什么事,至于怎么做,那是下一层抽象。 所以我看到一堆看起来莫名其妙的public函数尤其是public类会很不舒服 。事实上我的函数一般都是20行以内为多,很自然就是这么个状况,也从来没有刻意考虑过行数。

如果发现某个接口实现起来太复杂(长函数),那就说明设计有问题,有一层抽象太臃肿,应该考虑组合或者继承。简单的把长函数切碎在我看来是很粗暴的(这些多出来的函数估计是会给加在同一个类里也不管合理不合理,是不是同一层次的抽象),也掩盖了真正的设计问题 (比如是不是应该加一个 utility 类,是不是某个类太臃肿失衡). 设计一个东西,首先想的就是分几个包,几个类,这些包或类负责什么层次的抽象,又怎么继承或组合。关键类有哪些函数,这些函数都做什么事,都是应该远在写代码之前思考好的。

我觉得一个设计良好的系统是很难出现超过50行的函数的。但反过来说,如果把函数不超过50行作为设计原则,那就太思维简单而颠倒了因果。这就好比一个人感冒就会流鼻涕,但你绝对不会用把鼻涕堵住的办法去治感冒。

但说实在的,如果只是CRUD,存取数据库之类那也没什么好设计的,似乎怎么样都能做出来。这就是做应用的悲哀,太简单了,精力用不完,所以大家开始想各种花样互相折腾。
回复  

使用道具 举报

135#
发表于 26-12-2013 10:49:57 | 只看该作者
本帖最后由 caoglish 于 26-12-2013 10:58 编辑

测试也是有很多概念的,写的测试有问题也是非常现实的。不过就好像程序,可以不断改进。测试也是随着自己的的技术和经验,来不断提高的。测试能写的很烂,也能写的很好。好的测试,的确是能够证明代码的健壮性

我写unit testing,断言恒等的断言不等都会写;预计怎样的输入会错,也会有几个case,这样unit testing就更加说服力。

另外,如果是给公司写代码,其实unit testing是写给自己的,帮助自己更快发现修改代码时候出现的错误。老板只要你的东西能用就行,这个是技术上的东西。

但是如果是开源代码,两个软件同时声称有这个功能,但一个有单元测试,一个没有,你会用那个?开源代码或者模块,面向的对象都是技术人员,自然是用技术说话。

另外有人质疑javascript写单元测试有意义吗?相反javascript就是因为单元测试的出现,才使涌现出来那么多优秀的第三方模块,也正是单元测试的原因,大家敢用第三方模块。js第三方模块如此活跃,单元测试功不可没。


我最喜欢用的时间处理库是momentjs,因为它有2万多个断言(http://momentjs.com/
jquery团队为了测试jquery,开发了qunit
angularjs自从有了测试方法和工具和详细的测试文档,才开始火爆起来的。
另外lodash,为了证明自己比underscore更好,他们也是unit testing上下了很大的功夫。(http://lodash.com/tests


js的单元测试和其他平台不一样,其他平台基本上就是改错的时候和部署的时候会用到。而js的单元测试还会直接用到浏览器兼容这一块,甚至是要前台后台一起做测试。关于这点,可以看看testem这个项目。它是多平台单元测试的一个项目(检测文件改动而自动刷新浏览器页面),我曾经实验过打开IE,firefox,chrome,然后iphone,android一起打开页面进行单元测试开发,完全没有压力。js没有自动测试(单元和功能测试),浏览器的兼容测试就是一场噩梦。

另外还有单元测试的使用好处,在团队合作开发会很有意义。如果有10个人甚至是100个人一起开发一个项目,没有一个统一的单元测试文件列表,你如何判断这次从代码库中下载的代码是没有问题的。

一个人开发的话,单元测试是给你以后开发的那个人看的,或者是两年后的自己看。




评分

参与人数 2威望 +100 收起 理由
karl.lee.2004 + 50 谢谢分享!
cais + 50 谢谢分享!

查看全部评分

回复  

使用道具 举报

136#
发表于 26-12-2013 11:00:22 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 26-12-2013 12:07 编辑

I can see the point of doing unit testing for momonent or lodash, even jquery.

But have a look at this page http://shenshowcase.appspot.com/static/map/demo/toolbar.html, how will you write unit test for an app or lib like that? It does not hurt to create unit tests, but I wont get too confident with them. I don't think auto testing is efficient for finding issues for real complicated UI.

So my problem with unit testing is it wastes your time when things are simple, and soon becomes useless when your UI is complicated. When handling complex UI or making some serious design, your will need to use your brain and time very efficiently. The auto testing is redundant if it is can't be reliable. But of course, doesn't cost much apart from your time.
http://www.realfreemarket.org/bl ... -stupidity-spreads/
Another interest ing story. Anyway I feel it is a crime to force telented people to auto test everything they write, or overvalue this technical. it is nothing creative.
回复  

使用道具 举报

137#
发表于 26-12-2013 11:57:52 | 只看该作者
black_zerg 发表于 26-12-2013 11:00
I can see the point of doing unit testing for momonent or lodash, even jquery. But have a look at t ...

测试还有个概念,叫做可测试性。就算是简单的代码可能也会发生不可测试的情况发生。比如说内部含有singleton和static的函数/方法。所以在设计的时候,就一定要考虑可测试性这个因素,可以设计一定的测试方式。

比如第一个地图,起始位置都是一样的。然后定义两个点,抓图。然后单元测试的时候,基本上就是自动点亮点,抓图,进行图片比较。这个是一个方式。
JS-ImageDiff Jasmine是这个方式的代表。不过它主要用来做css测试的。不过坏处也比较明显,浏览器渲染方式一不一样,就会有difference
http://humblesoftware.github.io/js-imagediff/test.html

现在还是有人在研究如何在canvas进行做单元测试,下面的是一个demo。
http://philip.html5.org/tests/canvas/suite/tests/

如果还是有很多地方不能测试,那么就把能测试的地方都测试一下,而不是做整体测试,保证代码的基础部分一定正确,也能保证项目的可靠性。我对历史项目的测试原则  就是能多写一条测试,就多写一条。

当然,现在你的项目可能测试很困难,实在没有一个可以使用的测试框架,但是自动化测试始终是这个行业的发展趋势,如果你开发的东西,找不到现成的测试工具,但是你又为了完成测试,自己开发了一套测试框架来完成你的测试,那就是这个技术的领头羊,给这个技术带来革命性的创新了。

回复  

使用道具 举报

138#
发表于 26-12-2013 12:05:44 | 只看该作者
black_zerg 发表于 12-12-2013 09:49
spot on 所以你这两百多用例的产出就是发现了这两个实际根本不会发生的bug,这个时间也许不如用在学习或者思 ...

同意。个人比较反感一些条条框框。纯粹是让人有饭吃。

以前版本控制的产品卖得很贵,但Linus 3 天就写了个git,还免费。

佩服这种牛人,也是好程序员的方向。

回复  

使用道具 举报

139#
发表于 26-12-2013 12:10:49 | 只看该作者
提示: 作者被禁止或删除, 无法发言
Totally, and the guy wrote JavaScript in like ten days. I would never believe he wrote auto test in that ten days.
回复  

使用道具 举报

140#
发表于 26-12-2013 12:20:18 | 只看该作者
black_zerg 发表于 26-12-2013 11:00
I can see the point of doing unit testing for momonent or lodash, even jquery.

But have a look  ...

另外要我设计像你一样的app的测试方式,也是有可能的。

程序无非就是数字转成图形,图形转成数字。第一个地图,可以按照点的顺序,进修记录坐标。然后模拟点击,最后检测模拟点击的的位置产生的数据,是否和预期的顺序和坐标一样了,表示正确。

第二个地图是heat map,基础色和heat map的颜色是不相同的,这样的话在模拟点击后,heat map的颜色就会增加,只要计算heat map说产生的颜色数量在不断的提升变化,就可以表示功能在运作。

第三个的确不好说,不过上面的图片坐标值,和移动和的坐标值和下图的坐标值进行比较,也能做一定的测试,说明某些功能是正确运行的。

评分

参与人数 1威望 +20 收起 理由
black_zerg + 20 谢谢分享!

查看全部评分

回复  

使用道具 举报

141#
发表于 26-12-2013 13:44:40 | 只看该作者
Nicholas C. Zakas:我得到的最佳职业生涯建议
http://blog.jobbole.com/53812/

楼主看看这篇翻译吧,很好说明了程序员在非技术性方面的不足以及改进建议。

评分

参与人数 1威望 +20 收起 理由
black_zerg + 20 精品文章

查看全部评分

回复  

使用道具 举报

142#
发表于 26-12-2013 14:21:08 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 26-12-2013 14:47 编辑
caoglish 发表于 26-12-2013 13:44
Nicholas C. Zakas:我得到的最佳职业生涯建议
http://blog.jobbole.com/53812/


Very inspiring article! Nicholas is brilliant, very talented and hands on. I remember there was a presentation he talks about maintaining javascript code or something.  
回复  

使用道具 举报

143#
发表于 26-12-2013 14:47:05 | 只看该作者
caoglish 发表于 26-12-2013 12:20
另外要我设计像你一样的app的测试方式,也是有可能的。

程序无非就是数字转成图形,图形转成数字。第一 ...

一直都很喜欢TDD,并且把TDD视为对我这些年技术成长影响最大的三个东西之一。
不过我觉得TDD的适用范围还是有一定的限制的。例如一些逻辑并不复杂但有大量数据库操作,或者UI关联特别紧密的地方。 这些地方TDD虽然也能做,但必然会带来大量的mock对象,维护这些东西的成本往往比收益还要高。
我这几年主要是在做产品,中间也曾经去做过两年的外包。做产品时TDD的确很管用,但做外包的时候情况就完全不一样。
应用TDD这类技术的时候环境和团队文化特别重要,我的经验是小规模高素质的团队里应用效果很好;一旦团队扩大,成员水平跟不上,TDD很难有好效果。

-------------------------------------
关于50行代码限制:
其实这是一个提醒而不是目的。一旦代码超过50行,你的函数在逻辑上很可能就承担了多个层次或者多个类型的工作,有bad smell的可能性极大。不是没有例外,但大多数时候都是这样。
如果你之前没有尝试过去关注这个问题,现在不妨开始试试,我保证你不会后悔的。

评分

参与人数 1威望 +20 收起 理由
black_zerg + 20 我很赞同!

查看全部评分

回复  

使用道具 举报

144#
 楼主| 发表于 26-12-2013 18:26:28 | 只看该作者
woodheadz 发表于 26-12-2013 14:47
一直都很喜欢TDD,并且把TDD视为对我这些年技术成长影响最大的三个东西之一。
不过我觉得TDD的适用范围还 ...

还有哪两个东西啊?
回复  

使用道具 举报

145#
发表于 26-12-2013 19:17:09 | 只看该作者
DDD888 发表于 26-12-2013 18:26
还有哪两个东西啊?

同求。。。。
回复  

使用道具 举报

146#
发表于 27-12-2013 13:03:48 | 只看该作者
DDD888 发表于 26-12-2013 18:26
还有哪两个东西啊?

一个是侯捷的《深入浅出MFC》,《深入浅出com》,算是启蒙,让我理解了framework的意图,也亲身感受到封装和抽象的意义和力量。

第二个是robert martin 的《敏捷开发原理,实践》,里面关于OOP几大设计原则和设计模式的梳理让我把之前比较零散和模糊的设计经验理顺固化。这本书同时也彻底把我从学院派软件工程思想里解放了出来。

第三个TDD思想其实我也是从robert martin的书里学到的,但经历了一个逐渐尝试到接受的过程。 我自觉获益最大的是TDD里面包含的从外到内小步前进,不断重构同时永远保持最小化实现的思想。咱们程序员在掌握了一些基本的设计手段后最大的问题就是过度设计,TDD的这种思想是我现在接触过的开发哲学中应对过度设计问题最好的手段。
回复  

使用道具 举报

147#
发表于 27-12-2013 13:55:48 | 只看该作者
提示: 作者被禁止或删除, 无法发言
本帖最后由 black_zerg 于 27-12-2013 14:13 编辑

The article from Nicholas C. Zakas is really inspiring. He is a very talented JavaScript guru, now even he is emphasizing the importance of the interpersonal skills and how did they help his career. Really makes me think.

Why techniques becomes less important? Why always a people person gets promoted but rarely the most talented programmer? I would blame the society and the capitalism. But at the end of the day, we all need to provide for the family. We have little choice but to understand the way the industry works and do our best to fit in. However, we can still play with code when we have free time, and keep learning new techniques as our hobbies.

One thing I learnt is, The skill is only valuable when it is needed. Couple of years ago I created a product for my company nearly single handed. After that, the boss just sent teams installing the system everywhere.  The product doesn't break easily, so people forgot my contributions. The manager/team leaders of the implementing team get much more attention and credit than me. I got some pay raise at that time, but comparing to the money company gets from this product, it was nothing. That is why now I value client relationship and people skills much more.  And, never, never make something too perfectly for cheap price. your hard work won't be appreciated.
回复  

使用道具 举报

148#
 楼主| 发表于 27-12-2013 14:26:45 | 只看该作者
对现有C#代码(legacy code),有没有自动生成unit testing的代码的工具啊?我找了许多时候都没有找到
回复  

使用道具 举报

149#
 楼主| 发表于 27-12-2013 18:26:20 | 只看该作者
现在我写C# unit test 神清气爽,我发觉以前我用delphi写unit test实际上写的是integration test,并非unit test
回复  

使用道具 举报

150#
 楼主| 发表于 27-12-2013 19:53:58 | 只看该作者
我发觉要真正应用tdd,计算机的性能一定要非常好,运行几百/几千个unit testing,等上超过10秒钟是不可以接受的啦
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 2-11-2024 15:23 , Processed in 0.079482 second(s), 50 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表