JUnit4 使用進階一

一、簡介

JUnit是一個Java語言的單元測試框架。它由Kent Beck和Erich Gamma建立,逐漸成爲源於Kent Beck的sUnit的xUnit家族中爲最成功的一個。來自JUnit的體驗對測試驅動開發是很重要的,所以一些 JUnit知識經常 和測試驅動開發的討論融合在一起。可以參考Kent Beck的 《Test-Driven Development: By Example》一書(有中文版和影印版)。

本文,對JUnit4的下載安裝、基本測試方法及運行,配合實例進行基礎介紹。幫助讀者看完之後,就可以將JUnit4運用到單元測試中去。而JUnit4的更多功能可以參考後續的JUnit4使用進階二

二、下載安裝

JUnit當前版本是4.11,如果,你的工程是使用Maven進行管理構建,那麼只需要在工程的pom.xml文件中添加如下依賴信息:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

否則,在你的測試classpath中放置下面兩個jar:junit.jarhamcrest-core.jar,這兩個jar可以在這裏找到並下載。

三、一個簡單的模版

package com.example.foo;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Foo}.
 *
 * @author [email protected] (John Doe)
 */
@RunWith(JUnit4.class)
public class FooTest {

    @Test
    public void thisAlwaysPasses() {
    }

    @Test
    @Ignore
    public void thisIsIgnored() {
    }
}

這個模版是不是很簡單!

  • 需要測試的方法,只需要通過@Test標註出來就可以了。

  • 測試類只需要添加@RunWith註釋,不再需要繼承junit.framework.TestCase這個父類了。

當然了,JUnit4還提供了很多特色功能,後面我們會一一介紹。

四、運行測試

  • 在命令行,對寫好的測試類,進行測試很簡單,只需要下面一個命令就ok了:

      java -cp .:/usr/share/java/junit.jar org.junit.runner.JUnitCore [test class name]
    
  • 在IDE裏面進行測試就更簡單了,NetbeansEclipse 和 IntelliJ Idea都內置了圖形化的測試運行器。

測試類如何運行,是由@RunWith註釋來決定。JUnit4當前版本的默認基本測試方式是JUnit4.class。除此之外,還有一些其他特殊的,我們將在JUnit4 使用進階四中進行介紹。

五、JUnit4的核心之一是斷言

JUnit4框架主要是通過斷言來判斷運行結果正確與否,針對Java的原生類型(long,boolean,float...)或者Objects或者數組,JUnit都提供了對應的斷言方法。

下面,我們先來看個例子:

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.both;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.junit.matchers.JUnitMatchers.everyItem;
import static org.junit.matchers.JUnitMatchers.hasItems;

import java.util.Arrays;

import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;

public class AssertTests {
  @Test
  public void testAssertArrayEquals() {
    byte[] expected = "trial".getBytes();
    byte[] actual = "trial".getBytes();
    org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
  }

  @Test
  public void testAssertEquals() {
    org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);
  }

  @Test
  public void testAssertFalse() {
    org.junit.Assert.assertFalse("failure - should be false", false);
  }

  @Test
  public void testAssertNotNull() {
    org.junit.Assert.assertNotNull("should not be null", new Object());
  }

  @Test
  public void testAssertNotSame() {
    org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());
  }

  @Test
  public void testAssertNull() {
    org.junit.Assert.assertNull("should be null", null);
  }

  @Test
  public void testAssertSame() {
    Integer aNumber = Integer.valueOf(768);
    org.junit.Assert.assertSame("should be same", aNumber, aNumber);
  }

  // JUnit Matchers assertThat
  @Test
  public void testAssertThatBothContainsString() {
    org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));
  }

  @Test
  public void testAssertThathasItemsContainsString() {
    org.junit.Assert.assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
  }

  @Test
  public void testAssertThatEveryItemContainsString() {
    org.junit.Assert.assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
  }

  // Core Hamcrest Matchers with assertThat
  @Test
  public void testAssertThatHamcrestCoreMatchers() {
    assertThat("good", allOf(equalTo("good"), startsWith("good")));
    assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
    assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
    assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
    assertThat(new Object(), not(sameInstance(new Object())));
  }
}

注意:

  1. assertEqualsassertSame 的區別在於,前者是調用期待值equals方法來判斷真實值(expected.equals(actual)),而後者是判斷期待值真實值是否是同一個對象(expected == actual)。
  2. 例子中,這樣調用org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);是不是覺得有點累,沒關係,我們可以通過JDK1.5中的靜態導入(import static)來簡化這一切,看下面的代碼。

簡化後的例子:

package tangzhi.mytest;

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.both;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.junit.matchers.JUnitMatchers.everyItem;
import static org.junit.matchers.JUnitMatchers.hasItems;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;

public class AppTest {
  @Test
  public void testAssertArrayEquals() {
    byte[] expected = "trial".getBytes();
    byte[] actual = "trial".getBytes();
    assertArrayEquals("failure - byte arrays not same", expected, actual);
  }

  @Test
  public void testAssertEquals() {
    assertEquals("failure - strings not same", 5l, 5l);
  }

  @Test
  public void testAssertFalse() {
    assertFalse("failure - should be false", false);
  }

  @Test
  public void testAssertNotNull() {
    assertNotNull("should not be null", new Object());
  }

  @Test
  public void testAssertNotSame() {
    assertNotSame("should not be same Object", new Object(), new Object());
  }

  @Test
  public void testAssertNull() {
    assertNull("should be null", null);
  }

  @Test
  public void testAssertSame() {
    Integer aNumber = Integer.valueOf(768);
    assertSame("should be same", aNumber, aNumber);
  }

  // JUnit Matchers assertThat
  @Test
  public void testAssertThatBothContainsString() {
    assertThat("albumen", both(containsString("a")).and(containsString("b")));
  }

  @Test
  public void testAssertThathasItemsContainsString() {
    assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
  }

  @Test
  public void testAssertThatEveryItemContainsString() {
    assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
  }

  // Core Hamcrest Matchers with assertThat
  @Test
  public void testAssertThatHamcrestCoreMatchers() {
    assertThat("good", allOf(equalTo("good"), startsWith("good")));
    assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
    assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
    assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
    assertThat(new Object(), not(sameInstance(new Object())));
  }
}

在上面的代碼中,我們靜態導入了import static org.junit.Assert.*;後,在測試類中就可以直接使用assertEquals這些方法了。是不是很方便!

常用的斷言方法有:

assertTrue([message ,] condition);
assertFalse([message ,] condition);
assertEquals([message ,] expected, actual);
assertNotEquals([message ,] first, second);
assertArrayEquals([message ,] expecteds, actuals);
assertNotNull([message ,] object);
assertNull([message ,] object);
assertSame([message ,] expected, actual);
assertNotSame([message ,] unexpected, actual);
assertThat([message ,] actual, matcher);

從上面的列表可以看出:

  1. 大部分斷言方法的參數順序都是:[Message] 期待值 真實值,第一個參數是個可選字符串,出錯時的描述信息。第二個參數是期待值,第三個參數是真實值。

  2. 只有一個斷言方法assertThat的參數順序例外:可選的出錯提示信息、真實值和一個Matcher對象。它參數中的期待值與真實值的順序,與其他斷言方法的參數順序正好相反。

這個assertThat方法是斷言中的神器,後面我們會在進階三介紹!敬請期待吧!

六、小結

前面我們介紹了JUnit4的基本知識。至此,你已經可以使用JUnit4進行代碼測試了。如果你想知道更多信息,可以繼續看看JUnit 使用進階二

轉自:http://www.blogways.net/blog/2013/04/15/junit-usage-1.html

發佈了25 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章