JUnit in java 真正的測試用例實戰!

單元測試基礎

當今軟件測試十分盛行時,本人通過項目實踐和個人親身體會淺談單元測試,本人一直堅持“用代碼說話的原則”,同時也希望個人能給出寶貴意見,共同探討、共同進步,爲中國軟件事業有更大的發展共同奮鬥!

最早我們項目組開發的項目時,寫代碼都是從底層一直寫到表現層到jsp,然後開發人員在web層調試頁面,近乎98%都會報一大堆exception,然後再在代碼中加斷點一步一步查到底哪一層代碼出現問題……,比較好點做法就是在各個類中加上main方法測試,但總體很不理想,給web層開發人員的調試和質量控制人員帶來繁重的工作壓力;使用單元測試後,針對每一個方法都做嚴格的把關,大大減少調試的時間;同時質量控制人員返回過來的bug少了近60%,現在對于開發人員寫測試用例非常熟練,並且本人根據實際情況對測試用例做了點小小改動(這部分主要在後面代碼中詳述),帶來很好的效果!

單元測試到底給實際開發帶來什麽好處那?

(1) (1)首先對于開發人員來說大大減少調試工作的時間,同時也規範了對于代碼安全管理(我們知道那些方法是可以調用的);

(2) (2) 對于整個項目來說,有了完整的測試,保證項目最後交付測試有了可靠依據;

(3) (3)對于測試人員大大減少bug的反饋;

(4) (4)對于項目經理整個項目達到很好的可控;

(5) (5)最主要的完整的單元測試給後期維護人員帶來很大的便捷!

單元測試好處可能還有很多,但本人只能理解和感悟這麽多,希望觀者補充!

單元測試配置:

我將使用eclipse+myEclopse給大家介紹關于JUNIT的環境的簡單配置;右鍵點擊項目選擇“屬性”,在彈出窗口中到環境變量中添加junit.jar包,這樣下一步我們就可以進行單元測試了;

JUnit in java 真正的測試用例實戰!

使用eclipse快速開發test Case:

如下圖:右鍵選擇你要測試的類,在新建中點擊“JUnit 測試用例”,

JUnit in java 真正的測試用例實戰!

彈出對話框,配置測試名稱和根目錄,添加注釋等,再點擊“下一步”到下圖:

JUnit in java 真正的測試用例實戰!
選擇你要測試類中的方法,點擊完成!便生成測試類的基本框架,如下代碼,我們以對一個DAO類測試爲例:

/**//*

* Copyright reserved 2005 by XXXXCo. Ltd.

* Author:Fu wei Date:2006-9-4

*/

import junit.framework.TestCase;

/** *//**

* @author Fu wei

*/

public class OrgTypeDAOTest extends TestCase ...{

/** *//**

* @param arg0

*/

public OrgTypeDAOTest(String arg0) ...{

super(arg0);

}

/**//*

* @see junit.framework.TestCase#setUp()

*/

protected void setUp() throws Exception ...{

super.setUp();

}

/**//*

* @see junit.framework.TestCase#tearDown()

*/

protected void tearDown() throws Exception ...{

super.tearDown();

}

/** *//**

* 主函數

* @param args

*/

public static void main(String[] args)...{

TestRunner.run(OrgTypeDAOTest .class);

}

/** *//**

* {@link OrgTypeDAO#getOrgTypeList()} 的測試方法。

*/

public final void testGetOrgTypeList() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#insertOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的測試方法。

*/

public final void testInsertOrgTypeInfo() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#deleteOrgTypeInfo(java.lang.String)} 的測試方法。

*/

public final void testDeleteOrgTypeInfo() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#updateOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的測試方法。

*/

public final void testUpdateOrgTypeInfo() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#getOrgTypeInfoById(java.lang.String)} 的測試方法。

*/

public final void testGetOrgTypeInfoById() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#isRepeatOrgTypeInfo(java.lang.String)} 的測試方法。

*/

public final void testIsRepeatOrgTypeInfoString() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#isRepeatOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的測試方法。

*/

public final void testIsRepeatOrgTypeInfoOrgTypeVO() ...{

fail("尚未實現"); // TODO

}

/** *//**

* {@link OrgTypeDAO#getFlatOrgIdByName(java.lang.String)} 的測試方法。

*/

public final void testGetFlatOrgIdByName() ...{

fail("尚未實現"); // TODO

}

}

JUnit單元測試一共要注意一下幾點:

(1)import junit.framework.TestCase 和 junit.textui.TestRunner;

(2)繼承junit.framework.TestCase ;

