街口支付軟體測試自動化方案選型

JKOPAY SDET
街口支付 JKOPay
15 min readJul 22, 2020

對於新創公司而言,「快」是首要準則。

「搶得市場先機」對於服務的產出或是客群尚未明確之前是很重要的一環;相較之下,產品品質的優先級就沒有那麼高了。但是,一旦服務亮相了, 使用者體驗會立刻被放大檢視,服務的好用與否將會是影響使用者留存率很重要的變因,「快速發佈經過驗證且具高穩定性的產品」對於測試團隊是個非常重要的目標。街口支付 ( 後稱「街口」) 在台灣電支市場中有著相對大量的用戶群體,目前正處於高速成長的階段,主要功能又是一般人日常都會進行的支付/交易服務。因此,根據市場需求進行快速反應與持續優化使用者體驗是街口的首要目標,顯而易見地,高效且高穩定的持續性發佈是必要條件,但是如何在有限的時間內快速的驗測完成,並確保目前程式的品質呢?「測試自動化」能在每次的發佈都能有效的提供完整的測試報告以提升大家對於服務可用的信心水準,因此自動化方案的選型探討有其必要性。

街口支付提供了支付、轉帳、叫車、外送、捐款、繳費……等不同的服務,以系統服務劃分於許多不同的模組進行驗測,如果僅透過手動進行功能回歸驗測,耗時、耗資源且覆蓋率不高。「測試自動化」提供了基礎的解決方案,一來大幅縮短手動回歸測試的時間,二來提供完整的報表以供 PM, RD, QA 進行確認,在三方認可的前提之下能快速的釋出服務,而服務的穩定性、可用性、可靠性也會因為「測試自動化」而大大提升。

需求分析

對於傳統的公司而言,只要確保服務可用不出錯即可。但對於街口的測試團隊而言,在全局的角度下,測試不應只局限在開發尾端的功能驗收,更多的是要把重心放在「測試左移」與「測試右移」,透過快速的迭代測試在服務成型的過程中確保高質量的輸出,除了確定開發過程中的品質,對於服務上線後的監控與反饋都必須有強烈的感知。

依據以往的經驗,針對測試領域的自動化方案,有幾個特徵值是需要被考慮到的:

  • 開發者導向:易於協作、易於維護;依據多元的使用場景、開發彈性;框架具有高擴充性、解決方案多
  • 使用者導向:易於切入、易於使用;產出報表清楚且易理解;結果具高可信度

街口支付自動化方案的開發者為測試團隊,而測試團隊的資源並不是只有一個人,因此需要有個「容易協作的環境且易於維護的框架」。首先,先工商一下 (笑),在招聘的初期對於測試團隊成員的篩選必須對 「開發」 不排斥,且各成員的技能樹不能有太多的落差,也因此團隊對於開發環境與語言的選定能有一定的共識,有興趣的測試大大們 歡迎投遞履歷 😎😎😎。「在測試框架與實作的維護領域」是另一個重點,依據康威理論 (Conway’s Theory) :「軟體的任何一部分都反應了創建它的組織結構」。在公司創立初期,街口支付的組織規劃依其名劃分為「街口服務」與「支付服務」,「街口服務」圍繞著叫車、外送、點餐,透過基本的服務建立街口的生活圈;「支付服務」則聚焦支付、轉帳、收款、繳費,讓使用者只要想到跟錢有關的服務就會聯想到街口支付。

但是隨著使用者數量的增加與服務的多元化,簡單的二分法已不足以支撐街口的業務量級,開發如此,測試亦是如此。測試框架的模組化與資料結構需要緊貼著開發的模式,一旦開發的結構邊界不明確,耦合過高,測試的元件也無法清楚定義,自然也不容易維護。如下圖,街口支付的開發前期僅先將大模組拆分,分為基礎服務與支付服務,而後隨著使用者的快速成長,需要將基礎服務拆分,每個團隊職責明確且清晰,在測試的範疇也能更為獨立。以測試獨立的角度而言,一旦開發人員改動了特定的模組,測試只要聚焦驗測該模組並做基本回歸即可,不僅省時、省力亦省資源。

