JUnit中获取测试类和方法的名称

在JUnit的测试中,有时候需要获得所属的类(Class)或者方法(Method)的名称,以方便记录日志什么的。

在JUnit中提供了TestName类来做到这一点,在org.junit.rules中:

虽然TestName只提供了方法的名称,要加上类的名称很容易,只需对TestName稍作修改如下:

在测试用例中的用法是:

大功告成!

使用WebDriver对特定的WebElement截图

用过 WebDriver 的同学都知道,WebDriver 可以对浏览器中的页面进行截图。例如:

这样产生的图片是整个网页。但有时候我们并不需要整个网页,只需要某些特定的 WebElement,以避免一些干扰。

虽然 WebDriver 本身没有提供这样的 API,不过我们可以自己来,就是在全屏的截图中再进行裁剪,如下:

其中 ImageIO 和 BufferedImage 分别来自 javax.imageio 和 java.awt.image。

这种方法可以很好的削减截图的大小,也避免了一些不确定因素(比如日期时间等),是测试中保存截图的很好的方式。

注:如果测试的网页中含有 iframe,则需要使用更复杂的方式计算 WebElement 的位置,详见:计算网页中某个元素的位置

使用 Preconditions 来检查传入参数

Preconditions 是 Guava 中的一个类库,用于检查传入参数,一个常见用法如下:

用法简单明了,就是检查参数 elements 是不是 null,如果是 null 则扔出 NullPointerException。当然 Preconditions 类里还有其它方法,可能满足几乎所有的传入参数的检查。Preconditions 的好处在于,它在 call stack 中更容易理解,并且每个方法还提供了格式化字符串的变体,形如:

和 Java 自带的 assert 关键字不同的是,Preconditions 的方法在 release 版本中依然有效,这么做的原因,大概是因为 Java 已经很慢了,不太乎多做些检查吧-_-

StringBuffer vs StringBuilder

早先用Java的时候,知道有个类叫StringBuffer,用来拼接较长的字符串。转到C#之后,也有一个似类功能的类叫作StringBuilder,简写都是sb,非常好记。

再后来转移回Java的时候,发现Java也有了StringBuilder,于是就好奇了一下为什么在StringBuffer之后又推出了StringBuilder。

原来Java的StringBuilder(和C#一样)是非线程安全的,而早先的StringBuffer具有一定的线程安全属性。当然,推出StringBuilder,主要也是因为它没有必要在多线程的情况下使用。

常见的StringBuilder(或者StringBuffer)的用例是:

在这种情况下,StringBuilder都不是一个类成员,它只是一个局部变量,根本谈不上多线程的问题。

于是,StringBuilder的引入带来了非常大的性能提升,而且一点安全问题也没有……

Java里的static import

换了工作要把Java重新捡起来了,这个在大学里用过的语言,虽然不复杂,还是有一些奇怪的地方的。比如static import。

Static import是JDK 1.5中引进的特性,不过读大学那会还真没注意到。它的作用是把静态(static)的方法或者常量import进来。比如:

使用了static import之后,就可以写成:

注意"Math."和"System."可以省略掉了。

Static import和import的规则类似,引用的内容不可以有歧义。

使用了static import,代码会变短,增加了可读性,但一定程度上会对代码整体的理解造成困难,因为常量和静态方法看上去像全局变得和全局方法了,有点C++的味道,失去了一些OO的美感。

上海时间的变迁

这是最近IT界流传甚广的一个贴子,原发于StackOverFlow,后被到处转载。起因是一个程序员发现在Java中,当地区设置为上海(Asia/Shanghai)的时候,在公元1927年12月31日的23:54:07,和23:54:08之间,相差了整整353秒,也就是5分53秒。而23:54:08和23:54:09之间,又只相差1秒了。这是为什么呢?

根据TimeAndDate记载,上海的时区在1927年12月31日的午夜发生了变化,从LMT(当地平时,Local Mean Time)转到了CST(GMT+8),于是乎,就少了353秒。不过TimeAndDate只记下了这个变化,并没有说明原因。不过Wikipedia上面有这么一段:

民国17年(1928年),国民政府统一中国,原中央观象台的业务由南京政府中央研究院的天文研究所和气象研究所分别接收。……不再使用北平的地方平时,而改以南京所在的标准时区的区时即东经120°标准时替代。

这样可以大概解释这个问题了。

尽管我们现在都习惯了GMT+8的时区,在国内无论跑到哪里都是同样的时间,不过在历史上,北京时间也是有变化的。比如:

1986年至1991年,中华人民共和国在全国范围实行了六年夏时制,每年从4月中旬的第一个星期日2时整(北京时间)到9月中旬第一个星期日的凌晨2时整(北京夏令时)。

也就是在那段时间里,北京时间使用的是GMT+9的时区,后来由于经常改时间造成了不必要的麻烦,这个规定就没有继续执行下去……

最后还是要赞一下Java的开发人员呀,1927年的陈年旧事都能考虑到,真是太不容易了……

《编程方法》第五课 变量

如果你喜欢这门课程,请在新开学网站上支持一下,使译者更有积极性。顺便也请支持一下《算法导论》课程,非常希望这门课能推广出去……

点击观看课程视频(优酷)

以下是笔记:
[01:30] 在计算机中,变量就像一个盒子,可以存放可变的内容。
[02:00] 变量的三元素:名称、类型和值
[02:20] Java的变量可以用下划线或者字母开头,之后可以跟字母、数字、下划线。(如果没记错的话,Java的变量可以使用Unicode字符,只不过这是美国人在讲课-_-)
[04:20] 原始类型:int(范围从-20亿到+20亿)、double
[06:00] 变量的声明:类型 名称 = 值;
[07:00] "=" (等号)表示赋值:变量 = 表达式;
[14:00] 变量可以要存放类的实例
[16:00] 类的实例通过new操作符生成
[17:00] 调用方法:变量.方法();
[18:30] (貌似英文字幕有错,应该是IM,Instant Messenger,而不是I am)
[22:30] 方法和参数:变量.方法(参数1, 参数2, ... );
[24:30] 变量在使用之前一定要先定义
[25:00] java.awt中预先定义的Color实例
剩下的内容都是在讲解一些图形的类如何使用,方法的定义和例子之类的,就不一一记录了,有兴趣的同学自己观摩吧:P
[39:00] 表达式的种类 变量 = 变量 操作符 变量,如a = b + c,操作符有+ - * /(整除) %(取余)