软件构造心得(一)

  上周温习了软件构造的知识,有了一些感触。

 

软件测试(一)

  下面将讲述关于Java中的自动单元测试工具Junit的使用。

  Junit,用于自动单元测试,只需要在Junit测试文件中编写关于测试函数功能的代码,它会自动比较运行结果和期望答案之间的差别,从而完成测试。

  而在Junit之中,比较重要的是对于assert及其类似的各种断言语句的使用(它的作用是用于判断函数运行结果是否达成预期)。

  

  对于org.junit.Assert包中的各种方法,第一个参数一般都是输出信息message,指的是预测(断言)失败后输出的信息。 对于断言,如果断言成功,则继续执行程序;否则,输出错误信息message并抛出AssertionError异常(结束程序)。

  下面讲一下关于Assert包中的各类方法(主要为其断言的说明):

  一、assertTrue和assertFalse

  assertTrue/assertFalse(String message, boolean bool), 它们都是用于断言布尔类型真假的方法,assertTrue是断言bool为真,assertFalse是断言bool为假。

  例子:

 

//Queue类是队列,其中empty()方法是判断队列是否为空,空的话输出true


@Test
public void queueEmpty() {
    Queue q=new Queue();
    assertTrue("The queue is not empty", q.empty());//断言为空,否则错误输出信息
}

 

  二、assertNull和assertNotNull

  assertNull/assertNotNull(String message, Object object), 它们都用于断言object是否为空,assertNull断言object为空,assertNotNull相反。

  例子:

//该代码应该不会抛出异常,正常执行;若是assertNotNull则会抛出异常,输出错误信息,结束程序

@Test
public void assertNullTest() {
    assertNull("Not Null", new Object());
}

  三、assertSame和assertNotSame

  assertSame/assertNotSame(String message, Object expect, Object actual),它们都用于断言expect和actual是否为同个对象。assertSame断言expect和actual为同个对象;assertNotSame相  反。

  例子:

//该代码不会抛出异常,因为生成的两个对象不是同个对象(内存地址不同);若为assertSame则会抛出异常

@Test
public void assertSameTest() {
    assertNotSame("Same Object", new Object(), new Object());
}

  四、assertEquals和assertNotEquals

  assertEquals/assertNotEquals(String message, Object expect, Object actual),它们用于断言expect和actual是否相等。assertEquals断言expect和actual相等,assertNotEquals相反。

  (assertEquals在基本数据类型中,也有第四个参数delta,只要expect和actual误差在delta内即可成功断言相等)

  例子:

//该代码不会抛出异常;若为assertNotEqual则会抛出异常且输出“Wrong Answer ”

@Test
public void assertEqualsTest() {
    String str=new String("newbee");
    assertEqual("Wrong Answer", str.toUpperCase(), "NEWBEE");
}

  

  tips:  如何区分assertSame和assertEqual?

  assertSame基于的是“==”运算符,而assertEqual基于的是equals()方法。

  对于“==”运算符,首先判断它们的对象的数据类型是否一致。然后,判断它们内存地址是否相同(这与公共池、堆相关)。数据在常量池和堆取决于创建类的方式,以下以String为例子:

String s1 = "newbee";              // String 直接创建
String s2 = "newbee";              // String 直接创建
String s4 = new String("newbee");   // String 对象创建
String s5 = new String("newbee");   // String 对象创建

  String的直接创建会创建在公共池中,所有直接创建的大小相同的变量都会指向指向公共池中的同一字符串(即地址相同)。这里可以理解为公共池类似一个集合,每个元素只出现一次,因此直接创建若元素相同则指向地址相同(指向集合中的这个元素)。

  而String的对象创建则会创建在堆中,对于每一个对象创建所指向的地址都不同,就算元素相同,也视作创建一个新副本。这里可以理解为堆类似一个可重集,每个元素可出现多次,因此每一次对象创建则往可重集中加入一个新的元素并让该变量指向它。

  而对于equals()方法,若对象中没有重载equals则按照“==”运算符来计算;否则就按照重载的equals方法来判断。

 

  五、assertArrayEqual和assertArrayNotEqual

  跟assertEqual类似,只不过expect和actual的参数由Object换成了数组,断言的是整个数组是否相等。

 

  六、assertThat

  以上的几种方法特别是assertEquals是主要用来断言的方法,主要比对的是输出结果是否与期望相等。但对于测试某些输出格式不同但是结果大致相同的函数,并且它们的输出较为复杂,此时用以上方法就要一个一个地去构造期望答案。而assertThat能只用它自身这一种方法,结合 Hamcrest 提供的匹配符,完成所有的测试思想,而且也有许多很方便的地方。

  主要的匹配符以及其用法如下:

//字符串
//startsWith/endsWith(String str): 以str开头/结尾
assertThat("myname", endsWith("me"));
assertThat("myname", startsWith("my"));
//containsString(String str): 包含str
assertThat("myname", containsString("ynam"));
//equalTo(String str): 与str相等
assertThat("myname", equalTo("myname"));
//equalToIgnoringCase(String str): 忽略大小写比较
assertThat("myname", equalToIgnoringCase("MyName"));
//isOneOf: 是否为其中之一
assertThat("A", isOneOf("A", "B"));

//数值
//closeTo(float actual, float delta): 在delta误差范围内是否与actual相等
assertThat(3.25, closeTo(3,0.5));
//comparesEqualTo: 是否相等
assertThat(0, comparesEqualTo(0));
//greaterThan(OrEqualTo)、lessThan(OrEqualTo): 是否大于(等于)、小于(等于)
assertThat(114514, greaterThan(1926));

//逻辑
//allOf: 相当于&&,满足所有条件
assertThat("ABC", allOf(startsWith("AB"), containsString("C"))); 
//anyOf: 相当于||,满足其中至少一个条件
assertThat("ABC", anyOf(startsWith("A"), containsString("D"))); 
//both: 两个都满足
assertThat("ABC", both(containsString("A")).and(containsString("BC"))); 
//either: 两者至少满足一个
assertThat("ABC", either(containsString("A")).or(containsString("CDE")))
//hasItem是否有元素(一个)、hasItems是否有元素(多个)
assertThat(Arrays.asList("ABC", "D", "EFG"), hasItems("D", "ABC"));
//is: 是否一致(相等)
assertThat("myname", is("myname"));
//not: 取非(是否为否/不一致)
assertThat("me", is(not("you")));

  还有其他的语法可以上网查询(以上只是我认为相对多用且重要的语法)。

 

posted @ 2022-06-06 17:01  立志马院的newbee  阅读(74)  评论(0编辑  收藏  举报