在 UCI 的第一個 quarter 結束了。身為一個在台灣也念過一陣子博士班的人,對於在國內外念書尤其是做研究的環境差異有些粗淺的經驗分享。

學習動機

首先是(國際)學生的學習動機。漂洋過海來的國際學生,在繁複的申請流程中就已經初步確認了動機,畢業後的目標也很明確,到校後就算沒有動機,為了畢業,課業上也不太會打混,這很明顯的反映在全班平均成績上。在大家都滿認真的情況下,自己相對地也會比較辛苦。另一方面,我最喜歡的是 lab meeting 時討論的氣氛,因為美國碩士可以不用寫論文,而大部分目標放在工作的碩士生,沒興趣也不需要做研究,換句話說,會來參與討論的都是對研究有興趣的人。這個制度一方面讓博士生有更大的 lab 空間 (碩士生沒有座位),一方面又可以減少參加 lab meeting 的人數,讓會議得以更有效率及建設性地進行。在台灣因為碩士也要寫論文,如果學生對研究沒興趣卻被逼著做研究,跟他們在研究上的互動簡直是對彼此的折磨 (報個 paper 報得亂七八糟,問個問題也一問三不知)。但是這是否代表台灣也該引進 course track 的碩士制度?不一定,因為台灣跟美國的環境不同,來美國念碩士的國際學生,很多人根本已經有數年工作經驗,或這是他們的第二碩士,換言之,他們已經有解決問題的能力,只是需要學位當作工作的敲門磚而已;而台灣碩士班的學生大多是大學直升,學習動機也有差,寫論文能學到的解決問題的能力也的確是修課(聽講、作業、考試)學不到的。

修課壓力

其次是修課,UCI 是 quarter 制,以一般 CS 相關課程來說,在 10 週之內會完成 3 次程式作業加期中期末考,所以通常一開學就會處在備戰狀態了,跟學期制前兩週還在收心閒晃決定要修什麼課的氣氛差很多,也因為節奏緊湊的關係,修個三門主課就大概會耗掉全部的課餘時間,因為你沒有太多時間慢慢準備作業跟考試。壓力是有的,但我個人反而比較喜歡這種節奏,可以早點把 coursework 處理完,然後專心在研究上。對於有工作經驗的人來說,修課不是什麼難題;對博士生來說,修課對研究也不一定有幫助,所以能早點結束比較好。對於只是需要學位求職的人來說,碩士通常 4 個 quarter (1年3個月) 就可以拿到,也比較理想。

討論課與大量閱讀

上面提到的”修課不是什麼難題”指的是類似我們在台灣上的傳統課程(聽講、作業、考試),但是這裡有另外一種課程是類似討論課,也就是讓你課前讀 paper 寫摘要評論,課堂上發言討論的,對我這種習慣傳統 CS 課程的學生來說就會痛苦很多,一方面是讀寫說的速度都不如 native speaker,一方面是不習慣上課發言。像我這個 quarter 剛好修到兩門都是這種的,一個禮拜要讀 6-8 篇 paper,課前要繳交摘要評論,上課太安靜也會被點名發言。尤其如果你的 program 或 department 有些跨到社會科學領域,像我所在的 Software Engineering program / Informatics department,就一堆這種課,有的甚至是混合,不只要讀 paper 寫評論,程式作業也沒少的。我只能說我的修課壓力大部分來自這種課,不過經過第一個 quarter 的洗禮之後,我體認到這種課才是我,或說一個博士生需要的,因為這剛好可以增加我的知識廣度、訓練我的思考跟表達。當然對於碩士生來說就不一定需要。

研究發表

以博士生最主要的工作跟畢業門檻:發 paper 來說,雖然我還沒有資格多嘴,但我可以肯定的是在台灣念絕對能發 top conference or journal paper,我在台大跟清大實驗室的同學跟學長們就是最好的實例,我自己之前在台大做的東西最近也上了不錯的 conference;找教職方面則不得而知,但台大電機與清大資工近年也聘了幾個土博助理教授。單純就發表來說在台灣念是沒有問題的。

