- 浏览: 524482 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
飞天奔月:
public List<String> gener ...
实践中的重构30_不做油漆匠 -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道public class A {
...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在世界的中心呼喚愛 写道在classB ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在classB的finalize上打断 ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
iteye比较少上,如果可以的话,可以发e-mail交流:ch ...
深入理解ReferenceQueue GC finalize Reference
首先,单元测试以及单元测试覆盖率只是一个工具,很烂的代码一样可以有全套的单元测试和很高的单元测试覆盖率(这里只指代码覆盖率,不涉及分支覆盖等)。其次,单元测试和覆盖率是有用的,尤其是在我们想把一件事情搞好的时候。
单元测试顾名思义就是对单元进行测试,这里的单元就是方法。但是我们在类的设计中会设计方法的访问限定符,以此来更好的做到高内聚,低耦合。如果只是对public的方法做测试,那么为了验证一些private方法的正确性,我们就需要以public方法为入口,构造复杂的测试上下文,如此,增大开发测试的负担。那么,对不公开的方法如何测试呢。
1 采用java独特的包访问权限,这样的话,product code和test code可以放在不同的目录,但是可以有相同的包名。这样的缺点是test影响了product code的设计。
2 采用反射,采用反射可以访问product code的private方法,这样,test和product就完全隔离开了。这样的缺点是test中对方法名要进行hard code,不利于重构。但是权衡利弊,这个方法还是可行的。
在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。
比如我们有一个
private int getUserAge(String userId) 的方法,为了测试,在test中可以有如下结构。
//调用指定对象的指定方法。用java的反射机制实现。
private Object invokeMethod(String methodName, Class<?>[] parameterClasses, Object object,
Object[] parameters)
//转发调用。
private int invokeGetUserAge(String userId){
调用invokeMethod,做适当的类型转换。
}
//真正的test方法,调用invokeGetUserAge。
public void testGetUserAge()
在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。
比如我们有一个
private int getUserAge(String userId) 的方法,为了测试......
UT还private?更进一步地说,UT还纠结于单元测试?
如果你真的做UT,你在动手写代码之前就有关于用户行为(这里的用户不仅仅指最终用户,如果你是发布一组工具那么你的用户就是其它开发组中的程序员)的设计了,你可以将这种设计写为测试程序(而不是满足在可以随便忽悠着解释的文档),然后才开始开发。如果编译不通过,就让它编译通过;如果针对数据输入输出的断言不通过,就让断言通过!
你做UT时还纠结于private,甚至纠结于单元测试,咄咄怪事。(因为单元测试工具只是一个驱动测试开始执行的工具,而你要的是针对UT的对象而不是什么代码函数单元啊)。
更进一步说,好的测试是对重构提供支持的。你纠结于那些“单元”,还能重构吗?使用你的所谓单元测试代码维系垃圾代码,当作餐桌上的主菜,是不是本末倒置了?
我给你提供一个测试的“原则”作为参考。对于纯粹功能性的开发,我在写测试时保持大致1个半小时的开发时间(因为之前需要10~30分钟编写测试代码的时间),这就是我写测试的原则。
每当重构了,当然要回归运行那些测试代码。因此这些测试时为了支持重构这种高度灵活性的东西而准备的。
怎么可能像你那样,先写完了实现代码,然后才钻到垃圾堆底层private单元集合里边去翻最臭味道的代码单元来编织到“测试系统”里呢?
你说的这些我都是同意的,如果条件允许的话,我当然也是这么做,事实上,TDD的开发精髓就是测试驱动设计。
问题是我现在面临的场景中,业务逻辑很复杂,于是,为了方法的内聚性,一个public的方法往往需要调用拆分出去多个private方法,这是,如果坚持一套完整的测试的话,那么测试环境的搭建将变得复杂,或者说关注点不集中,因为测试的分支是成指数级别增长的,而为了系统的稳定性,我们需要覆盖掉所有的分支。我选择用反射来测试这些private方法可以分离测试的关注点。当然,这个对重构是有不好的影响的,权衡利弊,我只能采取一些措施降低这种影响,但是还是要保全一个test的完整性和专注性。
举个例子,
public Object f(Object input){
根据input计算出s1,s2,s3,s4,flag
if(flag){
a=g(s1,s2);
return a;
}else{
b=g(s3,s4);
return b;
}
}
public void f1(){
调用g.
}
private Object g(Object o1,Object o2){
}
flag有2种状态。
假设g方法的参数o1,o2各有3种状态。
如果采用先test后code的方法,为了完整的测试f的功能,那么我们需要控制input来生成所有的2*3*3=18个test才能完全覆盖到所有的分支。当然,也可以控制input生成flag为true的9种情况,以及1个flag为false的情况。
但是我觉得这样的测试关注点不够集中,我的思路是,可以先为f写两个test,来覆盖flag的两个分支,然后coding,保证f的两个分支都被测试到,即g都被调用过,至于g自己的方法约定,应该属于g自己的事情,可以用反射来测试。
我们在考虑一下如果f,f1都要调用g方法的情况,那么我们有必要为测试f,f1都建立g的9种状态吗?如果还有更多的f2,f3,...fn呢?
传统的test是一种黑盒测试,而用反射是白盒测试。我认为程序员是可以利用关于实现的知识进行测试的。利用反射,虽然一方面增加了重构的难度,但是,可以提高测试的关注点,同时,白盒测试也有利于重构出被多个public方法调用的private方法。
爽吧?
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。
内聚性不一定要通过把方法写在一个类里实现,可能还是对业务拆分的粒度不够,或许可以大概说说这个业务实现的功能详情?
个人经验,设计成多个类,短时间内可能复杂一点,但是问题多样化以后,对类的修改反倒会简单些。呃,代码效率就不好说了
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
不相信.
很多人不理解自己写过的代码
当然很多人不理解自己写过的代码
但是并不是所有人都不理解
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
不相信.
很多人不理解自己写过的代码
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
这种空对空的代码是没有任何意义的
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
前边例子已经举过,真实的代码当然是公司的,不能外泄。但是抽象出的示例代码已经可以说明问题了。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?
这个很有道理。不要滥用反射进行这种测试。如果利用反射进行对private方法进行测试。那么本质上就是忽略了private方法作用了。
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。
如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?
单元测试顾名思义就是对单元进行测试,这里的单元就是方法。但是我们在类的设计中会设计方法的访问限定符,以此来更好的做到高内聚,低耦合。如果只是对public的方法做测试,那么为了验证一些private方法的正确性,我们就需要以public方法为入口,构造复杂的测试上下文,如此,增大开发测试的负担。那么,对不公开的方法如何测试呢。
1 采用java独特的包访问权限,这样的话,product code和test code可以放在不同的目录,但是可以有相同的包名。这样的缺点是test影响了product code的设计。
2 采用反射,采用反射可以访问product code的private方法,这样,test和product就完全隔离开了。这样的缺点是test中对方法名要进行hard code,不利于重构。但是权衡利弊,这个方法还是可行的。
在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。
比如我们有一个
private int getUserAge(String userId) 的方法,为了测试,在test中可以有如下结构。
//调用指定对象的指定方法。用java的反射机制实现。
private Object invokeMethod(String methodName, Class<?>[] parameterClasses, Object object,
Object[] parameters)
//转发调用。
private int invokeGetUserAge(String userId){
调用invokeMethod,做适当的类型转换。
}
//真正的test方法,调用invokeGetUserAge。
public void testGetUserAge()
mock1234 写道
zhang_xzhi_xjtu 写道
在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。
比如我们有一个
private int getUserAge(String userId) 的方法,为了测试......
UT还private?更进一步地说,UT还纠结于单元测试?
如果你真的做UT,你在动手写代码之前就有关于用户行为(这里的用户不仅仅指最终用户,如果你是发布一组工具那么你的用户就是其它开发组中的程序员)的设计了,你可以将这种设计写为测试程序(而不是满足在可以随便忽悠着解释的文档),然后才开始开发。如果编译不通过,就让它编译通过;如果针对数据输入输出的断言不通过,就让断言通过!
你做UT时还纠结于private,甚至纠结于单元测试,咄咄怪事。(因为单元测试工具只是一个驱动测试开始执行的工具,而你要的是针对UT的对象而不是什么代码函数单元啊)。
更进一步说,好的测试是对重构提供支持的。你纠结于那些“单元”,还能重构吗?使用你的所谓单元测试代码维系垃圾代码,当作餐桌上的主菜,是不是本末倒置了?
我给你提供一个测试的“原则”作为参考。对于纯粹功能性的开发,我在写测试时保持大致1个半小时的开发时间(因为之前需要10~30分钟编写测试代码的时间),这就是我写测试的原则。
每当重构了,当然要回归运行那些测试代码。因此这些测试时为了支持重构这种高度灵活性的东西而准备的。
怎么可能像你那样,先写完了实现代码,然后才钻到垃圾堆底层private单元集合里边去翻最臭味道的代码单元来编织到“测试系统”里呢?
你说的这些我都是同意的,如果条件允许的话,我当然也是这么做,事实上,TDD的开发精髓就是测试驱动设计。
问题是我现在面临的场景中,业务逻辑很复杂,于是,为了方法的内聚性,一个public的方法往往需要调用拆分出去多个private方法,这是,如果坚持一套完整的测试的话,那么测试环境的搭建将变得复杂,或者说关注点不集中,因为测试的分支是成指数级别增长的,而为了系统的稳定性,我们需要覆盖掉所有的分支。我选择用反射来测试这些private方法可以分离测试的关注点。当然,这个对重构是有不好的影响的,权衡利弊,我只能采取一些措施降低这种影响,但是还是要保全一个test的完整性和专注性。
举个例子,
public Object f(Object input){
根据input计算出s1,s2,s3,s4,flag
if(flag){
a=g(s1,s2);
return a;
}else{
b=g(s3,s4);
return b;
}
}
public void f1(){
调用g.
}
private Object g(Object o1,Object o2){
}
flag有2种状态。
假设g方法的参数o1,o2各有3种状态。
如果采用先test后code的方法,为了完整的测试f的功能,那么我们需要控制input来生成所有的2*3*3=18个test才能完全覆盖到所有的分支。当然,也可以控制input生成flag为true的9种情况,以及1个flag为false的情况。
但是我觉得这样的测试关注点不够集中,我的思路是,可以先为f写两个test,来覆盖flag的两个分支,然后coding,保证f的两个分支都被测试到,即g都被调用过,至于g自己的方法约定,应该属于g自己的事情,可以用反射来测试。
我们在考虑一下如果f,f1都要调用g方法的情况,那么我们有必要为测试f,f1都建立g的9种状态吗?如果还有更多的f2,f3,...fn呢?
传统的test是一种黑盒测试,而用反射是白盒测试。我认为程序员是可以利用关于实现的知识进行测试的。利用反射,虽然一方面增加了重构的难度,但是,可以提高测试的关注点,同时,白盒测试也有利于重构出被多个public方法调用的private方法。
评论
23 楼
piao_bo_yi
2010-11-30
#ifdef _MY_TEST #define private public #endif
爽吧?
22 楼
fflame
2010-07-12
zhang_xzhi_xjtu 写道
skydream 写道
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。
内聚性不一定要通过把方法写在一个类里实现,可能还是对业务拆分的粒度不够,或许可以大概说说这个业务实现的功能详情?
个人经验,设计成多个类,短时间内可能复杂一点,但是问题多样化以后,对类的修改反倒会简单些。呃,代码效率就不好说了
21 楼
zhang_xzhi_xjtu
2010-07-09
抛出异常的爱 写道
zhang_xzhi_xjtu 写道
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
不相信.
很多人不理解自己写过的代码
当然很多人不理解自己写过的代码
但是并不是所有人都不理解
20 楼
抛出异常的爱
2010-07-09
zhang_xzhi_xjtu 写道
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
不相信.
很多人不理解自己写过的代码
19 楼
zhang_xzhi_xjtu
2010-07-09
skydream 写道
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。
18 楼
skydream
2010-07-07
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。
实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
17 楼
zhang_xzhi_xjtu
2010-07-03
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
不是多职责类,而是本身的业务就是很复杂。
16 楼
scott.yao
2010-07-02
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
15 楼
icefire
2010-07-02
太多的private说明此类承担太多责任或者过于复杂,无论怎样,说明抽象程度不够,拆分不够,所以测试难以覆盖,才会想到用反射来做测试。
所以测试多好,一下就帮你发现问题了。。
所以测试多好,一下就帮你发现问题了。。
14 楼
gigix
2010-07-01
引用
private int getUserAge(String userId)
这种空对空的代码是没有任何意义的
13 楼
zhang_xzhi_xjtu
2010-07-01
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
12 楼
zhang_xzhi_xjtu
2010-07-01
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
前边例子已经举过,真实的代码当然是公司的,不能外泄。但是抽象出的示例代码已经可以说明问题了。
11 楼
抛出异常的爱
2010-07-01
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.
目的决定手段.
10 楼
gigix
2010-07-01
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
不要空对空。拿例子出来说。
9 楼
jiangduxi
2010-06-30
gigix 写道
第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?
这个很有道理。不要滥用反射进行这种测试。如果利用反射进行对private方法进行测试。那么本质上就是忽略了private方法作用了。
8 楼
zhang_xzhi_xjtu
2010-06-30
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类
这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
7 楼
gigix
2010-06-30
tzm1984 写道
反射有时还有用的,
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。
第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。
如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?
6 楼
tzm1984
2010-06-30
反射有时还有用的,
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。
反正具体情况具体对待 哈哈。
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。
反正具体情况具体对待 哈哈。
5 楼
berlou
2010-06-30
这种情况与其用反射区牺牲重构方面的利益,不如干脆把private变成protected或者default。
4 楼
aws
2010-06-30
只针对接口测试
发表评论
-
编码知识ppt1.4
2013-01-15 17:13 1102编码知识的一个PPT,时隔1年重新更新一个版本。 检测编码的 ... -
CSV文件的一些注意点
2012-08-20 15:38 7480狭义的csv是comma separated ... -
编码简介
2011-11-20 21:18 1075梳理一下编码的知识,做一个ppt。 -
开发故事
2011-10-30 20:49 872故事1: 这段代码我没有找到被引用的地方,是不是有什么隐秘的用 ... -
用户体验的分层
2011-03-20 11:22 1112前两天开会的时候涉及到用户体验。突然想起了王国维的《人间词话》 ... -
系统故障分类以及对我们的启示
2010-11-13 00:58 1240最近关注了一下系统的故障。发现故障基本的原因可以分为以下几类: ... -
老生常谈之如何写好的代码
2010-11-04 23:01 2640这两天一直做code review ... -
从scrum说敏捷
2010-09-09 00:47 1007最近又搞了一次scrum培训,整整搞了两天,加上以前也有参加过 ... -
衡量程序的质量
2010-08-21 22:44 1016本文介绍几个衡量代码质量的指标和工具 1 CAP篇 不好的程 ... -
我们要写怎么样的系统
2010-08-17 23:17 980编程也好久了。越来越觉得一个做一个好的程序员不是一件简单的事情 ... -
文档的作用
2010-06-16 18:09 1138万事万物总是有其两面性的。 当瀑布模型把文档放在一个很重要的位 ... -
计算机数学基础 数论简要笔记
2010-03-26 17:59 1485基本概念:整除,因子,素数,合数,互质,公约数,最大公约数,欧 ... -
一个貌似失败的行业通用解决方案之旅
2010-03-11 10:53 1468公司于两年前计划研发一个行业的通用解决方案。 当时的外部环境是 ... -
《代码之美》第7章 漂亮的测试 的bad smell
2009-09-26 02:13 1067这章基于二分查找讨论了一个漂亮的测试应该怎么做。 先看看原文怎 ... -
好好的做程序员这份有前途的工作
2009-09-23 00:07 1225好好的做程序员这份有前途的工作!!! 凡是对我说这句话的人都 ... -
理论计算机的一些有启发的想法
2009-09-16 17:21 8811 门电路,自动机和图灵机。 门电路只能处理固定数目的输入 ... -
jar的混乱
2009-05-25 23:43 1222使用了一阵.net之后回到 ... -
面向过程,面向对象与程序设计
2009-04-28 23:55 1363有一种说法,说是一个长时间搞面向过程的人(搞c的人)很难理解O ... -
抽象简化了开发吗?
2009-03-29 16:10 1170都说抽象是简化了开发! 呵呵,我不这样认为,声明先,不是我的 ...
相关推荐
介绍如何利用反射和注解去简单的模拟JUnit4单元测试的使用,之所以选择JUnit4是因为4.0以后最大的改进就是使用了注解。需要注意的是这里并不是完全的模拟,只是简单实现了一下Runner类和JUnit注解相关的工作流程。...
关于注解、反射、单元测试、lombok等知识点的总结笔记
利用Floquet周期性边界条件,用HFSS对反射阵单元进行仿真,选用的单元是方形贴片
使用matlab计算反射阵天线单元的相位补偿
折射-反射-枚举-单元测试综合案例
通过matlab编程,计算反射阵单元相位补偿。反射阵天线每个单元相位补偿不同,点源球面波反射后可形成平面波
对在Java环境下应用反射的性能,做了测试分析
这个只是上传的笔记而已。勿喷。关于代码都没能上传,请谅解。相关笔记以后再上传。
学习反射机制时候,编写的Demo.代码写的有点乱,具体可以大家自己琢磨下,其中包括Excel的操作Jar包
c# 反射测试 demo
JAVA反射机制自定义框架测试代码,留着以后复习用!
ehcache 测试 反射类 例子
unity光线反射测试demo,主要配合博客进行学习,可以形象的看出光线路径
图像质量测试箱式反射灯箱调研,包括: 北京正印科技、上海研鼎信息、深圳三恩时科技共三家公司的灯箱产品,包含产品具体参数、外观图片。
java 反射使用的整理和委托实现接口反射的例子
Java基本的反射方法
光时域反射仪OTDR光缆测试仿真软件:exfo otdr、可以打开sor,trc等文件格式,并进行断点、损耗等功能分析!
反射反射反射反射反射反射反射反射反射反射反射反射反射反射反射反射
使用反射启动WC服务