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

起因

過去在寫 End-to-End Testing 我都是用 WebdriverIONightwatch,直到今年 10 月才開始接觸 Robot Framework。會選擇 Robot Framework(後端為 Python)來寫測試的原因非常簡單,就是 follow 團隊先前的決定而已 XD 至於團隊為什麼要選它就不得而知了,據說是對於不會寫程式的 QA 來說,以關鍵字驅動(keyword driven)的口語化的撰寫方式會讓進入與熟悉門檻降到極低吧!

由於我寫 Nightwatch 時間比較長,加上 Nightwatch 與 WebdriverIO 個人感覺滿相似的,因此以下 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 天內就可以上手,但就是要花些時間轉換腦袋。

無法跟前端共用資料結構

這是指前端開發所帶入的資料,若想在測試時也一併使用,這是做不到的。如下,Python 的 dictionary 與 JavaScript 的 object 其中一個不同的地方就是 dictionary 的 key 要用單引號括起來,但 object 不用。在習慣上我在定義 object 的 key 時不用單或雙引號括起來,因此要搬用整個物件的時候,就必須檢查一下,並且加上單引號才能供 Robot Framework 所用。其實這非常廢話!不同語言就是要重新定義啊 XD ◢▆▅▄▃ 崩 ╰(〒皿〒)╯ 潰 ▃▄▅▇◣

在 Robot Framework 是這樣寫的。

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',],
    },
]

在 Nightwatch 是這樣寫的。

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'],
  },
];

回顧前面,list 是一個陣列,我們在轉換資料結構時痛過一次,等等若要 iterate 又會再痛一次喔(見上例 For Loop)。

UI 相關的 API 不足

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

如下,將畫面 scroll 到特定位置。

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

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

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

Scroll To Position    0,0

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

browser.moveToElement(elem);

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

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

在 WebderiverIO 是這樣寫的,這句程式碼的意思是將 elem 捲到畫面上。

elem.scrollIntoView();

總結

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

References


comments powered by Disqus