关于单元测试中可维护性的2个关注点

关于单元测试的内容很多,关于可维护性的内容也很多,在这里主要关注单元测试代码可维护性中的两点。

  • 重复

  • 条件测试

重复


重复:同一概念,多处表达。从形式可以把重复分类为:代码内容完全一样,代码结构相同,结构不同但语义相近。

获取重复的感性认识

代码完全相同

在多个文件中到处充斥着

log("当前网络不可达!");

在比如, 下面的两处空字符串""完全一样,两处 "plainText"完全一样.

public class TemplateTest {
    @Test
    public void emptyTemplate() throws Exception {
        assertEquals("", new Template("").toString());
    }

    @Test
    public void plainTextTemplate() throws Exception {
        assertEquals("plainText", new Template("plainText").toString());
    }
}
代码结构相同

比如下面的代码,结构是相同的

public class TemplateTest {
    @Test
    public void emptyTemplate() throws Exception {
       String template = "";
        assertEquals(template, new Template(template).toString());
    }

    @Test
    public void plainTextTemplate() throws Exception {
        String template = "plainText",;
        assertEquals(template, new Template(template).toString());
    }
}
<a name="semanteme_repeat"></a>结构不同但语义相近

下面两处内容、结构都不同相同。但可以抽象为通过某种条件对一个集合进行过滤,最后得到目标集合。

@Test
    public void groupShouldContainTwoSupervisors() {
        List<Employee> all = group.list();
        List<Employee> all = new ArrayList<>(all);
        Iterator<Employee> i = employees.iterator();
        while(i.hasNext()) {
            Employee employee = i.next();
            if (!employee.isSupervisor()) {
                i.remove();
            }
        }

        assertEquals(2, employee.size());
    }

    @Test

    public void groupShouldContainFiveNewcomers() {
        List<Employee> newcomers = new ArrayList<>();
        for (Employee employee : group.list()) {
            DateTime oneYearAgo = DateTime.now().minusYears(1);
            if (employee.startingDate().isAfter(oneYearAgo)) {
                newcomers.add(employee);
            }
        }

        assertEquals(5, newcomers.size());
    }

去重后

@Test
    public void groupShouldContainTwoSupervisors() {
          groupShouldContains(2, group.list(), employeeFilter);
    }

    @Test
    public void groupShouldContainFiveNewcomers() {
        groupShouldContains(2, group.list, customFilter);
    }

抽象接口

public interface Filter<T> {
        List<T> filter(List<T> objects);
}

抽取公共方法

 private void groupShouldContains(int expectedCount, List group, Filter filter) {
     List list = filter.filter(group);
     assertEquals(expectedCount, list.size());
}

怎么去掉重复

根据重复的概念---“同一个概念,在多处表达” 所以我们要第一步先抽象出表达的概念。第二步 把所有出现重复的地方用我们抽象的概念形成一个统一的命题。

第一步 抽象概念

我要打印一个树,可以这样实现,printTree 等价于11条print语句

print "   *  " 
print "  ***  " 
print " ***** " 
print "*******" 
print "   *   " 
print "  ***  " 
print " ***** " 
print "*******"
print "   #   "
print "   #   "
print "   #   "

同样的问题还可以这样看:printTree等价于先打印两个树冠,在打印一个树干。

printCrown();
printCrown();
printTreeTrunk();

这里的树冠(crown)和树干(trunk)就是我们抽象出来的概念。

在上面语义重复的例子 抽象出的概念是过滤器的概念。

第二步 统一命题

在上面语义重复的例子 抽象出过滤器的概念后,可以形成这样一个统一的命题:如果一个原始集合经过过滤器过滤,那么会生成一个符合预期的新集合。

有了过滤器的概念不难定义一个过滤器对象,然后把命题用过滤器对象翻译出来。

从可读性的角度看重复

我们知道可读性是可维护性的前提,那么重复的代码是怎么影响可读性的呢?

首先要说一下可读性的概念。什么是可读性?可读性可以定义为理解一段代码的意图所需要的时间。时间越短可读性越好。

而重复会造成我们看到同一个概念还要继续思考一下才明白这是同一个概念。如果重复的形式是内容完全相同那么还好一下,如果是结构重复,甚至是语义重复,那么我们理解代码段的意图耗费的时间就更长了,如下图所示。


所以不管是在产品代码还是测试代码中我们都要尽最大努力去掉重复。

条件测试

待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容