Assert.assert,断言,是大家JAVA单元测试必用的语句。根据个人的体验,Assert颇有不便之处:
1. Assert可以输入一个message,失败的时候,会把这个message打印出来,开发人员就知道错误是什么;开发人员也可以选择不输入message,这样失败了就什么都看不到;
2. Assert的工具不够多,比如没有函数直接支持 a 大于 5这样的断言, 也不能断言一个list包含另一个list;
问题是,单测本来是耗时耗力的事情,并且99%的断言都是不fail的,并且要写一个能解决问题的message很困难,于是很多人养成了不写message的习惯。然而,如果某个case在本地是好的,但是另一个环境 fail了,开发者打破脑袋也想不出来为什么,唯一的办法就是加个message,再次提交,再次fail。
我认为导致这个问题的原因是:junit的断言,是断言真假,而不是断言变量。
两者的区别是:断言真假,只知道结果是true或者false;断言变量,不仅能知道true和false,还知道参与断言的变量是什么。
如果断言fail,我们可以把参与断言的变量tostring打印出来。这样既能节约开发人员的时间,又能全面的获得fail时的上下文,便于排查问题。
基于junit的assert,可以很容易的扩展出基于变量的断言,比如下面的断言。无须任何message,但是如果断言失败,打印出的message足以告知出错的原因。
/** * 断言某个List包含另一个List的所有元素。 * @param actual * @param expected */ public static <T> void assertContains(List<T> actual, List<T> expected){ String actualStr = join(actual,",",100); String expectedStr = join(actual,",",100); //省略… Assert.assertTrue("\nactual="+actualStr+"\nexpected=" +expectedStr+"\nmissed="+missedStr, missed.isEmpty()); } |
有时候用户的class可能不会实现tostring方法,这是即使把obj打印出来也没大用。所以我使用了一个强制输出string的办法,如下所示:
/** |