經濟支持

最後還是要回到現實面,我覺得支持博士生自保生活無虞,應該是對於學校最基本的要求,這已經跟直接就業能賺到的錢比起來少很多了。我個人經驗是:在美國雖然拿的錢仍是低收入戶等級,一般博士生的 support package (e.g. 學費全免, 做 TA 或 RA 賺生活費) 至少能自保生活無虞;在台灣則很難說,跟你研究的領域是否熱門、老闆接計畫的能力、組織是否有錢 (例如中研院的博士學程) 高度相關,大好大壞都有,而我是偏壞的那邊。或許我也該感謝這個因素推了我一把。 (待續)


因為工作的關係又碰到了 Robot Framework,之前用它寫 test case 時比較隨性,這一次因為要將其導入並介紹給團隊,花了些時間看了官方文件跟一些 best practices,也有些實作經驗可分享。

什麼是 Robot Framework, 它能做什麼

Robot Framework 簡單來說就是一個讓你撰寫 keyword driven script 的 framework. 根據你想做的事情引入不同的 library 之後,就能使用各種 keyword 去兜出你想完成的工作。所以理論上它能夠做到 Python 可以做到的任何事情,反正如果沒有現成的 library 或 keyword 就自己寫即可。例如我們寫 Python 時經常用 requests 與 server 溝通:

import requests

url = 'http://yourhost.com'
payload = {'uname': 'user', 'pwd': 'password'}
resp = requests.post(url, data=payload)
print resp.status_code  # 200

如果改用 RobotFramework 來寫的話,就引入 RequestsLibrary 即可:

*** Settings ***
Library  RequestsLibrary

*** Test Cases ***
Post request
  Create Session  my_session  http://yourhost.com
  &{params}=  Create Dictionary  uname=user  pwd=password
  ${resp}=  Post Request  alias=my_session   uri=/  data=&{params}
  Log  ${resp.status_code}

我們可以看到 Create SessionPost Request 等 keywords 就是在做 requests 的 requests.post(),而事實上 RequestsLibrary 也的確是 requests 的 wrapper, 把 requests 能做到的事情打包成 keywords 讓你在 Robot Framework 裡面使用。再看一個 webdriver 的例子,用 Python 驅動 browser 去點擊或輸入網頁是這樣寫:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://yourhost.com')
element = driver.find_element_by_id('THE_ID')
element.send_keys('VALUE')
element = driver.find_element_by_xpath('THE_XPATH')
element.click()

在 Robot Framework 中則是引入 Selenium2Library:

*** Settings ***
Library  Selenium2Library 

*** Test Cases ***
Open browser and run
  Open Browser  http://yourhost.com  chrome
  Wait Until Element Is Visible  id=THE_ID
  Input Text  id=THE_ID  VALUE
  Wait Until Element Is Visible   xpath=THE_XPATH
  Click Element  xpath=THE_XPATH

同樣地,Open Browser, Wait Until Element Is Visible, Click Element 等都是 Selenium2Library 提供的 Keywords。當然,你也可以用 Keywords 組成自己的 Keyword (Wait And Click, Wait And Input):

*** Settings ***
Library  Selenium2Library 

*** Test Cases ***
Open browser and run
  Open Browser  http://yourhost.com  chrome
  Wait And Input  id=THE_ID  VALUE
  Wait And Click  xpath=THE_XPATH

*** Keywords ***
Wait And Input
  [Arguments]  ${locator}  ${text}
  Wait Until Element Is Visible  ${locator}
  Input Text  ${locator}  ${text}
  
Wait And Click
  [Arguments]  ${locator}
  Wait Until Element Is Visible   ${locator}
  Click Element  ${locator}

如果沒有現成的 Keywords 可用,自己寫一個也很方便,例如這個做 Base64 編碼的 class:

