对实验二的编程模式的总结(软构)

测试优先的编程模式

首先实验二采用了测试优先的编程模式,下面先复习一下测试优先的编程模式。首先是流程:

首先写规约

在IDEA中,敲/**按回车生成的就是规约,如图:
在这里插入图片描述

规约里要写的是方法或类的功能,但一般不写实现方法,这样程序员就有用任何方法实现的自由,以后再改实现也不需要去改规约。
规约里可以先写一段话大致描述功能,然后可以使用@param标签描述参数,注意直接写参数名,不写类型;可以使用@return 参数描述返回值,一个例子:
在这里插入图片描述
给方法写好spec后,在别处使用这个方法时,鼠标悬停在这个方法处就可以看到我们写的规约了:
在这里插入图片描述
一个要注意的地方是如果某个类中的一个方法是override它父类中的方法,是不需要重新写规约的,因为父类中写过规约了。

写测试

这里没什么可细说的了,为每个输入的等价类都加一些测试数据。实验二中涉及到了一个实验一中没有的问题:怎么实现测试程序能否正确抛出异常。我开始写这部分的时候不知道后面上课会讲,就自己写了一种比较丑陋的实现方法。
首先是我的丑陋的实现方法:

		try{
            Edge<String> e2= new Edge<String>("c","d",-1);
            //System.out.println("nb");
            flag=1;//fail直接写在这不管用,就算不中断也不会显示失败,可能是fail在try里不管用,设一个flag然后fail写try外可以,这时如果没中断flag就变成1,下面就会调用fail
        }
        catch (AssertionError error){
        }
        if(flag==1)fail();

就是利用了JUnit中的fail()函数,该函数强制令测试失败。如果图中try的第一条语句抛出异常,就会直接进入catch,try里面后面的语句就不会执行,所以下面的判断就不会进入;如果第一条语句没有被执行,相应的判断就会进入,fail()函数使测试强制失败。我实际实现中遇到fail()写在try语句里没有用的问题,目前还不知道为什么,详见注释。
然后是上课讲的方法:

@Test(expected=AssertionError.class)

在test标签多写上这些东西就好,这句话的意思是这个方法如果抛出了AssertionError这个异常就测试成功,否则测试失败。但是我想到一个这个方法的缺点就是如果这个方法里有多条可能抛出异常的语句时它不能知道这个异常到底是那条语句抛出的。

实现,测试,修改,再测试

这一步没啥好说的。

测试优先的编程模式的好处

通过写测试用例,可以理解、修正、完善spec的设计。
规格说明本身也可能是错误的 - 不正确,不完整,模 棱两可,缺失边界情况。
测试优先可以尽早发现设计问题,避免浪费时间做错误的事情。
错误越早发现越容易纠正,通过测试优先,我们可以更深入和更早的理解需求和设计,更早的暴露需求和设计的问题,同时可以确保程序的可测试性。

程序实现部分的流程

首先是测试部分的流程,对应于测试优先模式中的第二步。
首先写test strategy:
在这里插入图片描述
这个没有具体的格式要求,可以写写你的例子涵盖了那些情况,再写写你的测试原则,比如测试ADT时,
测试creators, producers, and mutators:调用observers来观察这些
operations的结果是否满足spec;
▪ 测试observers:调用creators, producers, and mutators等方法产生或 改变对象,来看结果是否正确。
▪ 风险:如果被依赖的其他方法有错误,可能导致被测试方法的测试结果失效
然后写测试代码,没什么好说的。

ADT 实现流程

1.首先定义fields,就是每个一个ADT类中有哪些成员变量,这里建议好好想想再写,fields定义的不好,后面的实现会很麻烦。
2.然后是写Abstraction function,Representation invariant,Safety from rep exposure。RI是一些限制条件,通过这些条件限制表示空间,也是AF的定义域,是一些对fields中变量和变量之间的约束。AF是抽象函数,将RI限制得到的每种表示映射到一个抽象含义。Safety from rep exposure就是讲一下你是怎么防止表示泄露的,一般的方法有成员变量私有化,方法返回不可变类型,返回可变类型的observer使用防御式拷贝等。一个例子:

	// Abstraction function:
    // AF(source,target,weight)->一条从source指向target,权重为weight的边
    // Representation invariant:
    // weight>0
    // Safety from rep exposure:
    // 每一个field都是private的,且source,target,weight都是immutable的

3.写构造器,注意调用checkRep()
4.写checkRep(),功能是检查RI,在每个creator,producer,mutator返回前调用,observer理论上不用,但也可以写上。一般实现方法是使用一堆assert语句。
5.可能需要重写equals()和hashcode()方法,将在下一篇文章讨论
6.实现各种其他方法。
7.重写toString(),因为默认的toString输出的非常丑陋,所以我们自己定义的ADT类一般要重写toString()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值