<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 6,comments - 7,trackbacks - 0
    單元測試基礎
    ???????? 當今軟件測試十分盛行時,本人通過項目實踐和個人親身體會淺談單元測試,本人一直堅持 用代碼說話的原則 ,同時也希望個人能給出寶貴意見,共同探討、共同進步,為中國軟件事業有更大的發展共同奮斗!
    最早我們項目組開發的項目時,寫代碼都是從底層一直寫到表現層到 jsp ,然后開發人員在 web 層調試頁面,近乎 98 %都會報一大堆 exception, 然后再在代碼中加斷點一步一步查到底哪一層代碼出現問題 ……, 比較好點做法就是在各個類中加上 main 方法測試,但總體很不理想,給 web 層開發人員的調試和質量控制人員帶來繁重的工作壓力;使用單元測試后,針對每一個方法都做嚴格的把關,大大減少調試的時間;同時質量控制人員返回過來的 bug 少了近 60 %,現在對于開發人員寫測試用例非常熟練,并且本人根據實際情況對測試用例做了點小小改動(這部分主要在后面代碼中詳述),帶來很好的效果!
    單元測試到底給實際開發帶來什么好處那?
    (1) 首先對于開發人員來說大大減少調試工作的時間,同時也規范了對于代碼安全管理(我們知道那些方法是可以調用的);
    (2) 對于整個項目來說,有了完整的測試,保證項目最后交付測試有了可靠依據;
    (3)對于測試人員大大減少bug的反饋;
    (4)對于項目經理整個項目達到很好的可控;
    (5)最主要的完整的單元測試給后期維護人員帶來很大的便捷!

    單元測試好處可能還有很多,但本人只能理解和感悟這么多 , 希望觀者補充!
    單元測試配置:
    ?????? 我將使用 eclipse myEclopse 給大家介紹關于 JUNIT 的環境的簡單配置;右鍵點擊項目選擇 屬性 ,在彈出窗口中到環境變量中添加 junit.jar 包,這樣下一步我們就可以進行單元測試了;
    使用 eclipse 快速開發 test Case
    如下圖:右鍵選擇你要測試的類,在新建中點擊 “JUnit 測試用例
    彈出對話框,配置測試名稱和根目錄,添加注釋等,再點擊 下一步 到下圖:
    ????? 選擇你要測試類中的方法,點擊完成!便生成測試類的基本框架,如下代碼,我們以對一個 DAO 類測試為例:
    /*
    ?*?Copyright?reserved?2005?by?XXXXCo.?Ltd.
    ?*?Author:XXX???Date:2006-9-4
    ?
    */


    import?junit.framework.TestCase;

    /**?
    ?*?
    @author?XXX
    ?
    */
    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單元測試一共要注意一下幾點:
    1import 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 測試,就運行測試類!
    在執行測試類時,執行的大概過程
    1)先執行構造方法public OrgTypeDAOTest(String arg0)
    2)再執行初始化數據方法protected void setUp()
    3)再執行以test開頭的測試方法;
    4)最后執行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中海測試");
    ????}

    ????
    **
    ?????*?獲取數據方法(主健)
    ?????*?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 構建整體測試帶來極大方便性!其中的好處相信只有使用才能體會!
    ???? 說到這,就此暫告一段落!由于時間倉促,書寫不規范和關于任何問題處敬請指出,相互探討.
    posted on 2006-10-01 14:54 扁豆 閱讀(2640) 評論(2)  編輯  收藏 所屬分類: java技術

    FeedBack:
    # re: junit in java 真正的測試用例實戰!
    2006-10-01 20:05 | JonneyQuest
    最新版本的JUnit已經不用集成TestCase了,可以直接加Annountation標記。  回復  更多評論
      
    # re: junit in java 真正的測試用例實戰!
    2009-08-01 09:30 | vanjor
    “把所有以 test 開頭的方法中的方法名稱前的 test 去掉(例如把 testOrgTypeList() 改為 orgTypeList() 方法)”
    好小細節!  回復  更多評論
      
    主站蜘蛛池模板: 久久青草免费91线频观看站街| 精品成在人线AV无码免费看 | 亚洲美女在线国产| 91视频免费网站| 亚洲永久在线观看| 亚洲精品国产自在久久| 久久精品国产免费一区| 亚洲人成自拍网站在线观看 | 亚洲最新在线视频| 免费国产一级特黄久久| 无码午夜成人1000部免费视频| 亚洲色图激情文学| 亚洲va久久久噜噜噜久久狠狠| 久久久久国色AV免费看图片| 中文字幕不卡高清免费| 色老板亚洲视频免在线观| 中文字幕久久亚洲一区| 久久精品网站免费观看 | 亚洲人成无码久久电影网站| h片在线免费观看| A毛片毛片看免费| 亚洲精品久久无码| 精品亚洲国产成AV人片传媒| 亚洲乱码日产精品a级毛片久久| 免费精品人在线二线三线区别| 97在线免费视频| 免费国产草莓视频在线观看黄| 亚洲国产av美女网站| 亚洲人成亚洲人成在线观看| 国产真人无遮挡作爱免费视频 | 色猫咪免费人成网站在线观看| 337P日本欧洲亚洲大胆艺术图| 亚洲日本国产精华液| 亚洲精品制服丝袜四区| 国产一区在线观看免费| 国产精品成人免费一区二区| 青青青国产手机频在线免费观看| 免费人成再在线观看网站| 亚洲乱码无人区卡1卡2卡3| 亚洲最大中文字幕| 久久久久亚洲av无码专区喷水|