iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
1

設定好 test 測試環境, 以及 git 環境設定, 現在我們可以開始搗鼓我們的產品實驗室. 當我們編寫產品程式時, 我們就試著用下面流程來跑

  • 紅燈 -- 寫一個新的測試失敗的案例
  • 綠燈 -- 實作程式碼, 讓測試案例通過
  • 重構 -- 重構程式碼

每增加一個新功能就從第一點流程開始跑.

需求描述

有一家小王書店在進行賣Typescript 教學系列書的促銷活動, 每一本書定價 $100 元. 買兩本書可以打5% 的折扣, 買三本書可以打 10% 的折扣, 買四本書可以打 20%. 如果買到五本以上可以打到 25% 的折扣. 請寫出一個函式可以計算價格.

我們先寫一個測試案例 bookstore.test.ts,

test('buy 1 book', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(1)).toEqual(100); 
});

上面測試描述了買一本書的測試案例, 預期結果應該是100元.

當然上面程式碼不會編譯通過, VSCode 編輯器顯示下面錯誤訊息

Cannot find name 'Bookstore'. Did you mean 'bookstore'?

建立測試案例

這時候你在測試案例上面新增一個Bookstore class

class Bookstore {
}

test('buy 1 book', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(1)).toEqual(100); 
});

此時VSCode 出現下面錯誤

Property 'getPrice' does not exist on type 'Bookstore'.

你可以注意到 getPrice 的地方會出現紅色的發抖底線, 這一行開頭有個小燈泡
alt

用滑鼠點取小燈泡, 選取 "Declare method 'getPrice'", 然後VSCode 會自動幫你補上方法

class Bookstore {
   getPrice(arg0: number): any {
      throw new Error("Method not implemented.");
   }
}

然後我們修正一下並實作這個 getPrice 方法

class Bookstore {
   getPrice(books: number): number {
      return 100;
   }
}

別想太多, 我們先回傳100 元, 讓這個測試案例通過

執行jest 跑測試, 果不其然結果成功

> yarn test

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.101s
Ran all test suites.
Done in 5.68s.

接下來新增下一個案例: 買2本書的時候, 可以打5% 的折扣, 預期應該是190 元

test('buy 2 books', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(2)).toEqual(190); 
});

這時候跑一下測試, 你可以看到測試結果失敗

v but 1 book (4ms)
x buy 2 books (4ms)

* buy 2 bookstore

Expected: 190
Received: 100

      12 | test('buy 2 books', () => {
      13 |    let bookstore = new Bookstore();
    > 14 |    expect(bookstore.getPrice(2)).toEqual(190); 
         |                                  ^
      15 | });

   at Object.<anonymous> (tests/bookstore.test.ts:14:34)

然後我們再修正 getPrice 實作方法

class Bookstore {
   getPrice(books: number): number {
      if( books == 2 ) {
         return 190;
      }
      return 100;
   }
}

跑一下Jest 測試

> yarn test

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.113s
Ran all test suites.
Done in 5.69s.

以此類推, 現在加上第3 個測試案例 --> 跑測試紅燈 --> 修好 Bookstore --> 測試綠燈 --> 加第4個測試案例 --> 測試紅燈 --> 修好 Bookstore --> 測試綠燈

test('buy 3 books', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(3)).toEqual(270);
});

test('buy 4 books', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(4)).toEqual(320);
});

test('buy 5 books', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(5)).toEqual(375);
});

test('buy 6 books', () => {
   let bookstore = new Bookstore();
   expect(bookstore.getPrice(6)).toEqual(450);
});

最後我們的實作程式碼如下

class Bookstore {
   getPrice(books: number): number {
      if( books == 2 ) {
         return 190;
      }
      if( books == 3 ) {
         return 270;
      }
      if( books == 4 ) {
         return 320;
      }
      if( books == 5 ) {
         return 375;
      }
      if( books >= 6 ) {
         return books * 100 * 0.75;
      }
      return 100;
   }
}

上一篇
簡單的Git 操作 - 11
下一篇
參數化測試 - 13
系列文
為什麼世界需要Typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言