[30天快速上手TDD][Day 21]ATDD - Acceptance Testing

[30天快速上手TDD][Day 21]ATDD - Acceptance Testing

前言

上篇文章提到了,系統與程式碼存在的目的,就是為了滿足使用者的需求。

因為我們需要一個方式來定義與管理使用者的需求。本系列 TDD 的文章,則是以 user story 為例。而 user story 除了需要簡單扼要清楚的描述使用者的需求,還要確保團隊中每一個角色(包括使用者)都能理解以外,另一個重點就是 user story 通常需要 acceptance test cases 來輔以說明,該 user story需要滿足哪一些驗收測試案例,才能稱為完成。

上一篇文章有提到,通常會使用 user story card ,而驗收測試案例,通常就會寫在 user story card 的背面。

因此,這一篇文章就要針對 acceptance testing 來進行說明。

 

What - 什麼是驗收測試

驗收測試(Acceptance Testing)是系統行為與功能面的規範,用來說明某一個 user story ,系統在特定情況下應該完成什麼樣功能,以及針對某一些輸入,應該具備怎樣的輸出結果。

更重要的是,是從使用者的角度來檢視,系統是否能正常運作(是否符合使用者的期望)。

基本上驗收測試有幾個 feature :

  1. 使用者為 owner :
    使用者為最後的驗收人員,所以使用者最有資格、也最應該來撰寫驗收測試。讓使用者來主導,而由有經驗的測試人員與開發人員輔助撰寫測試案例,最大的好處除了成員具有參與感,在一開始就達成共識,朝向同一目標前進以外,也可以避免開發出來的功能使用者不認帳。(但絕對可以迅速調整,時程與 priority ,則屬 Scrum 的討論範圍,本文章篇幅限制就不多加著墨)
  2. 由使用者(或是 Product Owner 代表)、開發人員、測試人員一同撰寫
    由這三種角色來共同撰寫驗收測試案例,有其目的與對應的好處,請參考本文後半段 Who 的部分。
  3. 重點在 What 而不是 How:
    與 user story 的精神相同,驗收測試案例的重點在於該有什麼樣的功能,用什麼樣的方式,能代表滿足這個 user story ,也就是這個使用者需求。

    太著墨於 How 的部分,容易失焦、失去設計彈性、失去需求異動的彈性、增加重工的機率與成本、增加未來討論與製作 prototype 的成本。
  4. 用 domain specific language 來描述
    驗收測試案例是使用者最後要驗收的方式,所以使用者要看的懂。

    開發人員需要瞭解使用者要什麼樣的功能,透過什麼樣的方式,來處理與呈現相關的資料流,所以開發人員也需要瞭解在這個問題領域的 domain know-how 。

    測試人員則需輔助使用者與開發人員,建立起兩個角色之間的橋樑,共同擬定出一份大家都看的懂,也都能朝向這個目標走的驗收測試案例。(測試人員還需要考量如何自動化驗收測試)

    因此,為了滿足上述三種角色的需求,使用 domain specific language 來描述驗收測試案例,是最好的選擇。

    可以避免技術人員使用使用者看不懂的火星文,透過 domain specific language 也可以避免被技術平台、工具或語言綁定了該怎麼實現這個功能或需求,如下圖所示的情況:
    使用者與開發人員
  5. 簡潔、準確、無異議的描述
    夠抽象,就可以穩定。夠簡潔,就可以減少擬定測試案例的困難與成本。重點在於在程式碼還沒撰寫前,三個角色可以迅速的達成共識(包括推翻先前的 user story 與測試案例,都要夠迅速、無痛)

 

Why - 驗收測試的目的與好處

透過驗收測試,我們可以得到什麼好處:

  1. 提供「完成」( done )的定義:
    在 Scrum 中,完成的定義相當重要,因為那是用來衡量團隊的產出進度與預期是否有落差。是否該迅速調整相關的 user story ,Scrum Master 要迅速找出團隊的問題等等...

    有了完成的定義,重點就在於我們可以瞭解兩點:「知道我們現在到哪了」以及「知道什麼時候該停止」。這可以幫助我們避免出現 scope creep 的問題,以及 gold plating 的問題。

    因為我們目標明確,可以清楚瞭解還差多少,完成時也可以清楚地知道,目前已經完成了。

    驗收測試案例可以幫我們在該停的時候停,不會太早,也不會太晚。
  2. 團隊協同合作
    如同後面段落 Who 會提到的,讓整個團隊都有參與感,就會是一個擁有共同目標的團隊,就像划船一般,大家都有著相同的節奏,並且朝向同一個目標、方向努力,互補有無,截長補短,成就共享。
  3. 兌現承諾並贏得信任
    當一開始一起訂出的 user story 與驗收測試案例,可明確的被執行無誤,並且通過驗收時,這代表著一開始的承諾沒有跳票,大家的目標一起被完成,而且是可行的,不是亂開芭樂票。這會逐漸累積團隊的士氣、信任感,並且可以幫助未來預估不同的 user story 的開發時程更加精準。
  4. 透過有意義的例子驗收
    驗收系統,不只是像規格/說明書一般,看看每一個頁面、看看每一份文件,或是打開繁複的程式碼或資料庫,確認是否是使用者要的。

    而是把使用者的需求,轉成一個個的故事,上面有著目的( benefit ),有著誰( as a role ),有著該有的功能( goal ),有著不同的情境底下,滿足了這些測試案例,即代表著這個故事完成。

    不只是程式碼會說話,連驗收測試案例都在幫這個系統與使用者說故事。
  5. 彌補測試與實際環境(絕大部分先是模擬環境)運行之間的差距
    單元測試雖可以隔離每一個物件之間的關係,單獨的測試每個物件的獨立運作是否符合預期。但不能保證物件之間協同合作是否仍能正常運作。

    而整合測試只能確保在多個單元測試所模擬物件的行為的組合情況下,針對某一些流程或模組,在黑箱測試的執行過程中,最後的 input/output 仍符合預期。但不能保證,使用者看到的,會跟整合測試的結果相同。也有可能整合測試是對的,但不是使用者要的方式。

    驗收測試從一開始就是由使用者出發,使用者為 owner ,使用者撰寫,使用者最後進行驗收,這幾乎等同於未來系統實際上線的使用情境(差異可能是在仿真的測試環境,例如 beta, pre-production 環境),這可以彌補單元測試與整合測試的不足。

    但這並不代表就不需要單元測試或整合測試,還記得嗎?越高層的自動化測試程式,通常會因為需求而越不穩定。