(3)自行添加一個main方法 中調用TestRunner.run(測試類名.class);

(4)有一個調用super(String)的構造函數;

以上都是JUnit必有的特征,除以上外,我們發現有許多以test開頭的方法,而這些方法正是我們要測試的方法,Junti測試其實采用的是斷言的方式,只要我們在所有test開頭中的方法對數據添加斷言方法,同時提供很多斷言的方法,

常用斷言方法

assertEquals("失敗提示信息","期望數據","測試數據")

斷言獲取數據是否與所期望的相等

assertNotNull("失敗提示信息","測試數據")

斷言獲取數據不爲null,否則提示錯誤

assertNull("失敗提示信息","測試數據")

斷言獲取數據是爲null,否則提示錯誤

assertTrue("失敗提示信息",測試數據blooean值)

斷言獲取數據是否爲ture,否則提示錯誤

fail("失敗提示信息");

此方法一般放到異常處,遇到此方法,測試將停止!

assertSame("失敗提示信息","期望數據","測試數據")

斷言獲取數據是否與所期望的相同

當我們寫完所有方法策略後,JUnit測試如下圖:

在方法頁面中點擊右鍵在“調試方式”或“運行方式”中點擊“JUnit 測試”,就運行測試類!

JUnit in java 真正的測試用例實戰!

在執行測試類時,執行的大概過程:

(1)先執行構造方法public OrgTypeDAOTest(String arg0) ;

(2)再執行初始化數據方法protected void setUp() ;

(3)再執行以test開頭的測試方法;

(4)最後執行protected void tearDown()方法清理對象;

如果測試失敗或者錯誤,將會顯示一個紅色的亮條;如果測試通過將顯示綠色亮條;如下圖

JUnit in java 真正的測試用例實戰!
這樣就把一個整個單元測試操作例子演示完成!

可能對于一個測試類中有多個方法要測試,對于後面看著的確有些困難,因此,我對上測試類進行簡單的調整,如下代碼:

import junit.framework.TestCase;

import junit.textui.TestRunner;

import com.zhjy.mock.SpringMock;

/** *//**

* 舉例測試類

*/

