HIT-2022年春季学期《软件构造》Lab 2实验心得

 

2022年春季学期计算学部《软件构造》

课程Lab2实验心得

目录

1. 实验目标概述

2. 实验环境配置

3. 实验过程

3.1 Poetic Walks

3.1.1 Get the code and prepare Git repository

3.1.2 Problem 1: Test Graph

3.1.3 Problem 2: Implement Graph

3.1.4 Problem3: Implement generic Graph

3.1.5 Problem4: Poetic walks

3.1.6 使用Eclemma检查测试代码覆盖度

3.2 Re-implement the Social Network in Lab1

3.2.1 FriendshipGraph类

3.2.2 Person类

3.2.3 客户端main()

3.2.4 测试用例

​​​​​​​3.2.5 提交至Git仓库

​​​​​​​4. 实验过程的经验、教训、感想

​​​​​​​4.1 实验过程中的经验教训

​​​​​​​4.2 针对以下方面的感受


1. 实验目标概述

        本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象编程(OOP)技术实现 ADT。具体来说:

  • 针对给定的应用问题,从问题描述中识别所需的 ADT;
  • 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
  • 根据 ADT 的规约设计测试用例;
  • ADT 的泛型化;
  • 根据规约设计ADT的多种不同的实现;针对每种实现,设计其表示 (representation)、表示不变性(rep invariant)、抽象过程(abstraction function)
  • 使用OOP实现 ADT,并判定表示不变性是否违反、各实现是否存在表示泄露(rep exposure);
  • 测试 ADT 的实现并评估测试的覆盖度;
  • 使用 ADT 及其实现,为应用问题开发程序;
  • 在测试代码中,能够写出 testing strategy 并据此设计测试用例。
  • 2. 实验环境配置

Eclipse IDE for java Developers-2022-03

Eclipse Downloads | The Eclipse FoundationThe Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 415 open source projects, including runtimes, tools and frameworks.https://www.eclipse.org/downloads/Java SE 11.0.14

Javahttps://developer.oracle.com/java/GitHub Desktop

GitHub Desktop | Simple collaboration from your desktopSimple collaboration from your desktophttps://desktop.github.com/

EclEmma Java Code Coverage 3.1.3

3. 实验过程

该任务是实现一个图的模块,基于此实现GraphPoet类

实现Graph类的方法:add、set、remove、vertices、sources、targets;

3.1 Poetic Walks

        利用实现的Graph类,应用图的思想,实现GraphPoet类,如果输入的文本的两个单词之间存在桥接词,则插入该桥接词;若存在多个单一桥接词,则选取边权重较大者。

3.1.1 Get the code and prepare Git repository

        使用GithubDesktop,add,clone,导入eclipse

3.1.2 Problem 1: Test Graph<String>

 编写测试样例,并使用emptyInstance()方法编写GraphInstanceTest.java,测试代码覆盖度:

        静态测试本身不复杂,只要对于Graph提供的规约测试即可,对于graphInstance,只要将graph想象成一个黑盒,按照ADT规约去测试它就可以

3.1.3 Problem 2: Implement Graph<String>

        重写Graph里的方法,分别写出以点为基础的图和以边为基础的图

  • Implement ConcreteEdgesGraph

以边为基础实现,共包含以下两个部分:

EDGE{

  • Source:边的起始点
  • Target:边的终止点
  • Weight:边的权重
  • Edge:边本身,初始化上述三个成员变量
  • Checkrep:检查边权是否是正整数,始末点是否不同
  • SameEdge:判断是否出现相同的边
  • ToString:输出边的相关信息,方便测试和调试

}

ConcreteEdgesGraph{

  • Add:增加点
  • Set:增加边
  • Remove:删除点,并删除依赖的边
  • Vertices:返回vertices
  • Sources:返回起点集合
  • targets:返回终点集合
  • toString:输出图的信息
  • Set<L>vertices:点集
  • List<Edge<L>>edges:边集
  • CheckRep:检查有无空的点和边

}

测试结果

 覆盖度测试结果:

  • Implement ConcreteVerticesGraph

以点为基础实现,包含以下几两个部分

Vertex{

  • Sources:返回inedges
  • Targets:返回outedges
  • Setedge:添加一个新的边,存在则重新添加,不存在则加入新的边
  • RemoveEdge:删除边,不存在返回0
  • Thisvertex:存储这个点本身的名字
  • Inedges:指向该点的边集
  • Outedges:由该点指出的边集
  • Vertex:初始化标识
  • CheckRep出度入度都大于0,边权大于0

}

Concreteverticesgraph{

  • Add:增加一个点(若不同)
  • Set:增加一个边
  • Remove:删除相关的边
  • Sources:调用vertex类的即可
  • Targets:同上
  • List<vertex<L>>vertices:点集
  • Checkrep:点不能没有标识,边权大于0

}