承如上方所提,街口的成長迅速,業務邏輯也日漸複雜,因此在不同專案、不同目的、不同功能的前提下,「保證測試開發的彈性」則是自動化方案的首要目標。再者,依據使用者 (e.g. PM, QA, RD) 的需求,如果自動化框架能夠彈性的給予支持,於特定場景有特別的功能應用,那更會增加使用者的黏著度。假設 RD 在本機的 branch 只改了一個小功能,明確知道不會影響其他的模組,但又不想花大把的時間等待整合測試的結果, 只想在特定的測試集中跑特定的幾隻用例,那自動化框架的「高擴充性」的重要性就會提高不少,根據多元使用需求,依賴自動化框架的高擴充性進行開發,解決方案自然就百花齊放。

以使用者的面向進行自動化框架的分析,一般而言需要滿足三點需求,「易於使用」、「清楚呈現」、「結果具高可信度」。使用者接觸自動化的介面,只要操作順手,確定要的測試範圍有被涵蓋,剩下就是等待結果了,而等待時間的長短、報表的呈現與結果的可信度都是影響使用者是否相信且依賴測試自動化的因素。而對於「可信度的量測」,能夠針對各個 Job 的執行歷程進行紀錄並完成後續的分析,確定自動化的失敗全然是因為部署新的程式而導致錯誤,進而降低甚至排除過期的測試資料與其他人為因素,這樣的結果讓使用者增強對自動化解決方案的信心,進而形成正向的循環,測試只要依循「觸發」、「執行」、「檢視」、「紀錄」的步驟針對使用上的痛點進行修正,那麼一套基礎的自動化流程便應運而生。

根據上述所提到的需求且避免資源的重工,街口支付需要一個易維護、可擴充、適合高變動環境且擁有使用者友善的介面的開源自動化框架。

測試自動化方案選型

第一步,API 測試

在不同的組織內部,無論依循的開發方法論為何,像是 BDD (Behavior-Driven Development, BDD), TDD (Test-Driven Development, TDD), ATDD (Acceptance Test-Driven Development, ATDD), DDD (Domain-Driven Design, DDD),都有其適合的場景。依據 Mike Cohn 所提出的測試金字塔 (Test Pyramid) 理論,CP值最高的投資實屬 API 測試 (API Testing),唯有先熟悉前端與後端的溝通介面,了解不同的入參與出參,清楚每個需求的實作,一旦服務出錯了才能立即的指出痛點縮短開發定位錯誤的時間。

如下圖的 Best case,從測試金字塔的底部由從下而上的描述,API Unit Testing 涵蓋的功能領域最廣,依次則是服務中間層,再來才是大家熟悉的介面測試,而純手動或是探索性測試則為金字塔的最頂層,原因是使用者行為多元,且能涵蓋 E2E (End-to-End, E2E) 的測試範圍,但是純手動的測試有其無法彌補的缺陷,在精確度與測試速度方面並不如自動化方案來的有優勢。然而,自動化的開發需要有「顆粒度」的區別,依此測試金字塔不難發現,愈靠近金字塔頂端,自動化的程度與比例應該是最低的,反之,在最下方的 API Unit Testing 所耗費的成本最低、產生的效益最高、執行與開發的時間最短,重點在於成效快並可重覆利用,所以最適合提高自動化的比例; 中間的服務整合層,透過不同條件與場景的整合,讓功能進行交叉驗證,其中亦包含了 Fake source 與 Service Mocking 的準備,適合應用場景相對複雜與多元面向的驗證;最上方的 E2E 與 手動測試除了速度最慢,投資報酬率也是最低的,但因為能輕易的透過終端產品 (e.g. Mobile, Web…, etc.) 的使用者行為確認主要功能是否正常,因此對於需要追求快速的公司很容易落入盲點進而過份的依賴,僅確定完基本功能則直接上線,依此周而復始,容易進入一個耗時且耗力的循環,進而演變成下圖的 Worst case。

過於重視前端的手動驗測,對於提供基礎功能的設施與服務不熟悉,是很多測試人員的通病,也因此埋下了許多的隱患。