public class OrgTypeDAOTest extends TestCase ...{ //(1)繼承TestCase

//private OrgTypeDAO orgTypeDAO;

//private OrgTypeVO orgTypeVO;

//private String id ;

/** *//**

* 構造方法

* @param arg0

*/

public OrgTypeDAOTest(String arg0) ...{

super(arg0);

}

/**//* 初時化方法

* @see junit.framework.TestCase#setUp()

*/

protected void setUp() throws Exception ...{

super.setUp();

//測試初始話數據調用類 orgTypeDAO和 封裝數據的對象orgTypeVO

}

/**//* 執行完清理方法

* @see junit.framework.TestCase#tearDown()

*/

protected void tearDown() throws Exception ...{

//清空 對象 ;==null

//orgTypeDAO =null;

//orgTypeVO =null;

super.tearDown();

}

/** *//**

* 主函數

* @param args

*/

public static void main(String[] args)...{

TestRunner.run(OrgTypeDAOTest.class);

}

/** *//**

* 測試方法

* Test method testOrgTypeInfo

*/

public void testOrgTypeInfo() ...{

//添加

String id = insertOrgTypeInfo();

//列表

orgTypeList();

//修改

updateOrgTypeInfo(id);

//查詢

selectOrgTypeInfoById(id);

//校驗

iExistOrgByOrgTypeId(id);

//測試是否重複數據方法(add)

isRepeatOrgTypeInfo(orgTypeVO.getName(),"");

//獲取數據方法(根據名稱)

selectOrgTypeIdByName(orgTypeVO.getName());

//刪除

deleteOrgTypeInfo(id);

}

/**//*

*添加初始數據

*/

private void setOrgTypeVOAddInfo() ...{

orgTypeVO.setName("add中海測試");

orgTypeVO.setDescription("add中海測試");

orgTypeVO.setStatus("1");

}

/**//*

*添加初始數據

*/

private void setOrgTypeVOUpdateInfo() ...{

//orgTypeVO.setId(id);

orgTypeVO.setName("add中海測試");

orgTypeVO.setDescription("update中海測試");

orgTypeVO.setStatus("1");

}

/**//*

* 新增方法

* Test method for {@link OrgTypeDAO#insertOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public String insertOrgTypeInfo() ...{

setOrgTypeVOAddInfo();

String id = null;

try...{

id = orgTypeDAO.insertOrgTypeInfo(orgTypeVO);

}catch(Exception e)...{

fail("添加通用組織機構失敗!");

}

return id;

}

/**//*

* 更新方法

* Test method for {@link com.zhjy.mltx.dao.OrgTypeDAO#updateOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public void updateOrgTypeInfo(String id) ...{

setOrgTypeVOUpdateInfo();

orgTypeVO.setId(id);

try...{

orgTypeDAO.updateOrgTypeInfo(orgTypeVO);

}catch(Exception e)...{

assertTrue("修改通用組織機構失敗!", false);

}

//查詢

orgTypeVO = orgTypeDAO.selectOrgTypeInfoById(id);

assertEquals("修改通用組織機構失敗!", orgTypeVO.getDescription(), "update中海測試");

}

/**//*

* 獲取數據方法(主健)

* Test method for {@link OrgTypeDAO#selectOrgTypeInfoById(java.lang.String)}.

*/

public void selectOrgTypeInfoById(String id) ...{

orgTypeVO = orgTypeDAO.selectOrgTypeInfoById(id);

assertTrue("無法查看一條通用機構名稱信息!",orgTypeVO != null);

assertEquals("添加通用組織機構失敗!", orgTypeVO.getName(), "add中海測試");

assertEquals("修改通用組織機構失敗!", orgTypeVO.getDescription(), "update中海測試");

}

/**//*

* 測試此通用組織機構是否被引用

* Test method for {@link OrgTypeDAO#iExistOrgByOrgTypeId(java.lang.String)}.

*/

public void iExistOrgByOrgTypeId(String id) ...{

boolean isfalse;

try ...{

isfalse = this.orgTypeDAO.iExistOrgByOrgTypeId(id);

assertFalse("通用組織機構校驗錯誤!",isfalse);

} catch (DataAccessException e) ...{

assertTrue("通用組織機構數據操作錯誤!!",false);

} catch (ObjectNotFoundException e) ...{

assertTrue("id is null!!",false);

}

}

/**//*

* 刪除

* Test method for {@link OrgTypeDAO#deleteOrgTypeInfo(java.lang.String)}.

*/

public void deleteOrgTypeInfo(String id) ...{

this.orgTypeDAO.deleteOrgTypeInfo(id);

orgTypeVO = this.orgTypeDAO.selectOrgTypeInfoById(id);

assertNull("刪除通用組織機構失敗!", orgTypeVO);

}

/**//*

* 獲取數據方法(根據名稱)

* Test method for {@link OrgTypeDAO#selectOrgTypeIdByName(java.lang.String)}.

*/

public void selectOrgTypeIdByName(String name) ...{

String orgtypeid = orgTypeDAO.selectOrgTypeIdByName(name);

//assertEquals(orgtypeid, id);

assertNotNull("未查出來通用組織機構ID!",orgtypeid);

}

/**//*

* 測試是否重複數據方法

* Test method for {@link OrgTypeDAO#isRepeatOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public void isRepeatOrgTypeInfo(String name,String id) ...{

//setOrgTypeVOUpdateInfo();

OrgTypeVO orgtypetest = new OrgTypeVO();

orgtypetest.setId(id);

orgtypetest.setName(name);

boolean isTrue = orgTypeDAO.isRepeatOrgTypeInfo(orgtypetest);

//assertEquals("通用組織機構錯誤數據",isTrue, false);

assertTrue("通用組織機構錯誤數據", isTrue);

}

/**//*

* 列表方法

* Test method for {@link com.zhjy.mltx.dao.OrgTypeDAO#orgTypeList()}.

*/

public void orgTypeList() ...{

List list = orgTypeDAO.orgTypeList();

assertNotNull("無法獲取通用機構名稱列表list is null!",list);

}

}

處理過程:

(1)把所有以test開頭的方法中的方法名稱前的test去掉(例如把testOrgTypeList()改爲orgTypeList()方法);

(2)同時添加一個以test開頭的方法,並調用測試方法;這樣做主要是因爲執行測試時JUnit(除本身特有的方法出外)只執行以test爲開頭的方法;

(3)同時大家注意到我還把測試初始數據放到兩個private方法中private void setOrgTypeVOAddInfo()和private void setOrgTypeVOUpdateInfo()方法中供調用;

大家可能認爲很簡單,就是這樣簡單的改動帶來很大的方便,大家是否注意到,我以後運行測試用例時,只關心public void testOrgTypeInfo() 方法就行了,因爲只要各個方法的斷言策略定制完成,一般就不會再改動,因此,後期的回歸測試還是驗收測試,縮小了我們對測試的關注點,同時對後面寫 test suite構建整體測試帶來極大方便性!其中的好處相信只有使用才能體會!