import base64

class Base64Library:
    def base64_encode(self, text):
        return base64.b64encode(text)

只要路徑正確,就能在 test script 內引用自己定義的 keyword (Base64 Encode):

*** Settings ***
Library  Base64Library.py

*** Test Cases ***
Self-defined Keywords
  ${encoded}=  Base64 Encode  abc123  
  Log  ${encoded}  # YWJjMTIz

當然常見的變數宣告、參數、If-else、迴圈等,也都可以使用。

為什麼要用 Robot Framework

雖然 Robot Framework 可以做到幾乎任何 Python 能做的事情,但看到這邊你一定有個疑問:為何我還要為了這個 framework 去查各種 library 與 keyword 的用法,直接寫 Python code 不是快得多嗎?沒錯,如果只是要翻譯 Python code,根本不必用到這個 framework,這個 framework 是用在自動化測試,尤其是自動化驗收測試 (acceptance testing) 上的。使用 Robot Framework 做自動化測試的好處有:

  • Keyword Abstration. 從前面的例子可以看到,雖然我們能夠直接寫 Python code, 但是 Robot Framework 有可能已經幫我們把好幾行程式碼濃縮成一個 keyword,例如使用 webdriver 時我們常常在等某個 DOM element 出現,在 python 裡面可能要寫個 try block 之類的去處理,但用 Robot Framework + Selenium2Library 一個關鍵字就搞定了 (Wait Until Page Contains / Wait Until Element Is Visible等);另外 keyword driven script 對於程式經驗較少的人來說也會比 Python 或 Java 程式碼容易上手;最後,自訂關鍵字的架構更可以把操作步驟一路抽象到自然語言層級,達到 “Test case 即註解” / “Test case 即文件” 的地步。這部分後面會再說明。

  • Test Report and Jenkins Integration. 它的報表與 Jenkins 整合功能大概是很多人選擇它的原因。Test script 執行之後會自動產生 HTML log,若 test case fail 會顯示停在哪一步,若是可以抓圖的話也會幫你把畫面抓下來,如下圖。當然它也支援一些測試相關功能,如 tag, test setup/teardown 等,Jenkins 也有 plugin 能顯示報表內容。

2016-07-28-rbfk

  • Human Readable Acceptance Test. 把 test case 的步驟用自然語言描述,讓不寫程式的人 (工讀生/PM/老闆) 都能看懂,是 Robot Framework 官方文件的建議寫法,但很多人往往只著重在把程式邏輯翻譯成 test script,這樣固然可以享受到 Robot Framework 的測試報表及 CI 整合等好處,但沒有利用到它全部的優點,比較可惜。以下分享一些 best practices.

Robotframework 的 Do’s and Dont’s: 怎麼寫易維護的 Test Case

剛開始寫 Robot Framework test script 的人,往往著重在把測試程式的邏輯翻譯成 keyword 的形式,這個起手式沒錯,例如上面的 webdriver 例子,直接等待並操作 DOM elements:

*** Settings ***
Library  Selenium2Library 

*** Test Cases ***
Open browser and run
  Open Browser  http://yourhost.com  chrome
  Wait Until Element Is Visible  id=THE_ID
  Input Text  id=THE_ID  VALUE
  Wait Until Element Is Visible   xpath=THE_XPATH
  Click Element  xpath=THE_XPATH  
  ...

用了一段時間之後,你可能會將測資設為變數,增加使用彈性,也可能把常用的實作細節包裝成自訂 keyword, 例如:

*** Settings ***
Library  Selenium2Library 

*** Variables ***
${HOST}  http://yourhost.com
${BROWSER}  chrome
${TEST_VALUE}

*** Test Cases ***
Open browser and run
  Open Browser  ${HOST}  ${BROWSER}  
  Wait And Input  id=THE_ID  {TEST_VALUE}
  Wait And Click  xpath=THE_XPATH
  ...

