利用 Model Controller Testsuite (MCT) 來建構自動化測試

你一定知道 MVC 架構,那 MCT 呢

Model–view–controller (MVC) 架構是一種設計模式 (design pattern),主要目的是用來簡化應用程式的開發與增加程式的可維護性,其做法是將應用程式分成三個邏輯的模組。每一個模組都有各自具體的任務,這樣做是為了將資料的傳遞與呈現給使用者的結果分開表示,透過 MVC 設計模式將這些主要模組分離開來,以實現程式碼的可重複使用性以及根據任務需求分配並行開發。

基於 MVC 架構的優點,工程師也可以將 MVC 提供分層模組化架構的優點應用在開發測試的基礎架構上。因此,這篇文章主要說明以 MVC 開發設計模式為靈感的自動化測試架構 – Model Controller Testsuite (MCT),並描述如何調整以便讓自動化架構更加穩定和可維護。

該如何進行 MCT 設計模式

如上所述,該怎麼使用 MCT 來設計開發測試架構框架,針對自動化測試的 MCT 的設計結構主要分成以下三個模組:

  • Model – Data, resources, variables in env, tool
  • Controller – Keywords, libraries
  • Testsuite – Test cases

Model

MODEL 的功能就如同 MVC 的定義,它提供了完整的測試所需要的資訊,例如:變數值,所需要的執行工具,以及所需要的靜態檔案。工程師可以方便的維護每一個資料來源,以方便進行測試。 MODEL 這一層只會做為資料的更新或讀取,以及工具的使用,就像是不同的國家需求,不同測試環境上的需求,或是需要透過客製化工具產生的資料,透過 MODEL 來提供以上資料給 CONTROLLER 做使用。

Controller

Controller 主要是負責和 MODEL 和 test cases 互動的中間層,該層不但提供了整個測試架構所需要的函式庫,讓 test case 做使用,並且可以從 MODEL layer 獲得所需要的 data set 或是工具產生的資訊,經過該層應用後回傳相對應的結果給 test case。在 CONTROLLER,就像是各位習慣使用的 page objects design 設計模式或是自行開發的 library 都可以讓整個 test case 來做使用。假設你正在開發網站的自動化測試並且是使用 Selenium webdriver,在這個案例中,CONTROLLER 會提供工程師開發設計的 page objects,或是你有自己的 API 需求,該 library 也會被包含在 CONTROLLER 之中。CONTROLLER 處理了所有與 MODEL 這層的資料處理關係,以及透過 test case 的需求,傳回給結果相對應的測試。

Testsuite

TESTSUITE 只負責表達測試情境,不論是工程師或是和專案有關的管理人員只需要在該層提供規格或是規格轉化成的 test cases 即可。 你不需要考慮如何透過程式碼來開發整個測試邏輯,相關人員只需要知道得到的結果是不是符合預期。

使用 MCT 的例子

我們以登入 LINE TODAY 為例子,這個 test case 表示能夠成功登入 LINE TODAY。如下圖所示,登入成功後能夠正確顯示個人顯圖。針對這個 test case 我們需要的設計架構就包含:

LINE TODAY before and after logging in

Model

MODEL layer 提供了測試時所需要的使用者資料,以及相對應個變數值,包含 URL、國家,或是新聞分類等等。
MODEL layer 包含:

global_vars = {
    "USERNAME": "user",
    "PASSWORD": "passw0Rd",
    ...
}

tw_variables = {
    "COUNTRY": "TW",
    "TODAY": "https://today.line.me/tw"
    "CATEGORIES": [u"國內", u"娛樂", u"生活", u"鄉民", u"國際"],
    ...
},
id_variables = {
    "COUNTRY": "ID",
    "TODAY": "https://today.line.me/id"
    "CATEGORIES": ["News", "Showbiz", "Sports", "Life"],
    ...
}

Controller

CONTROLLER 在這裡提供了許多的 libraries 以方便讓 test case 來做使用。如下所示,你可以發現這裡也大量的應用 Page object 開發模式,讓開發者可以專注的設計網站的邏輯。

from selenium import webdriver
class LoginPage(self):
    browser = webdriver.Chrome()

    def click_login_entrance(self):
        """Click the login entrance"""
        browser.click_button(self.locator.login_entrance_button)

    def enter_username(self, username):
        """Enter the given string into the username field"""
        browser.input_text(self.locator.username, username)

    def enter_password(self,password):
        """Enter the given string into the password field"""
        browser.input_text(self.locator.password, password)

    def click_the_submit_button(self):
        """Click the submit button, and wait for the page to reload"""
        browser.click_button(self.locator.submit_button)

    ...

當然,工程師也可以針對測試的需求自行開發客製化的 libraries,開發屬於該專案使用的 libraries 最重要的目的是為了彌補 built-in library 的不足。例如:我們期望可以針對文章有 “ADD LIKE” 的功能,這樣的功能並不會在 built-in library 提供你想大量的按下 LIKE 個方式。如下所示,我們可以自行開發 “add_liked_to_article” library 在 CONTROLLER 中。

import requests

class SampleCodeAPI:

    def __init__(self):
        ...

    def add_liked_to_article(self, article_id, like_type, cookies):

        api_url = '{api_url}/like/add'.format(api_url=self.api_url)

        payload = {
            "article": article,
            "country": country,
            "likeType": like_type
         }

        res = requests.post(api_url, headers={"Cookie": cookies}, json=payload)

        try:
            return res.json()
        except:
            ResponseError("Response error")

Testsuite

TESTSUITE layer 這裡可以發現,我們只需要認真把規格案例或是測試案例寫在這裡,這就表示 QA engineers 可以更專注的思考測試案例的應用或是針對商業邏輯的驗證,就算不是工程師背景的專案人員依然可以寫下商業邏輯規格,這樣的方式也達到每個人員都參與了測試的過程。

*** Test Cases ***
    Given User go to LINE TODAY
    When Login with valid credentials
    Then Login as a normal user

在 LINE 台灣,我們選擇使用 BDD (Behavior-driven development) 的開發方式,BDD 這樣的開發模式讓軟體項目中的開發者、QA 和非技術人員或商業參與者之間的溝通順暢,已達到對於產品或是規格明確的共識。

結論

在測試自動化框架中具有這種分層結構的 Model Controller Testsuite(MCT)架構,可以容易的讓開發者在測試環境和基礎架構發生變化時保持彈性,不但容易維護且在開發上較為快速。 傳統上,架構上若太耦合,會使得測試內包含大量的 hard-coded 的測試程式或是測試資料,造成更改成本相當高,一旦工程師應用了 MCT 設計模式,便可享受到較低的維護成本,邏輯清楚的程式碼以及明確的測試案例。

Related Post