說到這,就此暫告一段落!由于時間倉促,書寫不規範和關于任何問題處敬請指出,相互探討,後面將討論《單元測試在整個項目中的整體構建》,謝謝!後續!

測試驅動的開發系列 第二部分:用JUnit測試Java類
測試驅動的開發系列 第二部分:用JUnit測試Java類Test_Driven Development Series Part I:Testing Java Classes with JUnitBy Wellie Chao January 2004 一、簡介(Introduction) 看到這兒你應該已經知道爲什麽測試...查看完整版>>測試驅動的開發系列 第二部分:用JUnit測試Java類
 
Pragmatic Unit Testing in Java with JUnit 書評
書評 Pragmatic Unit Testing in Java with JUnit 看這本書時候正好在做一個java的項目,正好可以把書中的內容應用到項目中。這本書的作者是Andy Hunt和Dave Thomas。名著《The Pragmatic Programmer》正是出自他們之...查看完整版>>Pragmatic Unit Testing in Java with JUnit 書評
 
用JUnit框架實現Java單元測試
用JUnit框架實現Java單元測試
  隨著軟件項目的逐漸增大,軟件測試在軟件開發中的地位顯得越來越重要。假如軟件項目沒有良好的測試流程,隨著系統的增大,無論項目治理人員還是軟件開發人員都會對項目的前景失去信心,甚至會對項目的目標産生分...查看完整版>>用JUnit框架實現Java單元測試
 
Java標准單元測試庫 JUnit 4 搶先看
  JUnit 是 Java? 語言事實上的 標准單元測試庫。JUnit 4 是該庫三年以來最具裏程碑意義的一次發布。它的新特性主要是通過采用 Java 5 中的標記(annotation)而不是利用子類、反射或命名機制來識別測試,從而簡化...查看完整版>>Java標准單元測試庫 JUnit 4 搶先看
 
用JUnit框架實現Java單元測試
用JUnit框架實現Java單元測試
  隨著軟件項目的逐漸增大,軟件測試在軟件開發中的地位顯得越來越重要。假如軟件項目沒有良好的測試流程,隨著系統的增大,無論項目治理人員還是軟件開發人員都會對項目的前景失去信心,甚至會對項目的目標産生分...查看完整版>>用JUnit框架實現Java單元測試
 
Java開源測試工具JUnit簡介
  1.簡介  在一篇早些的文章(請參見Test Infected: Programmers Love Writing Tests, Java Report, July 1998, Volume 3, Number 7)中,我們描述了如何使用一個簡單的框架來編寫可重複的測試。在本文中我們將匆...查看完整版>>Java開源測試工具JUnit簡介
 
iBATIS in Action iBATIS實戰(圖靈程序設計叢書·Java系列)|報價¥33.70|圖書,計算機與互聯網,程序設計,綜合,Clinton Begin
目錄:圖書,計算機與互聯網,程序設計,綜合,品牌:Clinton Begin基本信息·出版社:人民郵電出版社·頁碼:269 頁碼·出版日:2008年·ISBN:9787115177100·條碼:9787115177100·版次:1版·裝幀:平裝·開本:16 1...查看完整版>>iBATIS in Action iBATIS實戰(圖靈程序設計叢書·Java系列)|報價¥33.70|圖書,計算機與互聯網,程序設計,綜合,Clinton Begin
 
iBATIS in Action iBATIS實戰(圖靈程序設計叢書·Java系列)|報價¥33.70|圖書,計算機與互聯網,程序設計,綜合,Clinton Begin
目錄:圖書,計算機與互聯網,程序設計,綜合,品牌:Clinton Begin基本信息·出版社:人民郵電出版社·頁碼:269 頁碼·出版日:2008年·ISBN:9787115177100·條碼:9787115177100·版次:1版·裝幀:平裝·開本:16 1...查看完整版>>iBATIS in Action iBATIS實戰(圖靈程序設計叢書·Java系列)|報價¥33.70|圖書,計算機與互聯網,程序設計,綜合,Clinton Begin
 
JUnit實戰
前言 由于現在公司進行Unit Test Case的整理階段,所以抽空對Junit進行了一下了解,以下是集合了衆家所長之精華(考慮的是按我的思路總結的,也許不能完全表達作者的思路,所以在附錄中有所有我參考的文章地址,大家...查看完整版>>JUnit實戰
 
 
回到王朝網路移動版首頁