*** Keywords ***
Wait And Input
  ...

Wait And Click
  ...

做到這一步其實已經有一定的彈性,但還是有一些缺點,最明顯的就是只看得出 test case 怎麼做 (How),但看不出它在做什麼 (What)。你要測試的 test requirement (system responsibility),與實作細節 (按鈕的 Xpath 或 id) 顯然無關。另外,如果其他 test script 也要用相同的自定義 keywords 怎麼辦?或日後 test case 一多,該如何降低維護成本?要比較好地處理這些問題,我們要回到驗收測試的基本精神:驗收系統功能,在不知道系統的介面及實作細節的前提下,利害關係人一樣知道系統該做什麼。因此,把系統功能步驟以自然語言的描述方式留在 test case 層級,實作細節留在 keyword / library,並把常用的實作細節抽出來方便重複引用,就是官方推薦的使用方式。例如若要驗收從瀏覽器登入的功能,以下是一個可能的寫法:

*** Settings ***
Library  Selenium2Library

Resource  resource.txt  # 有 Wait And Click, Wait And Input 等
                        # 其他 test script 也會用到的 keywords
			
# 每個 test case 開始前與結束後需要的步驟可寫在 Setup 與 Teardown
# 或是整個 test suite 所需的步驟可以寫在 Suite Setup/Teardown

Test Setup  Proceed With Login Page
Test Teardown  Close All Browsers

*** Variables ***
${HOST}  http://yourhost.com
${BROWSER}  chrome
${USERNAME}  user
${PASSWORD}  pass
${EMPTY_USERNAME}  ${EMPTY}
${EMPTY_PASSWORD}  ${EMPTY}

*** Test Cases ***
Valid Login
  Login With Valid Credentials
  Dashboard Should Be Presented

Invalid Login
  Should Reject Invalid Credentials  ${USERNAME}  ${EMPTY_PASSWORD}
  Should Reject Invalid Credentials  ${EMPTY_USERNAME}  ${PASSWORD}

*** Keywords ***
Proceed With Login Page
  Open Browser  ${HOST}  ${BROWSER}
  Wait Until Page Contains  Welcome

Login With Valid Credentials
  Login With Credentials  ${USERNAME}  ${PASSWORD}
  
Login With Credentials
  [Arguments]  ${uname}  ${pwd}
  Wait And Input  id=username  ${uname}
  Wait And Input  id=password  ${pwd}
  Wait And Click  id=submit

Dashboard Should Be Presented
  Wait Until Page Contains  dashboard

Should Reject Invalid Credentials
  [Arguments]  ${uname}  ${pwd}
  Login With Credentials  ${uname}  ${pwd}
  Wait Until Page Contains  Invalid username or password

這樣寫有什麼好處呢?第一個是把 test requirement 與實作細節分開,如果只看 test case,任何人都能輕易了解第一個是在測合法登入,登入後要看到 dashboard;第二個是在測非法登入,並且分成空的密碼與空的使用者名稱兩種,只關心功能的人完全不需要知道怎麼實作。另外,盡量抽出重複的實作,如果實作細節改變了 (例如登入鈕的 id / xath 改了),就能把修改成本降到最低。很多公司完全沒有導入自動化測試,因為維護 test case 是需要成本的,而成本主要來自兩個地方:需求變動與實作細節變動。把這兩個地方拆分有助於降低維護成本。你可以想像若直接把程式邏輯翻譯在 test case 層級,當需求變動時,我們必須花時間去看這一段邏輯是在做什麼事情;若實作細節改變了,就得大改一堆 test case。所有花在了解 test case 的時間,都在消耗工程師的生產力。

這份文件這份投影片建議了 Robot Framework 的 Do’s and Dont’s,我摘錄如下:

  • Test case 的命名: Tell what, not how
  • 使用變數取代 hard coding
  • 適當的抽象化
  • 用等的 (Wait Until…) 而不是睡的 (Sleep)
  • 讓 test case 自我描述,非必要不使用 document/comment
  • 盡量不要讓 test cases 有相依性
  • 盡量不要在 test case 層級有 variable assignment;複雜的邏輯如迴圈等盡量放在 library