测试结果:

 覆盖度

3.1.4 Problem3: Implement generic Graph<L>

        将每一个实例部分均修改,可以通过报错找到大部分位置,为Graph.empty()增加一个返回实例。

3.1.5 Problem4: Poetic walks

        给出一个语料库,根据这些文本生成一个单词图,并给定一个语句输入,自动补全语句中可能需要完善的部分每个不同的单词看做一个顶点,相邻的单词直接有一个有向边,检查长度为2的路的个数。划分多个等价类:两个单词不连接,有一个连接词,有多个连接词用文件输入单词,像lab1那样,用split分割为数组,依次增加点和边,若已有边则权重加一。处理时,检查相邻词汇之间长为2的路径,方法是一个点的sources和另一个的targets去比较即可

3.1.6 使用Eclemma检查测试代码覆盖度

 程序结构如下:

 

3.2 Re-implement the Social Network in Lab1

        这部分任务是用新的Graph类重写lab1中的Friendshipgraph,节点使用person类型,所以L即为Person。

3.2.1 FriendshipGraph类

  • Graph<Person>graph:调用Graph.empty生成一个新图
  • Addvertex:增加一个点
  • Addedge:增加一个边
  • Getdistance:利用深度优先搜索从起点搜索终点
  • 3.2.2 Person类

        给每个人建立一个Person对象,设置一个私有的姓名

3.2.3 客户端main()

        和lab1中一样的方式进行测试,测试四个添加和不同人之间的距离是否正确即可

​​​​​​​3.2.4 测试用例

        这里依然采用和lab1中一样的示例,但由于这里我保留了扩展成有向图的函数但按照无向图去构造,所以增加一个新的点来测getinstance能否正常返回-1

用例如下:

 

​​​​​​​3.2.5 提交至Git仓库

Git add*.doc

Git commit -m “finish P2”

Git push

代码结构如下:

​​​​​​​4. 实验过程的经验、教训、感想

​​​​​​​4.1 实验过程中的经验教训

        在实验中,我一开始没有充分结合实验课和知识课,导致对于实验内容了解不足,于是做了很多前期准备仍然没有抓手,对于ADT的规约等部分不是很熟练,应该先掌握理论之后再尝试进行实战,在实验中我感悟到了ADT的强大之处,假使ADT不是我编写,我也可以为其编写充分的测试样例,这使得协同作业很方便。

​​​​​​​4.2 针对以下方面的感受

  • 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?

        面向ADT编程更加抽象也更加实用,只要双方约定好接口的格式就可以很容易相互协作分工,且ADT能力更强,体系更大,使用更舒服。

  • 使用泛型和不使用泛型的编程,对你来说有何差异?

        使用泛型的编程更抽象,更强调代码前后的一致性,并且适用程度更高,使用范围更广,不使用泛型的编程更直接具体。

  • 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?

        在给出ADT的规约之后,根据规约去书写测试用例可以让测试者更容易考虑的完全,测试用例覆盖度更高,也能增加团队协作的效率,只需要根据给出的接口进行测试,不依赖先写好ADT,但由于ADT也是由我自己编写,还是会先想好怎么写再写测试用例,并不完全做得到黑和测试

  • P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?

        复用可以减少开发成本,效率更高

  • P3要求你从0开始设计ADT并使用它们完成一个具体应用,你是否已适应从具体应用场景到ADT的“抽象映射”?相比起P1给出了ADT非常明确的rep和方法、ADT之间的逻辑关系,P3要求你自主设计这些内容,你的感受如何?

已经开始有了一些适应,先写Spec是很重要的,自主设计ADT是很有趣的,oop语言虽然不是每个小细节都像C语言那样由自己所打磨,但自己设计一个如臂指使的ADT还是很有成就感的,设计的过程其实更难,比实现更重要。

  • 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?

        这些工作可以提高程序的健壮性,也可以让别人拿到你的代码之后能更快的理解或和你协同工作。

        我愿意这么做,对于一个体量较大的工程,前端,后端,软件测试员需要这样的方式去协调工作,这很高效。

  • 关于本实验的工作量、难度、deadline。

        工作量和难度都适中,主要是以体会设计ADT的过程和测试过程为主,ddl较晚,这可能使得实验三时间不足(与密集的考试复习完全重合,强烈建议协调)

  • 《软件构造》课程进展到目前,你对该课程有何体会和建议?

        基础理论内容比较多,完全可以增加学时,这门课实用性很强,应该占有更大的学分,实验课将理论和编程结合,每周都有,但两三周作为一个整体,和知识契合度有所下降,希望可以拆散开来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值