• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 先測試再開發?TDD測試驅動開發了解一下?

    發表于:2023-07-01來源:未知作者:i進擊的攻城獅點擊數: 標簽:tdd測試驅動開發
    我第一次接觸TDD這個概念,是在 >中,作者鮑勃大叔在書中,寫了一些關于測試代碼的代碼規范,其實就提到了有關TDD三定律:

    1、什么是TDD

    我第一次接觸TDD這個概念,是在<<代碼整潔之道>>中,作者鮑勃大叔在書中,寫了一些關于測試代碼的代碼規范,其實就提到了有關TDD三定律:

    - 定律一: 在編寫不能通過的單元測試前,不可編寫生產代碼

    - 定律二: 只可編寫剛好無法通過的單元測試,不能編譯也算不能通過

    - 定律三:只可編寫剛好足以通過當前失敗測試的生存代碼

     

    我第一次讀到這三個定律時,不能說是毫無頭緒,只能說是一臉懵逼。

    完全不知道作者想表達啥意思,也沒有案例代碼。

    對此,我不得不網上查閱的很多相關文章,最后總結出來。

    TDD測試驅動開發,就是先寫測試用例,再去開發功能。

    這里測試驅動開發里的驅動是做動詞,不是名詞

    好了,現在如果別人問你TDD是什么,你就可以直接這樣告訴他。

    2、傳統開發方式

    我們傳統開發一個功能是這么開發的?

    傳統編碼方式

    需求分析,想不清楚細節,管他呢,先開始寫

    發現需求細節不明確,去跟業務人員確認

    確認好幾次終于寫完所有邏輯

    運行起來測試一下,靠,果然不工作,調試

    調試好久終于工作了

    轉測試,QA 測出 bug,debug, 打補丁

    終于,代碼可以工作了

    一看代碼爛的像坨屎,不敢動,動了還得手工測試,還得讓 QA 測試,還得加班…

    傳統的開發方式,都是以開發為主,直接開始編寫代碼,代碼出了問題,再去改,多改幾次,你就會覺得這代碼簡直就是屎山,想重構一下,又怕出新的問題。

     

    3、TDD步驟

    而TDD測試驅動開發是怎么做的呢?

    TDD要求我們先根據需求去拆分任務,把一個大的任務拆分位各個模塊,也就是一個個的函數,我們再去為這些函數去編寫最小的測試,再去寫能讓這個最小的測試通過的最小的實現。

    TDD的生命周期圖如下。

    這樣做的好處是:

    1、有助于我們提前澄清需求

    2、可以通過單元測試斷言的診斷機制快速得出反饋

    3、當我們寫完了所有的需求,會發現所有的需求都會被測試覆蓋了

     

    4、舉個例子

    正所謂,光說不練,假把式;下來我們來整個簡單的例子去理解一下測試驅動開發;

    假如我需要寫個功能,分析用戶上傳的文本中,每個單詞的數量,并且按照數量倒序排序,這個應該怎么實現:

    比如說文本如下:

    Hello world
    Hello CSDN
    Hello Boy
    My name is Boy
    is is

    那輸出就是:

    Hello 3
    is 3
    Boy 2
    world 1
    CSDN 1
    My 1
    name 1

     

    如果是新手或者是完全不懂代碼設計的人拿到這樣的功能,可能會這樣寫:

    public static void main(String[] args) throws Exception{
    String words = "";
    File file=new File("word.txt");
    Scanner sc=new Scanner(file);
    while(sc.hasNextLine()){
    String line=sc.nextLine();
    words = words + line + " ";
    }
    System.out.println(words);

    String[] wordArrays = words.split(" ");

    HashMap<String,Integer> hashMap = new HashMap<>();

    for(int i=0;i<wordArrays.length;i++){
    Set<String> wordSet = hashMap.keySet();
    if(wordSet.contains(wordArrays[i])){
    Integer number=hashMap.get(wordArrays[i]);
    number++;
    hashMap.put(wordArrays[i],number);
    }else{
    hashMap.put(wordArrays[i],1);
    }
    }
    System.out.println("統計單詞------------------");


    List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(hashMap.entrySet()); //轉換為list
    list.sort(new Comparator<Map.Entry<String, Integer>>() {
    @Override
    public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
    return o2.getValue().compareTo(o1.getValue());
    }
    });
    System.out.println(list);
    }

     

    好了,寫完了,讓我們運行一下:

     

     

    運行結果貌似也沒有問題,好了提交代碼。

    真的沒有問題嗎?統計單詞的數目也沒有問題,但是,如果后期,你要對這段代碼做維護,要去修改這段代碼,這段代碼讀起來是什么感覺?在我看來,這段代碼,就是屎山。

    代碼里幾乎完全沒有注釋,讀這段代碼,得從頭開始往下讀,如果其中一段代碼出了問題,你必須在整段代碼中尋找錯誤,非常浪費時間。

    讓我們來試試看TDD的寫法,TDD要求首先要把一個功能,去拆分分成各個小功能,然后去為這些小功能寫測試用例。

    這個統計單詞數目的代碼應該怎么拆分,試著拆分成小功能一下(這里要注意一下,同樣的功能,在拆分模塊的時候,不同的人選擇的拆分方法可能不同,一千個人里有一千個哈姆雷特,一千個人里也有一千種拆分方法)

     

     

    拆分好后,我們就可以為這些功能編寫測試用例了,

    我們先編寫測試用例,用assert斷言測試用例是否通過,運行,我們可以看出,方法還沒有進行開發,顯示未通過。

     

    這一步,就是TDD定律二中規定的

     

    - 定律二: 只可編寫剛好無法通過的單元測試,不能編譯也算不能通過

     

     

    下一步要做什么?我們看定律一

     

    - 定律一: 在編寫不能通過的單元測試前,不可編寫生產代碼

     

     

    定律一反過來是什么意思,不就是編寫好不能通過的單元測試后,就可以開始編寫生產代碼了嗎?

    于是開始編寫生產代碼進行測試

    在這里,我們編寫好了方法,在執行測試用例后,顯示綠色,代表測試用例通過。

    這時候又滿足了第三定律

     

    - 定律三:只可編寫剛好足以通過當前失敗測試的生存代碼

     

     

    我們的測試用例,專門測試一個小的功能,只為了通過這個方法。

    下一步我們再重復以上步驟,去TDD其他模塊。

    直到TDD完所有模塊,我們的功能就開發完了。

    代碼如下:

    public static void main(String[] args) throws Exception {
    //讀取文件
    File file=new File("word.txt");
    String words = readFile(file);
    String[] s1 = words.split(" ");
    //單詞記錄到hashmap
    HashMap<String, Integer> stringIntegerHashMap = groupHashMap(s1);
    //排序
    List<Map.Entry<String, Integer>> entries = orderHashMap(stringIntegerHashMap);
    //輸出
    System.out.println(entries);
    }

     

    方法的代碼太長,太展篇幅就不粘貼了,你看我們新的main方法,代碼就比較簡介,如果出了問題,只可能在這三個方法中其中,我們可以快速定位到方法中去,并且可以用之前編寫的測試用例進行測試。

     

    5、總結

    關于TDD測試驅動開發,我感覺精髓就是對功能進行拆分,用測試用例去測試功能,我相信很多人,都不會去編寫測試用例,代碼寫好后,就去頁面上點幾下,其實這是不太好的。因為如果這里的功能改動比較頻繁,你每次去頁面上通過點擊的方式測試功能,你得打開瀏覽器,登錄地址,尋找IP,為功能配置參數,這一套下來,真的非常耗費時間。

    一次如果5分鐘,10次就是50分鐘。

    而TDD建議的是什么?建議通過測試用例的方式去測試,它要求你必須編寫好測試用例后再去寫代碼,這樣就能保住,你每個小功能,都有一個測試用例,這樣,之后你改一個地方,只要找到這個地方所對應的測試用例就能測試了,非常方便。

    當然,TDD這種開發方法其實弊端也是很明顯的,比如,大多數程序員,其實是怎么做測試的?就是直接重啟項目,去頁面上看看,功能對不對,測試用例?那是什么?我不是開發嗎,我又不是測試。我去頁面點幾下測試,可能只需要幾分鐘,我去配置測試用例,八成等得二十分鐘,所以大多數程序員可能還是會選擇通過頁面點擊的方式去測試。

    測試用例真的是沒有必要的嗎?如果你去新建一個Maven項目,你會發送,test目錄和main目錄是同一級別的

     

     

    我相信在設計的時候,可能設計者(設計Maven的程序員肯定是大佬中的大佬),也是認為測試用例是非常重要的,才會把test目錄放在這個位置吧。

    原文轉自:http://www.uml.org.cn/Test/202204264.asp

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>