Worst case 所標示的,手動的部份佔了很大的一部份,小專案還好,但一旦涉及到大專案光是進行主要流程的驗測就是個問題,更不用提不同模組之間的功能交互,列出來的用例動輒上千。第一個遇到的問題就是「人員資源不足」,無法完整的測試,這也是為什麼很多公司一次性的招聘 20 到 30 位 QA,在短期內是可以大量的增添人力以補足資源不足的窘境,但長遠來說,耗費成本且整體效益也不高,因為一旦專案結束發現資源過剩,這些人力該怎麼處理?其次,則是因為這些測試人員熟悉手動驗測,理所當然的下一步則是進行終端產品的 UI 自動化,但以 UI 自動化而言,維護成本極高,即便是一行文案的改動也會讓維護人員花大把的時間確認問題。再者,因為 UI 自動化的一個案例主要驗測的僅有一個主要情境,因此如何選擇特定的案例完成自動化也是另一個問題。當業務需求變多或是些許的改動,測試的時間也會一再的被壓縮,漸漸的,熟悉流程的人員也會因為對於功能的熟悉而落入測試的盲點,耗費過多的時間與心力,對於測試團隊的影響巨大,不可不慎!基於以上原因,在街口剛開始自動化框架的選型階段,首先考慮 API Testing Automation Framework 的選擇,因為唯有穩固的打底,對於接踵而至的繁重業務,測試才存在快速支持的機會。

框架百百種 只要測的出問題的都是好方案

目前街口的基礎服務與支付的技術棧以 .NET Framework 為主,新創服務以 Python 為輔,測試的部份主要則以 Python 為基礎進行開發,一來開源的資源多、二來學習曲線低,因此自動化方案首選有支援 Python 的框架與工具做選擇。在剛開始調研時,選擇 API 測試開源工具知名度比較高的工具進行分析:SoapUI, Postman, Unittest, Pytest,分析如下。

SoapUI

  • 官網:https://www.soapui.org/
  • 語言:Groovy, Java
  • 適用場景:Web Service,包含REST API、SOAP API、GraphQL API等。

SoapUI 基於Java開發並支援多種平台,能夠透過簡易的點擊與拖拉針對 Web Service 快速的產出測試,但誠如他的名稱,主要是針對 UI 進行驗測,也支援 REST 服務的驗測,通過 Soap/HTTP 檢查、呼叫、實現 Web Service 的功能,也支援壓力測試與安全性測試,對於 Web Service Mocking 也有專屬的介面與方法,外部傳入測試資料的支援也相對齊全。

Postman

  • 官網:https://www.postman.com/
  • 語言:Javascript
  • 適用場景:Web Service,包含REST API、SOAP API、GraphQL API等。

Postman 具有完整的 API 測試環境並支援不同的認證機制,能針對過往的 API 請求進行紀錄與回放。對於 API 的手動驗測,Postman 提供的能力完善且擁有優秀的操作介面,在 API 的自動化部份亦有提供功能以監控 API 的回應與正確性,Postman Collection Runner 也能針對不同的 API 進行自動化的驗測不僅提供完整的報告,其中包含並不限於各 API 的回應時間與狀態。

Unittest

Unittest 為 Python 原生的測試框架,測試寫法相對拘束,必須遵循許多規則以求一致,如在 Unittest 中 setUp 與 tearDown 的寫法,對比於 Pytest 中針對不同級別 (e.g. Module, Function, Class,…, etc.) 都有特定的使用方式,而 Unittest 的基礎概念是許多自動化新手需要熟悉的,許多用法都需要互相引用與繼承 (e.g. test cases, test suites, test runner…, etc.),但是在 Pytest 中則相對簡易,直接針對 test 開頭的方法執行即可。

Pytest