這份文件在講如何寫易維護的 test case,原則如上所述,也可以看看。

Robot Framework 與 Jenkins 的整合

與 Jenkins 的整合似乎就沒有什麼好講的了,就該裝的 plugin (robotframework, virtualenv) 裝一裝,該設定的 dependency 設一設。我目前做的事情是把一些手動測項改寫成 script,導入 Robot Framework 由 Jenkins 驅動。每當待測程式有新版的 build, 就從 git server 上把 script 拉下來, 建一個 virtualenv, 把最新版 build deploy 到機器上做 regression testing. 瀏覽器的部分在寫 script 時是用 Chrome webdriver, Jenkins 上是用 PhantomJS 跑 headless.

雖然說是自動化測試,但目前在業界還是手工藝,只能把一些簡單或常規的測項寫好之後讓它重複跑,省去 regression testing 的時間,讓 test engineer 能夠把心力放在複雜的測試上。至於真正的全自動化測試,目前還是在學術研究的階段,必須搭配自然語言處理與機器學習的進展,也是我的研究興趣。


如果你曾在網路上看過程式設計師最常回答的20句話,你可能有印象其中好幾句都跟程式執行結果的不穩定性有關,例如”程式昨天還好好的”、”之前不會這樣”等等,而第一名:

“It works on my machine.”

除了讓人會心一笑之外,也點出了在軟體測試在實務上的問題:需要測試的環境組態太多,且輕微的組態差異就可能造成不同的程式行為或結果(註)。Google Testing Blog 最近的文章: Flaky Tests at Google and How We Mitigate Them 就提到了 Google 內部的情況以及他們的處理方式。這篇文章將 flaky tests 定義為 “在一樣的待測程式、待測環境及測試程式碼下,測試結果有時候 pass, 有時候 fail 的那些 test cases”,中文姑且稱之為不穩定的測試個案。不穩定的測試個案會造成什麼影響?可能會大幅降低 programmer 的生產力:

  1. 對於 falied test 要花時間去看錯在哪裡, 花時間 debug
  2. 一時之間找不到 bug, 再花時間重跑 test 看看, 結果竟然過了?!
  3. 若此情況發生多次, developer 對於 test 的效力就會失去信心, 以後看到 failed test 可能就直接略過 (忽略了真正的 bug), 或是多跑幾次看會不會運氣好 pass (又是時間的浪費)

因此, flaky tests 對於軟體品質跟工程師的生產力傷害甚鉅。你可能會好奇為什麼同樣的環境下測試為什麼有時候會過有時候不過?文章中提到了幾個 flaky test 的成因,例如:程式本身的行為就是不確定的 (Nondeterministic)(例如程式內會根據隨機產生的值有相對應的行為)、所用的 third party code 不穩、環境問題等等。ICSE’15 的這篇論文也提到了影響 System GUI Testing 可重複性的幾個因素:

  1. 執行環境,例如不同 OS,不同 browser,不同的 Java 版本,甚至只是 Oracle Java 與 OpenJDK 的不同也會有差
  2. 程式啟始組態與輸入檔
  3. 自動測試工具的設定 (以 GUI 測試來說最常見的就是每個動作的間隔時間)
  4. 其他無法控制的因素,例如以程式啟動的時間日期做 random seed 等

論文中也提到:就算把前三個變因都控制到一模一樣,還是無法避免程式在 code coverage 或 GUI 畫面上會出現不同的測試結果。那 flaky tests 在 Google 內部出現的情況如何?文章中提到兩個統計數據:

  1. 全部的測試中有 1.5% 是 flaky tests
  2. 在程式提交後的自動測試 (post-submit testing), CI (Continuous Integration) 系統找出的由 passed 變成 failed 的 tests 中, 有 84% 含有 flaky tests

