JUnit in java 真正的測試用例實戰
單元測試基礎
當今軟件測試十分盛行時,本人通過項目實踐和個人親身體會淺談單元測試,本人一直堅持“用代碼說話的原則”,同時也希望個人能給出寶貴意見,共同探討、共同進步,為中國軟件事業有更大的發展共同奮斗!
最早我們項目組開發的項目時,寫代碼都是從底層一直寫到表現層到jsp,然后開發人員在web層調試頁面,近乎98%都會報一大堆exception,然后再在代碼中加斷點一步一步查到底哪一層代碼出現問題……,比較好點做法就是在各個類中加上main方法測試,但總體很不理想,給web層開發人員的調試和質量控制人員帶來繁重的工作壓力;使用單元測試后,針對每一個方法都做嚴格的把關,大大減少調試的時間;同時質量控制人員返回過來的bug少了近60%,現在對于開發人員寫測試用例非常熟練,并且本人根據實際情況對測試用例做了點小小改動(這部分主要在后面代碼中詳述),帶來很好的效果!
單元測試到底給實際開發帶來什么好處那?
?。?) 首先對于開發人員來說大大減少調試工作的時間,同時也規范了對于代碼安全管理(我們知道那些方法是可以調用的);
?。?) 對于整個項目來說,有了完整的測試,保證項目最后交付測試有了可靠依據;
?。?) 對于測試人員大大減少bug的反饋;
?。?) 對于項目經理整個項目達到很好的可控;
?。?) 最主要的完整的單元測試給后期維護人員帶來很大的便捷!
單元測試好處可能還有很多,但本人只能理解和感悟這么多,希望觀者補充!
單元測試配置:
我將使用eclipse+myEclopse給大家介紹關于JUNIT的環境的簡單配置;右鍵點擊項目選擇“屬性”,在彈出窗口中到環境變量中添加junit.jar包,這樣下一步我們就可以進行單元測試了;
使用eclipse快速開發test Case:
如下圖:右鍵選擇你要測試的類,在新建中點擊“JUnit 測試用例”,
彈出對話框,配置測試名稱和根目錄,添加注釋等,再點擊“下一步”到下圖:

?。?)最后執行protected void tearDown()方法清理對象;
如果測試失敗或者錯誤,將會顯示一個紅色的亮條;如果測試通過將顯示綠色亮條;如下圖
這樣就把一個整個單元測試操作例子演示完成!
可能對于一個測試類中有多個方法要測試,對于后面看著的確有些困難,因此,我對上測試類進行簡單的調整,如下代碼:
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中海測試"); } /**//* * 獲取數據方法(主?。?/div> * 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); } } |
處理過程:
?。?)把所有以test開頭的方法中的方法名稱前的test去掉(例如把testOrgTypeList()改為orgTypeList()方法);
(2)同時添加一個以test開頭的方法,并調用測試方法;這樣做主要是因為執行測試時JUnit(除本身特有的方法出外)只執行以 test為開頭的方法;
?。?)同時大家注意到我還把測試初始數據放到兩個private方法中private void setOrgTypeVOAddInfo()和private void setOrgTypeVOUpdateInfo()方法中供調用;
大家可能認為很簡單,就是這樣簡單的改動帶來很大的方便,大家是否注意到,我以后運行測試用例時,只關心public void testOrgTypeInfo() 方法就行了,因為只要各個方法的斷言策略定制完成,一般就不會再改動,因此,后期的回歸測試還是驗收測試,縮小了我們對測試的關注點,同時對后面寫 test suite構建整體測試帶來極大方便性!其中的好處相信只有使用才能體會!
posted on 2014-11-14 10:01 順其自然EVO 閱讀(213) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