---
# System prepended metadata

title: 第六章：寫完測試，然後呢？執行測試的時機和方法

---

# 第六章：寫完測試，然後呢？執行測試的時機和方法

## <font color="#FAA">相關資訊&前置作業</font>
### 時間

2025.07.03（四）21:10 開始～

### 主持人

weiwei

### 同學簽到區～

| classmate | check in | classmate | check in |
| --------- | -------- | --------- | -------- |
| 非常愛柯基  |          | 樂樂      |    🫠      |
| Eero      |    💤      |Antonio H  |          |
| Uli       |   💤       |Gui        |    😵‍      |
| WeiWei崴崴 |  🫥      |  依依     |         |

從下方選一個你今天的心情來簽到吧～👇👇👇
😀 🫠 😵‍ 🤯 🫨 😮‍ 🤣 🤑 🤤 🥰 🤔 🥳 🤡 💤 💃 🤦‍ 💩 🫥


    
    

## <font color="#FAA">6-3 在CI上常態地執行測試</font>


:::info
### :question: 已經有設置 husky 在每次 push 之前測試程式碼，在 PR 合併之後還有需要再次透過 CI 測試嗎？
:::


建議還是需要在 **CI** 過程中安排測試，或是常態性定期執行測試(例如每天晚上10點執行測試)。
可以使用的工具有 **GitHub Actions** 等等。