比例不算低,而 Google 用了一些方法去對應 flaky tests:

  1. test 連續 fail 三次才標記為 fail (降低是 flaky test 的可能性, 但就多了執行時間)
  2. 對於 test 可以標記其 flakiness (我猜是人工標註), 自動把高 flakiness 的 test 放到隔離區, 日後處理, 以免影響整體測試.
  3. 目前正在試著從 code 或 execution traces 裡找出與 flakiness 有高度相關的 features

而上面提到的論文也建議了一些讓 System GUI Testing 可重複的一些建議步驟:

  1. 確保執行環境是有紀錄的,且保持一致
  2. 同一個 test case 跑多次再確定結果
  3. 注意 application specific 的要求 (例如用到執行時間做 rand seed, file/network permissions, memory 要求等)

其實可以看到目前還沒有什麼好的解決方式。

註:專門探討如何系統化測試程式的各種參數或環境組合的研究叫做 Combinatorial Testing, 這篇論文有廣泛的回顧


PyConTW 是 Python 社群的年會,可以看看各地的 Python 使用者做了什麼有趣好玩的專案。每個人平常可能都專注在手頭上的工作,所以參加社群聚會是一個啟發創意思考,學習新知的好機會,也可以認識新朋友或找工作,現場有贊助商擺攤。參加後的心得簡言之如下:

  1. Keynote 都很有水準,沒讓人失望
  2. Talk 部分,每個人的背景、興趣不同,因此不是每一場演講都有收穫,有些太淺,有些因背景知識不足引不起興趣,但是都可以參考參考。(深深覺得我也應該投稿的…)
  3. 只聽演講其實沒有辦法學到多少東西,因為演講只是一閃而過的訊息,要學會還是要讀文件跟實作,所以就是看看別人在你有興趣的領域上,是怎麼解決問題,用什麼套件等。
  4. 可以看看社群在溝通協作上都用什麼工具,像共筆採用 hackfoldr + hackmd,就令我耳目一新;另外還有 sli.do 可以接收聽眾問題,gitter 公共聊天室,speakerdeck, slides.com 放投影片等。

我印象比較深刻的講題(與個人興趣、背景高度相關,僅供參考):

  • 唐鳳的 Keynote - 明日之後的世界: 講他推廣公民網路參與公共議題,形成共識的經驗
  • Mosky - Boost Maintainability: 講節省開發及除錯時間的程式設計原則
  • jserv 的 Keynote - Python 導入系統軟體教學: 講他在學校教書的經驗跟最近參加的本地大型專案。jserv 的名氣就不用提了,聽過好幾次他的演講後,我只想說原來程式大神跟嘴砲大神可以存在在同一個人身上 XD
  • 迪士尼資深工程師 Paul 的 Keynote - Inside the Hat: Python @ Walt Disney Animation Studios: 講動畫電影製造過程,Python 在其中的角色,他們對於商業軟體的看法與使用方式
  • PF - 用Numpy做一個自己的股票分析系統: 這大概每個有在買股票的工程師都想過要做,包括我自己 XD 他有提到用 Numpy 加速計算,跟前端 UI 可用 Amcharts.js
  • 柯維然 - 用Google Cloud Platform玩交通資料分析: 單純只是很驚訝泛公務人員體系的臥虎藏龍,之前也有叢培侃這位資安專家 (雖然他後來也離開了),這些人是我離開之前沒有預料過會遇見的
  • 施晨揚 - 如何打造關鍵字精靈: 談他用 Pixnet data 建詞彙關聯的結果,基本上就是在講 Word2Vec 及斷詞,對我而言技術已知,但 data 只有他有,所以可以看看他的實證結果;另外他也提供了好幾個我不知道的斷詞用字典來源
  • Andy Dai - Analyzing Chinese Lyrics with Python: 一樣是技術已知,但結果有趣;也講了很多計算與呈現結果可以使用的套件 (pandas, counter.most_common(), matplotlib, wordcloud)
  • PTVS 作者 Steve 的 Keynote - Intentional Communication: 很令人意外地沒有講他做 PTVS 的技術細節 (大概留在收費的 tutorial 了),而是在講如何有效溝通與溝通工具(說、寫、教)的效果,很有渲染力,他怎麼得到目前這份工作的過程也很值得一聽

