
Spring 2019 。 Ric Huang
---
### 期末專題分組情形
* 18 人尚未分組 --> 請在今天下課後留下來,我們來集體媒合一下
* 每人/組可以有 1 mins 介紹你自己 and/or 你的題目
* 其它相關資訊,請至學校信箱收信
----
### 期末專題 Deadline & Demo
* 有鑒於大家從現在開始到 06/26 可能不夠時間完成專題,**deadline 將會延長到 9pm, Sunday, 06/30**
* 由於預期組數會超過 40 組,擠在同一天 present 恐怕效果不彰,因此,我們將改為 **請大家自行錄製 demo 影片上傳**
----
### 期末專題繳交項目 Part I
* 請在專題 deadline 前,在你們專題的根目錄放上 README.md, 內容應包含:
```
* 題目名稱
* 一句話描述這個服務在做什麼
* (Optional) Deployed 連結
* 安裝/使用/操作方式 (含伺服器端以及使用者端)
* 其他說明
* 使用與參考之框架/模組/原始碼
* 專題製作心得
* 使用之第三方套件、框架、程式碼
* Demo 影片連結
* ------------------------
* 每位組員之貢獻 (請詳述)
* (Optional) 對於此課程的建議
```
----
### 期末專題繳交項目 Part II
* 請在專題 deadline 前,至 FB 社團 PO 文介紹你們的專題,內容應包含:
```
* 題目名稱
* 一句話描述這個服務在做什麼
* (Optional) Deployed 連結
* 安裝/使用/操作方式 (含伺服器端以及使用者端)
* 其他說明
* 使用與參考之框架/模組/原始碼
* 專題製作心得
* 使用之第三方套件、框架、程式碼
* Demo 影片連結
```
----
### 期末專題繳交項目 Part III
* 請在專題 deadline 前,至此 [Google Form](https://docs.google.com/forms/d/e/1FAIpQLSewxggVdc7zDu6PZBPNapBD68UKVhq9YsoXU-Gqy8s7OaBaGA/viewform) 填寫期末專題資訊,內容包含:
```
* 組別 (06/15 後於 Ceiba 公告)
* 組長中文姓名
* 題目名稱
* Github Repo 網址
* Demo 影片網址
* FB 社團貼文網址
* (Optional) Deployed service 網址
```
----
### Demo 影片規範
* 長度不得超過 8 分鐘,請在專題 deadline 前,上傳至雲端空間 (preferrably a video hosting service),如 Youtube, FB 等
* 影片內容至少應包含:
* 簡單自介 (組別、組員姓名、題目名稱)
* 三句話內介紹你們的題目在做什麼
* Project Demo
* 程式碼架構/使用技術介紹
* Optional 內容:動機/心得、投影片 or 其他輔助說明
* 影片拍攝製作技巧、有沒有露臉、畫質 (只要不要真的太差)... 等,不在評分範圍,大家不需要在這方面軍備競賽
---
### TA Information
| 助教 | 負責作業 | 聯絡方式 |
|-------|---------|---------|
| 陳家暄 | HW 1, Practice 1, 2 | FB |
| 李育嘉 | Practice 3, 4, 5, 6 | r07921037@ntu |
| 劉記良 | HW 2, 3 | FB or r07942083 |
* 針對作業分數如有問題,請儘速聯絡相關助教
* Midterm & Final Projects 會一起改
---
### OK, 今天的第一個重點:Testing
* 顧名思議,**testing** 就是去測試你寫的code有沒有錯
* (態度問題)為什麼不說"測試你寫的code對不對"?
* 什麼叫做 "正確/沒有 bug 的 code"?
* 開發者做測試:天生的盲點
* Recall: 一般軟體開發,花在 debug 的時間比寫 code 的時間還要長
* Debug 的功力才是決定你開發能力的關鍵!
----
### Test Driven Development (TDD)
* 顧名思義,由「測試」來驅動開發,也就是說,先根據 spec,寫好測試,再行開發
* 把開發切成很短的 cycles, 快速的 iterate, 隨時來檢查開發是否有誤 (或通過相對應的測試)
----
### TDD 的開發 Cycles ([ref](https://en.wikipedia.org/wiki/Test-driven_development))
1. Add a test
2. Run all tests and see if the new test **fails**
3. Write the code
4. Run tests
5. Refactor code
6. Repeat the above
----
### Unit and Integrated Tests
* Unit test(單元測試): 一般由開發者執行,也就是去寫一些小小的 tests 去測試程式碼的某項功能、某些假設等是否正確。通常會用某種 "coverage metrics" (e.g. line/path/condition) 來確認測試的完整度。
* Integrated test(整合測試): 一般由測試工程師來執行,會根據各種實際的使用情將來撰寫 "測試劇本",或者是規劃出 "test plan",配合一些整合測試工具(如:Selenium、Cypress),來進行測試的自動化。
----
### Regression Test
* 隨著程式不斷的開發與演進,一定會 introduce 一些新的 bug, 而原則上當每一個 bug 修好之後,應該要寫一個對應的 test (or say "assertion"), 來確保這個 bug 已經被正確修復。
* 然後,如何確保新的 code 不會把以前修好的 bug 又搞爛,就需要跑 "regression" -- 定時地把所有的 tests 跑過一遍,確保舊的問題不會重現
* 一般的 regression 會以 "天" 為單位,甚至是隨時都在跑 regressions
* 除了 functional test, 也需要考慮 performance / robustness tests
----
### Continuous Integration (CI)
* 在協同開發的專案裡面,整合 (integration) 常常是一個非常昂貴甚至是會阻礙專案成功最主要的因素
* CI 就是為了解決/減少整合的問題 -- 利用一個共同的 repository, 讓大家可以隨時同步,並且透過 tests, 確保整體專案是可以隨時執行/demo的
* 較嚴格的 CI 甚至會要求在 check-in 之前一定要跑過一定的整合測試才會放行
* CI tools: [CircleCI](https://circleci.com/), [TravisCI](https://github.com/travis-ci/travis-ci), [GitLab](https://gitlab.com/) 等 ([ref](https://www.guru99.com/top-20-continuous-integration-tools.html))
----
### Continuous Development (CD)
* 以 CI 的精神向上延伸,就有 Continuous Development (CD) 這樣的原則
* CD 包含了:continuous integration, continuous testing, continuous delivery and continuous deployment
* Staging repo: 為了避免 CD 造成以上線服務的問題,通常會在 formal release 之外另外開一個 staging 的 repo, 讓平時的 CD 流程先把新的 features 開發, bug 的修正,先 checkin 到這邊,待整體測試完畢之後,在上版到正式的環境發布
----
### 總之,建議大家在執行專案的時候盡量 follow CI/CD 的精神,確保專案可以隨時 "demo",在這樣的基礎下所有組員可以把開發與測試的工作盡量細分,並且參考 [git flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow),把個人、staging、formal 的 repo 分清楚
---
### Introduction to Jest
* [Jest](https://jestjs.io/en/), as well as [Mocha](https://mochajs.org/), [Jasmine](https://jasmine.github.io/), are famous JavaScript test frameworks
* Jest 強調他的簡單、直覺,為一個很容易上手的測試環境
----
### Let's setup a Jest example
```bash
mkdir jest-test
cd jest-test
npm init -y
npm install --save-dev jest
```
```bash
# Add this to "package.json"
{
"scripts": {
"test": "jest"
}
}
```
----
### A testing example
```javascript
// src/sum.js
function sum(a, b) {
return a + b
}
module.exports = sum
```
```javascript
// src/sum.test.js
const sum = require('./sum')
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3)
})
```
* Run "npm test" and see what happens!
----
### Jest Matchers
* Jest uses “Matchers” to let you set rules for your tests.
* See the [expect API](https://jestjs.io/docs/en/expect) for full documentation.
----
### Common Matchers
* Common matchers are simplest ways to test a value. For example:
```javascript
toBe
toEqual (basically toBe for objects and arrays)
```
* To reverse a matcher, simple add a not after 'expect'
```javascript
expect(something(1)).not.toBe(3)
```
----
### Other Matchers ([ref](https://jestjs.io/docs/en/using-matchers))
* Truthiness -- toBeTruthy(), toBeFalsy(), toBeNull()
* Strings -- toMatch()
* Arrays and iterables -- toContain()
* Exceptions -- toThrow()
* And more... ([ref](https://jestjs.io/docs/en/expect))
----
### Testing Asynchronous Code
```javascript
// Callback example---
test('the data is peanut butter', done => {
function callback(data) {
expect(data).toBe('peanut butter');
done();
}
fetchData(callback);
});
```
```javascript
// Promise example---
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
});
```
----
### async and await
```javascript
test('the data is peanut butter', async () => {
await expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
await expect(fetchData()).rejects.toThrow('error');
});
```
----
### Repeating Setup For Many Tests
```javascript
beforeEach(() => {
initializeCityDatabase();
});
afterEach(() => {
clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
```
----
### One Time Setup
```javascript
beforeAll(() => {
return initializeCityDatabase();
});
afterAll(() => {
return clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
```
----
### For deeper learning, check out [this video](https://www.youtube.com/watch?v=7r4xVDI2vho)
---
### Now you have learned almost everything I would like to cover.
### What's next?
---
### 台灣的軟體環境
* 資工系畢業學生都去哪裡? 新鮮人起薪? 繼續升學? ([ref](https://www.104.com.tw/jb/career/department/view?degree=3&mid=520114))
* 台灣軟體工程師平均薪水? ([ref](https://www.jobsalary.com.tw/salarysummary.aspx?codeNo=140202))
* 全球軟體工程師平均薪水? ([ref](https://www.payscale.com/research/US/Job=Software_Engineer/Salary))
----
### 唸研究所/出國? 進大公司/創業?
----
### Well, 如果你有一些創業的想法,請先問問自己底下三個問題:
1. 你是否已準備好 commit 四年?
2. 請質化與量化四年後公司應該要有的樣貌
3. Based on 2, 那一年後公司的目標為何?
----
### 想創業,但沒有想法怎麼辦?
* 增加自己的職場知識與經驗
* To B or not to B?
* 讓自己變強,在某些方面
---
### Some advices for entrepreneurs
* 搞清楚為何要創業?
* SMB? Local king? Global business?
* Project or product?
----
### 先同居、再結婚
* 權利義務要講清楚,股權要及早規劃
* 公司發展與財務規劃,讓數字說話
----
### 經驗、能力、個性,都很重要
* 但有上面三者但卻沒有「創業精神」,
還是謝謝再聯絡
----
### 市場、資金、人才,缺一不可
* 你真的了解市場嗎?
* 你知道你需要多少資金才能成功嗎?你知道投資的遊戲規則嗎?
* 你可以想像 3 人,30 人,300 人... 的公司很不相同嗎?
---
### My last advices for everyone
1. 理性地思考、感性地做決定
2. 做人就是不要後悔
3. 及早犯錯,學得更快
---
### Good luck on your final project!
### And have a good life~
{"metaMigratedAt":"2023-06-14T22:13:46.873Z","metaMigratedFrom":"YAML","title":"Semester Finale (Testing and Other Stuffs)","breaks":true,"slideOptions":"{\"theme\":\"beige\",\"transition\":\"fade\",\"slidenumber\":true}","contributors":"[{\"id\":\"752a44cb-2596-4186-8de2-038ab32eec6b\",\"add\":8906,\"del\":408}]"}