原因有以下幾點：
1. 程式碼互相影響：
    例如在多人協作的狀態下， *A* 修改了某段程式碼並且推送到 remote 。 *B* 在分支上基於 *A* 尚未修改的程式碼進行開發。
    因為在本地端並沒有 *A* 修改的紀錄，此時在本地端執行測試的指令或是 **husky** 執行 **pre-push hook** 的檢查，都不會發現任何問題。
    一直到合併回 *A* 修改後的分支時才會出現錯誤。
    
    ![圖示](https://hackmd.io/_uploads/BJTxecMrgx.png)
    
    ![雖然沒有衝突但是CI的測試仍未通過](https://hackmd.io/_uploads/HJZOIt-Sxx.png)


    
    這裡有準備一個[案例]讓大家參考。
    
2. 測試不穩定：
    可能因為環境(網路)或是第三方套件的改版等等其他因素，導致不預期的失敗
    
3. pre-push的hook其實是可以被繞過的[^繞過hook的方法]


> 💡**題外話補充：**
> 在撰寫CI測試失敗的案例時發現，就算是刪除遠端分支(`git push origin --delete`)也會觸發pre-push的hook
> :::spoiler 圖片
> ![意外發現刪除遠端分支也會觸發husky pre-push](https://hackmd.io/_uploads/r1uZoObSle.png)
> :::

[案例]:https://github.com/cieliscute/0701DemoCode "merge之後互相影響導致CI test失敗的案例"
[^繞過hook的方法]:`git commit -m "message" --no-verify`會繞過 pre-commit hook<br/>`git push [remote] [local_branch] --no-verify`會繞過pre-push hook


:::info
### :question: CI測試失敗時，是否仍繼續合併程式碼？
:::

```mermaid
flowchart TD
  A[測試失敗？] -->|是| B{能否快速找到並修復？}
  B -->|能| C[修復問題]
  C --> D[恢復合併程式碼至主分支的機制]

  B -->|不能| E[暫時停止執行測試程式]
  E --> F[標記測試為待修復]
  F --> G[安排後續修復工作]
  G --> H[修復後再恢復執行測試]

  subgraph 潛在風險
    I[未修復變因疊加，導致錯誤與修復更加困難]
    J[測試警報持續太久 → 疲勞 → 忽視失敗影響]
  end
```

結論：
<font color="#FFD66B"> ⚠️ 建議修復問題之後再合併！！！</font>



<!-- ![意外發現刪除遠端分支也會觸發husky pre-push](https://hackmd.io/_uploads/r1uZoObSle.png) -->

:::info
### :question: 如何減少合併程式碼後測試失敗的機率？
:::
1. 尋找與修復不穩定測試：
    不穩定的原因有許多因素，有可能是因為測試之間有依賴關係[^測試不穩定-測試之間有依賴關係]，或是因為測試環境網路不穩定等等。
    [測試依賴關係範例]
2. 尋找更適合的測試方式：
    頻繁迭代的產品，可以採用 unit test 或 integration test 等較小範圍的測試。
3. 實作測試時盡量縮小範圍：
    測試範圍越小，越容易快速找到問題點。
    
[測試依賴關係範例]:https://github.com/cieliscute/0703CoverageDemo/tree/flakytest
[^測試不穩定-測試之間有依賴關係]:依賴關係:多個測試之間會相互影響，導致測試的執行順序或執行與否會影響到測試結果。

















## <font color="#FAA">6-4 從程式碼的覆蓋率來推敲使用案例的覆蓋率</font>
:::info
### 📖 程式碼覆蓋率
:::
程式碼被測試的比例。

以Jest為例，Jest在執行測試時，使用`--coverage` 參數可以產生詳細的覆蓋率報告。這些報告會顯示在終端機，也會生成在專案的`coverage` 資料夾中，通常包含 HTML、text、json 等多種格式。主要的覆蓋率指標如下：
- Statements（語句覆蓋率）：程式碼中所有語句被執行的比例。
- Branches（分支覆蓋率）：條件語句（如 if/else、switch case）所有分支被執行的比例。
- Functions（函式覆蓋率）：所有函式、方法被執行的比例。
- Lines（行數覆蓋率）：所有可執行行被執行的比例。

Jest 也會標示出哪些行數未被覆蓋。可以在 `coverage` 資料夾下的 `lcov-report/index.html` 看到圖形化的詳細報告，點擊檔案還能看到每一行的覆蓋情況。

:::info
### 📖 使用案例覆蓋率
:::
test case 涵蓋專案與產品的各個功能和使用情境的比例

它關注的是「功能」或「需求」是否都被測試到，例如：
 - 使用者註冊流程是否有被測試？
 - 商品下單、付款、取消訂單等情境是否都被測試？

:::info 
兩者比較
:::



|        | 程式碼覆蓋率 (Code Coverage)     | 使用案例覆蓋率 (Use Case Coverage) |
| ---------- |:-------------------------------- |:---------------------------------- |
| 定義       | 測試時實際執行到的程式碼比例     | 測試時涵 蓋的業務/功能使用情境比例 |
| 測量方式   | 工具自動分析程式碼執行路徑       | 依據需求文件或用例手動比對測試案例 |
| 目標       | 確保程式碼被測試涵蓋             | 確保所有業務需求/功能被測試        |
| 關注重點   | 程式碼層級（函式、分支、行等）   | 業務流程、用戶操作、功能完整性     |
| 工具支援   | Jest                             | 較少，通常需手動追蹤或自訂管理     |
| 缺點       | 可能只測到程式碼但未覆蓋實際需求 | 難以自動化、需明確定義所有用例     |
| 代表性指標 | 行覆蓋率、分支覆蓋率、路徑覆蓋率 | 用例覆蓋率、需求覆蓋率             |


:::info
### :question: 程式碼覆蓋率100%了，就沒有問題了嗎？ 
:::

程式碼覆蓋率只能反應程式碼被測試的程度，就算覆蓋率達到100%，仍有可能存在一些功能或使用情境沒有被我們測試到的

且程式碼覆蓋率無法反映出哪些程式碼是重要(需要優先測試)的。

 
結論：
<font color="#FFD66B"> ⚠️ 程式碼覆蓋率可以當成一個**輔助工具**，透過覆蓋率以及沒有被覆蓋的段落，我們可以間接推導使用案例，以提高測試的有效性。</font>

[利用覆蓋率推導使用案例]

[利用覆蓋率推導使用案例]:https://tw.yahoo.com