全部議程共筆在這。


距離總處事求人開放資料版網站上線已經超過一年半了,期間經歷了各種奇怪的阻礙,例如:

  • 時不時就抓不到資料 (當天沒資料的話網站只能開天窗)
  • 突然改變資料開放的方式,從可以直接 GET 變成要從網頁 POST (後來又改回來了)
  • 總處主機突然擋起了國外 ip (我也想架在台灣但 AWS 在台灣沒有主機呀)
  • 除了我以外,也看到其他人要求總處增加開放資料的頻率,從每日更新一次到每日兩次等,不做就是不做,還把每日新增職缺貼在總處的 fb 頁面上,我是不太懂為什麼他們寧願人工張貼資料,也不願意讓機器自動從資料庫重新產製開放資料就好… (2016-06-02 更新: 現在資料改成每日產製兩次囉! 幫總處同仁按個讚!)

透過民意信箱跟總處打了多次交道,雖然官僚難免,但總的來說服務還是滿周到的,反應的問題大部分都有解決。

開始收集每天的開缺資料也已經超過一年了,為了慶祝即將上任的副人事長是資訊背景,人事資訊化將大有可為(?),花了兩天增修了網站的一些統計功能:

  • 新增各機關開缺數查詢:先點選機關,再點選職系,最後可看到開缺細節。所有表格皆可搜尋及自由排序欄位
  • 修改各職系開缺數查詢:改以表格呈現,並可看到該職系開缺機關,可搜尋及自由排序欄位
  • 職缺特殊條件新增「✔同意開放簡歷」,對應原總處「請注意:本職缺啟用現職應徵人員調閱簡歷功能,現職應徵者需同意開放簡歷給徵才機關調閱」條件

有了職系開缺數查詢,如果你想轉職系,或是朋友在選考公職職系時,可以來看看該職系是否常常開缺,最常開缺的機關是那些,從而了解是否容易調動;至於各機關開缺數查詢的使用時機更廣,例如:

  • 你很想調到某機關,想知道他們有沒有在事求人開過缺 (例如央行從不開外補)
  • 你看到某機關開缺了,想知道該機關是否一天到晚在找人

這邊要注意的是很多機關的缺是掛在上級機關下 (例如北市國中小人事室主任的缺都是北市府人事處開的),因此要找此類職缺必須先從上級機關 (例如北市府人事處) 找起,職缺列表的工作地址會註明真正的工作機關,並請善用關鍵字搜尋,如下圖。

opencpa-1

職缺列表的順序是從開缺日期最近的缺開始,但所有表格的每個欄位都可以自由排序。

總處的開放資料內容其實滿亂的,因為不是每個張貼職缺的人都會依照格式輸入,我只用了一些簡單的規則去判斷職缺結構,爬梳結果難免有不完整的地方 (例如職等判斷錯誤或留下了非公務人員的職缺職系等),不過就先頂著用吧。另有關本站目前的匿名留言功能,我一開始是希望有身分認證,然後讓大家可以私密地交換有意義的資訊,不過我早期測試的結果顯示很少人想要曝光,而且 fb 的封閉社團或 line 群組就已經可以實現這個想法,所以就不做了。網站未來增修的方向:

  1. 把考試缺資訊一起整合進來,機關用人的全貌會更完整 (之前有收到一位朋友來信,似乎正在做這部分的功能)
  2. 附上 Ptt 針對某機關某職系的討論文章

不過實作日大概也是遙遙無期吧。