設定好 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 的地方會出現紅色的發抖底線, 這一行開頭有個小燈泡
用滑鼠點取小燈泡, 選取 "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;
}
}