前端工程師寫 Robot Framework,可以嗎?

Robot Framework

起因

過去在寫 End-to-End Testing 我都是用 WebdriverIONightwatch,直到今年 10 月才開始接觸 Robot Framework。會選擇 Robot Framework(後端為 Python)來寫測試的原因非常簡單,就是 follow 團隊先前的決定而已 XD

至於團隊為什麼要選它,原因有二

因此,原先前端工程師所用的 WebdriverIO 就被捨棄,與後端統一使用 Robot Framework。

以下 JavaScript WebDriver 的例子以 Nightwatch 或 WebdriverIO 來輔以說明。

前端工程師可以寫 Robot Framework 嗎?

如果你是個前端工程師,正在找個 End-to-End Testing 的框架,你要選哪一個呢?WebdriverIO?Nightwatch?Robot Framework?若團隊傾向寫 Robot Framework,前端能寫嗎?以下有一些狀況也許是可以來好好評估或注意的。

寫關鍵字 vs 寫程式

Robot Framework 是利用「關鍵字」來寫 test case 的,每個關鍵字基本上就像是一句話,也就是說,每一個 test case 由一句或多句話組成,非常口語化。因此,對於不擅長寫程式的人來說,降低了進入與熟悉門檻;而對於喜歡看到程式碼的人來說,可能就會覺得太鬆散了,沒有 coding 的 feel。

如下是一個範例,用來在文字框輸入帳號 admin。做的事有…

Robot Framework 的寫法如下。

Open Chrome Browser To           http://www.sample.com
Wait Until Element Is Visible    css:body
Clear Input Text                 css:#userid
Input Text                       css:#userid    admin

除了使用 Robot Framework 官方提供的 API 之外,當然也利用關鍵字包裹一些功能,使其更抽象化、更易於使用。

Nightwatch 的寫法如下。

browser
  .url('http://www.sample.com')
  .waitForElementVisible('body')
  .clearValue('#userid')
  .setValue('#userid', 'admin'); // 輸入帳號「admin」

See?Robot Framework 就真的滿像日常講話的,而 Nightwatch 基本上就是前端工程師所熟悉的 JavaScript,較好上手,這就是寫我們前端工程師每天都在寫的程式碼而已。

乍看之下好像還可以接受?那麼…以下舉幾個簡單的例子來說明前端工程師到底有什麼煩惱,可以接受就歡迎跳坑喔 (o´・ω・)σ)Д)

語法差異太大

後端語言(以下使用 Python)和 Robot Framework 的語法與其 API 對前端所熟悉的 JavaScript 差異很大 (╥﹏╥)

第一個例子來看 For Loop。

在 Robot Framework 是這樣寫的。

@{list}    Create List    abc    edf

:FOR    ${item}}    IN    @{list}
\    ...

而在 JavaScript 可用 for、forEach 等來實作。

雖然看起來完全可以理解,但身為前端的我就硬是要從這麼基本的語法開始學起 _(┐ ◟;゚ д ゚)ノ

第二個例子來看條件判斷。

在 Robot Framework 是這樣寫的。

Run Keyword If    ...
... ELSE    ...

在 JavaScript 是這樣寫的。

if (condition  true) {
  // ...
} else {
  // ...
}

其他還有空白分隔(關鍵字內用一個空白分隔,關鍵字與關鍵字之間用 4 個空白分隔)…等,雖然還是可以理解,但就是有那麼一點差距。

學習這些基礎語法應該 3 天內就可以上手,但就是要花些時間轉換腦袋。

無法跟前端共用資料結構或共用檔案

由於 Robot Framwork 是 Python-based 的,因此無法跟前端共用資料結構或共用檔案,js 物件必須要轉換成為 json 格式,導致必須維護兩份資料。

在 WebdriverIO 或 Nightwatch 是這樣寫的,直接使用 JavaScript 物件即可。

const list = [
  {
    title: 'Dashboard Overview',
    menu: ['item 1', 'item 2', 'item 3'],
  },
  {
    title: 'Adding Widgets to the Dashboard',
    menu: ['item 4', 'item 5', 'item 6'],
  },
  {
    title: 'Creating a Widget',
    menu: ['item 7', 'item 8', 'item 9'],
  },
];

在 Robot Framework 是這樣寫的,要轉 json 格式。

list = [
    {
        'title': 'Dashboard Overview',
        'menu': ['item 1', 'item 2', 'item 3',],
    },
    {
        'title': 'Adding Widgets to the Dashboard',
        'menu': ['item 4', 'item 5', 'item 6',],
    },
    {
        'title': 'Creating a Widget',
        'menu': ['item 7', 'item 8', 'item 9',],
    },
]

UI 操作相關的 API 不足

面對 Robot Framework 沒有提供的 API 但前端又必須用到的,我們都會用終極大魔王 ◥(ฅº₩ºฅ)◤ 關鍵字 Execute JavaScript 在裡面直接包 JavaScript 程式碼或直接引入一個 js 檔案來實作,身為前端工程師的我在這當中就不斷跟自己說「其實還是在寫 JavaScript 嘛!只是外殼包了 Robot Framework 而已!」那…怎麼不寫 JavaScript 就好 XD

範例如下,若想將畫面 scroll 到特定位置,在 WebderiverIO 我們可直接使用 JavaScript 的 API 的 scrollTo 來做。

window.scrollTo(x, y);

Nightwatch 沒有這類行為,因為基本上會將元素捲到可視範圍內,當然也可手動使用 moveToElement() 將滑鼠移到這個元素上。

browser.moveToElement(elem);

若一定要是 scroll 這個動作,也可直接利用 Nightwatch 提供的 execute 執行 JavaScript 程式碼。

browser.execute('scrollTo(x, y)');

在 Robot Framework 是這樣寫的,我們先定義一個新的關鍵字「Scroll To Position」,然後包一些 JavaScript 來做捲到特定位置的動作。

Scroll To Position
    [Arguments]                 ${position}
    Execute Javascript          return window.scrollTo(${position})

或直接引入一個 js 檔案。

Scroll To Position
    [Arguments]                  ${position}
    Execute Javascript           ${CURDIR}/scroll.js

這個 scroll.js 會放一個 IIFE 來立刻執行。

return (function() {
  window.scrollTo(position);
})();

然後在 test case 中使用這個關鍵字。

Scroll To Position    0,0

無法 Mock 資料

雖然說 End-to-End Testing 應該要用實際在機器上的資料,但生資料做測試這件事情是要靠後端的,靠別人有 dependency 總是不開心 XD 若用 WebdriverIO 或 Nightwatch 就可以做 mock request,只是這樣的測試就不夠真實…各有利弊。

總結

身為前端工程師,我在撰寫 Robot Framework 的時候,起初最常遇到的問題是對於 Python 或 Robot Framework 語法的不熟悉,畢竟 Nightwatch 或 WebdriverIO 的 API 都還是用 JavaScript,順手多了!後來雖然稍微熟悉了,但寫起來對 UI 的操作的 API 就是少一些,導致我們需要利用 Execute JavaScript 創建新的關鍵字並在裡面包 JavaScript,多此一舉又十分麻煩,不推不推!之後想到什麼或遇到什麼再來補補吧!

References


comments powered by Disqus