# [測試]自動化測試(一)-Postman、newman、k6實務
###### tags: `postman` `newman` `k6` `Test` `工作筆記`
## 自動化測試的定義?
對於自動化測試的定義,很多人說法都不一
(尤其是來推銷的測試化工具業務...)
到底是誇大其辭的話術,還是真有其事我們接著看下去
**自動化測試 = 非手動測試... Really?**
根據ISTQB(國際軟體測試認證委員會)內辭典的定義:
`Test automation:使用軟體來執行或支持測試活動`

## 常見的兩種方法
### 方法一: Data-driven testing approach (最常見)
自動化測試框架的一部分,允許使用者重複使用單一腳本,搭配不同大量的輸入資料。重要的是此資料可以分離此腳本。

### 方法二: Keyword-driven testing approach (aka table-driven testing / action word based testing)
關鍵字(Actions)最簡單形式的定義是一個或多個最小測試步驟的集合。

(很少有工具可以做到,但常被拿來寫腳本的前端測試軟體**Selenium**實在太有名惹,就是那個少數)
## 使用工具
1. Postman (功能性測試手動腳本製作)
2. Newman (來將 Postman 的測試案例自動執行)
3. K6 usage (負載/壓力測試)
## 輔助工具
1. mockoon (當Server side尚未完成時,想預先測試自己寫的Test Script是否正確,可以參考: https://mockoon.com/ 建立一個Mock Server。 )
2. TableConvert (各種文檔格式互換工具) https://tableconvert.com/
## Postman實務功能性測試手動腳本製作
### 這次要測試的是一個登入後取得Token並驗證身分後,獲取帳號所有功能、我的最愛、設定主題、查詢所有主題之測試
`s1. OneTime Token` > `s2.取得該帳號所有身分` > `s3.取得JWT Token`> `s4.功能-所有資料` >`s5.帳號-我的最愛` > `s6.角色-所有資料` > `s7.主題項-依據主題` > `s8. 帳號-查詢所屬主題`
### s1. OneTime Token

首先POST後面網址列內的{{DOMAIN}}是事先定義好,塞進Postman全域變數的資料
(點選右上角【眼睛】符號可以做設定)
透過Postman進行測試的重點在於使用Tests 這個功能。參考: https://learning.postman.com/qa/
我們在`s1. OneTime TokenTests`裡寫入方法,並把獲取到的OneTimeToken塞入Postman的全域變數,以供之後的步驟使用。
### s2. 取得該帳號所有身分

在**Headers**的部分,設定了`X-Auth-token`的VALUE為一個`{{OneTimeToken}}`的變數,之後Postman就會自動帶入由`s1. OneTime TokenTests`塞進去的OneTimeToken值。

並且在**Tests**裡把API回傳的`aorId`和`ldapId`塞入Postman的全域變數內。
### s3. 取得JWT Token

進入**Body**把剛剛在 `s2.取得該帳號所有身分`設定的`aorId`和`ldapId`帶入API所需之參數內。
### s4. 功能-所有資料 ~ s8. 帳號-查詢所屬主題
就是普通的API的傳送方式,不贅述
---
## **到這邊基礎Postman用法就DEMO結束了,接下來進入Runner部分**

把寫好的測試步驟拉進去Runner內,但既然是自動化測試,就不會像是手動的一筆一筆測。
之前我們在 `s2.取得該帳號所有身分` 內所寫死的`ID: 46`就要改成`{{ID}}`變數,並將來自外部的`aorID_480.csv`ID資料帶入。
**Iterations**可以設定測試的次數,這邊配合資料筆數設定為`480`

`aorID_480.csv`內容如下(單純的ID 1~480):

執行的結果如下圖:

## 利用Newman將Postman的測試案例自動執行
>參考 NEWMAN官方文件
>https://learning.postman.com/docs/running-collections/using-newman-cli/command-line-integration-with-newman/
將剛才寫好的測試Script點選匯出成`Json`格式


Postman全域變數內還有我們預先設定好的`{{DOMAIN}}`也要一起匯出成`Json`格式

打開小黑窗輸入指令
```
newman run {{postman的匯出script}}.json -e {{postman環境變數}}.json -d {{外部Data檔案}}
```
這邊的話就是
```
newman run 2022-0501-BCRM-load-test.postman_collection.json
-e env.json -d aorID_480.csv
```
有順利執行的會就會出現以下結果

---
## 但基本上常常不會那麼順利...需要再次手動修改Driver Script...
**常見的原因有...**
1. 修改具有邏輯的URL Pattern API ,使其處理變數

2. 修改具有邏輯的Header ,使其處理變數

3. 改成非同步處理驗證邏輯

以`s7.主題項-依據主題`為例子,上面為同步,下面為非同步寫法


---
## K6 usage 負載測試腳本製作
>摘要:
將Postman 腳本轉換成 k6 腳本,進行壓力測試(可回歸測試)。 k6輸出呈現結果有多種。官方雲端環境的限制是,concurrent user 50 員(目標是400~500)。
k6官方的建議為將輸出資料餵入influxDB,使用 grafana 搭配 dashboard 呈現測試結果。
但這裡只以本機執行作為範例。
轉換程式: https://github.com/grafana/k6-example-postman-collection
轉換程式原始說明:https://k6.io/blog/load-testing-with-postman-collections/
依造官方說明,將GitHub上的範例抓下來

1. `env.json`置換成由Postman匯出的環境變數檔`env.json` (這裡剛好檔名相同,實際上為不同檔案)
2. `test-api.json`置換成由Postman匯出的Driver Script `2022-0501-BCRM-load-test.postman_collection.json`
3. `k6-script.js` 直接刪除,我們需要生成一個新的
打開小黑窗輸入指令
`postman-to-k6 t2022-0501-BCRM-load-test.postman_collection.json -e env.json -o k6-script.js`
執行完於資料生成了新的`k6-script.js`後,接著輸入
`k6 run k6-script.js`
### 執行結果通常不會很順利,需要依造會饋的錯誤,再去修改轉換出來的K6 Script

這邊可以看到回饋是因為讀取不到`{{ID}}`的資料,原本的ID資料我們是由外部的`aorID_480.csv`中讀取。但在K6當中並未匯入,據官方的API範例:https://k6.io/docs/javascript-api/init-context/open
支援外部以`CSV`或`JSON`的方式傳入Data (但CSV比較麻煩...)
這邊求方便,利用[TableConvert](https://tableconvert.com/)將`aorID_480.csv`轉換為JSON格式的`data.json`
然後改寫`k6-script.js`使其讀入`data.json`的ID資料,同時於options內設定壓力測試的參數


執行後成功畫面

# 結論
## 自動化測試的優點與缺點(國際組織ISTQB說的)
### Pros
1. 提高測試活動的效率
1. 將手動完成時需要大量資源的活動自動化
1. 自動化無法手動執行的活動。
### Cons
1. 對工具的不切實際的期望
1. 低估了最初引入的努力
1. 低估實現顯著收益的努力
1. 努力維護測試資產
1. 過度依賴工具
1. 忽視關鍵工具之間的互操作性
1. 供應商支持不佳
1. 忽略版本控制
1. 開源/免費工具項目暫停風險
# **The End**