Pytest 擁有簡易入門、文件豐富、Plug-in 多元 ( 315 種以上的 Plug-in 支援) 等特點,模組化的參數觸發與高度客製的 markers 讓 Pytest 比 Python 原生的 Unittest 框架更為好用,此外,在網上的聲量與社群討論,Pytest 的活躍程度高於原生的 Unittest 與 Nose2。以拓展性而言,Unittest 相對少應用亦不支援用例錯誤重跑的機制,對比於 Pytest,Pytest 支援失敗重跑且善用參數化能讓測試集的組合更為多元。以兼容性而言,以 Unittest 為基本,Pytest 可兼容 Unittest 的方法應用。因此,Unittest很適合剛踏入自動化領域的新手以鞏固其自動化的觀念,而 Pytest 適合已有自動化基礎的開發人員進行開發與拓展。根據 Python Developers Survey 2018 的調查,應用於 Python 的測試框架 Pytest 受到大多數人的喜愛,使用佔比約為 46%, 即便到了 2019 年的調查 (Python Developers Survey 2019),Pytest 仍為大多數的開發者的首選,佔比提升至 49%。

在自動化方案的選型上,團隊快速的達成了一致的想法:「以街口測試團隊的發展,在短時間內除了完善 API 測試也需要兼顧 UI 自動化的開發,而 Pytest 在 UI 自動化的應用亦能引用 Selenium 套件,在同一框架下能同時完成兩大面向的測試,一來測試開發人員的學習成本下降,二來更能針對集團的需求進行客製化」。基於以上的共識,團隊認可 Pytest 為相對適合街口需求的自動化方案。

全方案整合 All-in-One 自動化框架

每個框架都有其應用的領域,Pytest 除了在 API 測試方面很有彈性的應用,也能引用 Selenium 的套件完成 UI 自動化的驗測,因此在剛開始規劃時,團隊將自動化框架領域分成了兩大部份: API 自動化與 UI 自動化,以期符合街口所需求的 All-in-One 自動化框架。

在 API 自動化方面,依據組織架構與功能模組分成不同的 Component,透過不同的參數並使用 Data-Driven 的方式決定每一次所要執行的測試集,而參數的面向有可能是 Project-based 或是 Function-based,確保每次異動的部份都能透過 API 自動化的執行全面驗證過。當然不僅僅是基礎的 API 測試,根據不同的情境,團隊也透過各隻 API 的串接以模擬使用者的行為,在主要流程上確保每次的發佈都不影響基本功能的使用。在專案不間斷的過程中,成員們依序進行開發,達到的成果是非凡的,在短短不到一年的時間內,團隊產出了超過 2,500 隻的測試用例,其中完整覆蓋 “基礎服務” 與 “支付領域” 的所有重要邏輯,並確保每個 Component 的自動化所耗費讀時間不超過 5 分鐘。在此分享一個很重要的觀念,CBRT (Change-Based Regression Testing, CBRT) 能不能發揮具大作用與其執行時間有很大的關係,這也是為什麼在街口測試團隊的自動化需要在一定的時間內完成,即便結果失敗,測試人員也必須立刻進行反饋並進行後續的處理。如同之前所提及的,測試報告的正確性也會直接影響到使用者對於自動化的信賴程度,因此對於每個 Build 的結果紀錄與分析非常重要,對於測試而言,可以逐步修正自動化的精確度;對於開發而言,可以針對每次的通過結果以提高開發人員的信心與重視自測的必要性。

在 UI 自動化方面,維護成本相對高,一旦改動畫面的顯示,對於測試用例的修正都需要額外花測試人員的時間跟進。另外,在快速開發的過程中,若貿然進入開發 UI 自動化,容易造成資源的耗損卻無法得到預期中的效益。當然,UI 自動化的存在有其必要性,但在 API 自動化尚未完全覆蓋基礎功能面之前,UI 自動化的優先級自然稍微低了些。即便目前測試團隊主力並非放在 UI 自動化的開發,但是對於 UI 自動化的框架開發仍是不遺餘力,針對 App 與 Web 的使用者介面,團隊使用了 Appium 與 Selenium 以覆蓋大部份的基本用例,一旦之後有任何 UI 自動化的需求,此框架便能立即在 UI 自動化領域發揮其最大效益。

街口測試團隊選擇 Pytest 為想發展的框架,除了熟悉最基本的使用方式,更應該思考在不同的使用情境下拓展此框架的應用,以期在基礎框架上發展成符合街口需求的自動化方案,在後續的文章中會繼續與大家分享測試團隊在實現 All-in-One 自動化框架時所應用的場景、遇到的問題與解決方案。

JKOPay SDET Team

--

--