註:之前的新聞,新買的火車普悠瑪號,規格沒問題,測試也都沒問題,實際要進月台時,卻因為太胖卡住,最後得花了一大把的功夫,動用不少人力與資源,才削足適履的讓火車可以進月台。如下圖所示:
火車卡住
這就是很標準單元測試跟整合測試都通過,最後上線爆掉的例子。

 

When - 什麼時候撰寫驗收測試案例呢?

上一篇文章提到了軟體開發的 V-Model,這邊則要帶出來,在 ATDD/TDD 的流程中, V-Model 會加上幾個箭頭,如下圖所示:

v-model with TDD

從上圖可以看到,當需求分析後,基本上我們就擁有該需求所對應的 user story ,接著針對user story ,我們就將驗收測試案例寫在該 user story card 的背面。

在開始開發該 user story 任何程式之前,驗收測試案例應該要已經建立完畢。

當然,驗收測試案例是可以隨著需求而修改、增加、刪除的,如同 user story 一般,要 focus 的是在這樣的描述,是否就可以滿足使用者的需求,而不是 focus 在上面要有哪些細節。細節越多,彈性就越小,重工的 effort 就越大。

 

Who - 由誰來撰寫驗收測試案例

如前面 feature 所提到,驗收測試案例,是在 Product Owner( PO )定義好 user story ,或是分析人員( Scrum 中不一定有這個角色)、測試人員、開發人員與使用者,針對 user story 所需要的功能,一同定義出該怎麼來驗收這個 user story 。

該用哪些測試案例,才能代表使用者這個需求的全面性。

有哪一些測試案例的輸入/輸出值,是特別具有代表性的,驗收測試案例的撰寫,是由使用者、開發人員與測試人員一同撰寫,這樣可以兼顧領域專家(使用者)、技術專家(開發人員)、兩者兼顧的專家(測試人員)的全面性,確保訂出來的驗收測試是符合使用者行為與預期,並且開發人員不會有技術上的問題,測試人員也可以針對其思考如何自動測試與驗收。

 

Where - 該針對哪些部分進行驗收測試

是否該針對 UI 來進行測試?還是針對 API 或商業服務介面來進行測試?還是針對每個模組、物件或單元來訂立驗收測試?

答案是不一定。

但原則就是,用最少的功夫,獲得最大、最真的效果。且要使用者、測試人員、開發人員都有共識,一起埋單。驗收測試基本上還需要彌補單元測試或整合測試,所不能涵蓋到的範圍,也就是與使用者實際使用,這中間的差距。

至於哪些部分可以用仿真的資源,哪些部分在開發或測試環境,還是一定得用模擬的資源來代替,這也沒有特定答案,該由三個角色共同定義與承擔。

原則仍是:

  1. 要足夠接近真實系統
  2. 要能開發與測試

 

Sample

這邊有個簡單的範例給讀者參考一下:

sample

User story 是要協助客服人員可以在螢幕上顯示,打電話進來的客戶的歷史資料。

其中驗收測試案例,可能就如下圖所示:

accetance test cases

這樣的驗收測試案例甚至可能太細,不過只要使用者、測試人員與開發人員都有共識,又不會花太多功夫,就是個好的驗收測試案例。

 

小結

驗收測試案例,是一個承上啟下的重要角色,從使用者需求,轉變為 user story ,接著透過驗收測試案例來輔助 user story ,讓團隊中每個角色都可以迅速的達成共識,用最短的時間,最小的力氣,精準明確的滿足大家共同的目標,並迅速呈現結果給使用者,快速回饋是否如同大家預期一般,節省溝通、重工成本。

驗收測試案例,也是第一份由團隊中每個角色所共同撰寫的系統的說明書,有了使用者需求,有了如何確定這樣的需求完成,才會有個可行走的骨架(Walking Skeleton)系統,才會是一個可以滿足使用者需求的 working software ,也才會有後面TDD所需要的整合測試案例,也才會有後面單元測試需要的單元測試案例。

測試案例,是整個系統中最重要的文件,而這一份文件,應該要能用 domain specific language 來描述,又要能被自動化的執行。每個角色都依據測試案例來設計、開發、討論與驗收,最後就能把整個系統開發流程從需求收集/分析階段開始,一路到設計、開發、測試、驗收,一路打通,一次搞定,中間沒有太多轉換的 effort,沒有太多無謂的重工,沒有太多溝通的成本,沒有互相推諉責任、往下壓榨的情況發生。

很烏托邦的願景,對吧?

但相信我,它是真的可行的!

後面的文章就會介紹到,如何讓測試案例這一份文件,既能用 domain specific language 來描述,又能被自動化的執行。

對敏捷開發有興趣的朋友,可以參考我的粉絲專頁:91敏捷開發之路

對 TDD 課程有興趣的朋友,課程內容、大綱與學員心得,可以參考 skilltree 的公開課程:自動測試與 TDD 實務開發

若需要聯絡我,可以透過粉絲專頁私訊或是側欄的關於我。