3.2 系統實作
3.2.1 輔助作業發佈介面
國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
3.2 系統實作
3.2.1 輔助作業發佈介面
接下來,將對於輔助作業發佈介面的主要功能作介紹,包括:自動生成測試程式碼、
移除程式作業中的實作部分、啟動作業儲存庫、啟動程式作業發佈平台等功能作介紹。
一開始先介紹自動生成測試程式碼的實作部分。首先,介紹 Apache Velocity,我們 透過 Apache Velocity 的 VTL(Velocity Template Language)模板語言,來撰寫俱有 Spock 測試規格的模板,作為程式碼生成的功能。程式碼中可以錢字號($)為開頭的符號作為變 數,於程式碼生成的過程中會替換成設定好的數值。接著,依照 Spock framework 的規 格去撰寫測試程式碼的模板(Javatemplate.vm),俱有 Spock 測試規格的模板如圖 15 所 示,再使用模板產生器(Apache Velocity)將變數的資料寫進到模板中,最後產生測試程 式碼檔案(JavaSpec.groovy)。接下來,介紹 Spock framework,於 JavaSpec.groovy 檔案 內,每一個 method 擁有相對應的測試程式,測試程式上方會有註解來表示測試的類型、
配分以及測試個數。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
圖 15 俱有 Spock 測試規格的模板(template)
測試主要分為三大區塊:setup、expect、where。setup 區塊用作建立測試相關的環境 條件;expect 區塊用來判斷學生的作答和老師的正解是否相符合;where 區塊用作提供 多組測試數據資料。最後,測試程式的報告格式:使用 spock-report 技術,我們定義出 兩 個報 告 格 式模板 : spec-template2.md 表 示個別 Specification 結果以及 summary-template2.md 表示總覽號(ID),再顯示整份作業的作答概況資訊(總題數、答對題數、答 錯題數以及略過的題數等),接著依序條列出每一題 method 的詳細作答情況(包括:總分、
配分、權重、測試的輸入數據以及題目難易度等)。最後會顯示出整份程式作業的總得分。
於每一道題目(feature)中,可設定 timeout 屬性,以掌控執行測試的最大時間上限。若測 試時間超過所設定的 timeout 數值,則判定該題目(feature)為 failure。同時於整個 Specification 中,也會有 global timeout 參數,藉此掌控整體程式作業的測試時間。接著 說明自動化產生測試程式碼的原理,首先,使用 Velocity 模板語言定義以 Spock 的架構 下,預期產生測試程式碼的格式,例如:函數名稱、測試數據和測試參數的位置、使用 的套件等,接著,假設老師撰寫的程式作業的實作部分都是正確的,於是我們將測試數
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
據傳入至老師的函式中,所得的回傳值應該也是正確的答案。因此,我們將測試參數和 測試數據,以及正確的回傳值一併傳進 Velocity 模板中,進而產生出測試程式碼。將來,
於測試學生的程式作業時,我們只需將測試數據傳入學生的函式中,將所得學生的回傳 值和老師的回傳值相比較,就可判斷學生是否答對。
圖 16 程式作業
老師設計的程式作業(舉 HW7Solution2.java 為例)具有許多個 method,method 上方 可用標籤來表示與該 method 有關的資訊,如圖 16 所示,以這個 method 為例,Scores 標 籤的 points 參數表示如果答對這題 method 測試即可獲得 20 分;type 參數表示這題 method 測試為 NORMAL(普通)的題型;Validate 標籤的 number 參數為 3,表示這題 method 測試有 3 組測試項目;ex 參數可放入多組 Ex 標籤的測試數據資料;其中 Ex 標 籤的 dataInt 參數表示可輸入整數值的測試數據;dataString 參數表示可輸入字串值的測 試數據。當老師完成題目試卷後(包括題目和正確的實作),可於每一道題目標記適當標 籤,以賦予題目相關測試資訊。接著,透過 Java Reflection,可獲得程式碼內,所包含的
‧
各項資訊,包括:標籤(Annotation)的名稱和數值、method 的名稱和個數、method 的引 數和資料型態、以及回傳值的資料型態。因此藉由 Java Reflection 技術而獲得題目的所 有標籤資訊(Scores 標籤和 Validate 標籤),取得這些資訊後,再透過 Apache Velocity 技 術為每一道題目產生相對應,且俱有 Spock 測試架構的測試程式碼。產生測試程式碼的 參考依據,例如學生的失敗數或是測試時間等,於是透過 Java Annotation 技術,我們定 義三種標籤,Scores 標籤、Ex 標籤、Validate 標籤等,藉由以上三種標籤表示評分標準 和測試的相關資訊,標籤資訊詳如表 3 Java Annotation 標籤資訊所示。
首先,介紹 Scores 標籤,共有八項參數,除了 partial 為布林參數外,每一項參數都 為浮點數的資料型態,使用者可依照情況自由挑選作設定,並且我們可為所有的函式測 試做全域(global)的參數設定,亦可針對個別的部分做單獨的參數設定。Scores 標籤的 partial 參數表示只需答對部分的測試項目,即可獲得部分的分數,partial 參數預測值為 false,若 partial 參數為 true,我們定義 failures 和 errors 兩個參數分別代表測試項目的 結果為 failure 和 error 的情況時,所需要分別扣的分數值,此時,依照每題測試的配分 扣除失敗和錯誤的測試項目的分數,即為該題測試的得分,failures 參數的預設值為 0,
‧
誤表示出現程式的編譯問題,或者出現 Exception 的例外情況,例如學生的函式呼叫,於陣列的計算中出現 OutOfBoundException 或是 NullPointerException 等,則此項測試為 測試錯誤;若 partial 參數為 false,表示學生需要答對每一組的測試項目,才能夠獲得該 題測試的所有分數,不過我們也可慮一些極端的情況,例如該題測試有五項測試項目,
若學生僅答錯一組測試項目,則無法獲得該題測試的分數,於是我們思考從測試項目的 角度幫學生做調分,若學生的測試項目的成功率越高,則調分就越高,我們定義 caseRate 參數表示依照測試項目的成功率的獎勵分數,caseRate 預設為 0,例如 caseRate 假設為 5,若學生僅答對五項測試項目的其中一項,則,該題獲得 1 分的調分。我們也考慮到 有答對任何一題的測試,也會有最低的基本分數,所以定義 baseScore 參數,預設值為 0;而於每一組測試項目會有個執行測試的時間上限,為了避免過長的執行時間的等待,
定義 timeout 參數表示每組測試項目的最長時間,若任何的測試項目超過設定的時間,
則該項目的測試會被判定為失敗(fail),並且終止該項測試而輪到下一項作測試;我們定 義 type 參數供老師選填題目的難易程度,可輸入 NORMAL、EASY、HARD、DIFFICULT,
預設值為 NORMAL;每一題目也定義 points 參數表示試題的配分,預設值為 5。接下 來介紹 Ex 標籤,標籤存放每組測試數據的資料,其中的 dataInt 參數用來表示整數的輸 入資料,dataString 參數表示字串的輸入參數,describe 參數表示對該測試的描述。Validate 標籤記錄該試題的測試資訊,其中的 number 參數表示該試題俱有幾筆組測試資料,預
‧
設值為 5,代表該試題含有五組測試;ex 參數存每組的測試數據,沒有預設值;datafile 參數為外部的測試數據檔案,若題目(method)中有需要手動輸入(input)測試數據,則匯
partial = false
failures 每 項 測 試 失 敗 的 扣
‧
建構檔案(build.gradle),以及相關檔案一起放進 initializr-generator 模組內,而在模組內,我們會依據作業檔案的課程和作業版本資訊來分門別類,存放於不同的資料夾。接下來,
initializr-web 模組為提供 REST 端點和 Web 介面的設定,我們修改 home.mustache 檔案,
為 Web 介面擴充作業版本的欄位,以及修改各項輸入欄位的預設值。接著,initializr-actuator 模組為提供項目生成的統計數據和指標,不過這個模組我們不做任何的修改。
接下來,initializr-docs 模組為提供文檔,預設是不啟用,但可以於 IDE 開發環境中來啟 動這個模組,不過這個模組我們不做任何的修改。最後,initializr-service 模組為提供平
describe 該測試試題的描述 describe = "example"