最近在與長庚大學的學生協作開發畢業學分的計算工具,如果有興趣可以參考之前寫的:畢業學分計算工具開發心得 | side project 的嘗試與迭代,礙於獨立開發時並沒有很完善規劃,擔心學生們會不知道從何下手,那時就有進行了一些模組化、Docker 化的工作,也有想說怎麼可以讓他們方便測試以及整合到往後可以自動化測試。
由於專案後端 API 是用 Python Flask 做的,於是我就去研究了一下 Python unittest 的測試 framework。以下分享如何在專案中應用與實作。
一、專案架構
當時規劃的檔案架構大致上是這樣,countCredit.py 是放置計算學分邏輯的程式,會處理前端 post 過來的學分資料,然後 testCase.json 是哪來放 test case,裡面會放課程代碼及學分 ( 跟 post 過來的資料格式一樣 ) 以及計算結果, testCase.py 會去執行有加進去的測試程式碼,計算是不是每個都有符合預期。
graduateTools
| ------ countCredit.py # 計算學分的程式
| ------ testCase.json # 放 test case 的檔案
| ------ testCase.py # 執行測試的程式
二、安裝
Python 內建 unittest,無需另外安裝
三、實作介紹
先上程式碼:
import unittest
import countHCM
import json
class creditTestCase(unittest.TestCase):
def setUp(self):
self.hcm = self.getHCMTestCase()
def tearDown(self):
self.args = None
# get hcm test data
def getHCMTestCase(self):
with open("testCase.json") as file:
data = json.load(file)
return data['hcm']
def test_hcm(self):
testCases = self.hcm
for test in testCases:
expected = test['result']
lessonData = test['data']
lessonCodes = list(lessonData.keys())
HCMcounter = countHCM.hcmCount(lessonData, lessonCodes)
result = HCMcounter.count_hcm_credit()
# remove blank for test
expected = expected.replace(' ', '')
# remove blank and break line for test
result = result.replace(' ', '').replace("\n", '')
self.assertEqual(expected, result)
if __name__ == '__main__':
unittest.main()
稍微分段說明一下
setUp
: 方法是測試前執行,這邊我是先去取testCase.json
的 test casetearDown
: 方法是測試後執行,我沒有特別拿來做什麼test_hcm
: 所有要加入測試的方法,前綴都要加上test
,而最後我用了assertEqual
方法,需要提供測試預期結果以及計算結果,會判斷兩者是否相同unittest.main()
: 用此方法來執行所有測試
四、如何測試
開啟 terminal 執行 python -m unittest
,便會輸出測試結果
測試成功
測試失敗
另外也可以用 python -m unittest -v
輸出詳細測試資訊
總結
之後開發會希望在實作不同科系的計算邏輯後,都能加入單元測試,並在 commit 前先執行測試,減少程式碼的錯誤。之前並無單元測試經驗,因此在規劃及實作上有任何建議,也歡迎指教,謝謝!
測試對象是 html 內容嗎,既然是 API 應該是有物件等等可以直接比較的格式才對
然後前端是驗證此 API 接受到的資料是否能 render 成畫面,再驗證 render 伽果可以被使用者看到
或者說可以把這個測試對象 hcmCount 裡面再拆成 call 兩個 function
另外 calcResult 我不確定測試資料是什麼,但可以這麼有規律的驗證 感覺 json 格式也蠻複雜的
整體來說比較像「整合測試」在驗收可能是舊資料是否能繼續進行,但錯誤時候不會知道實際是哪部分出錯
而單元測試的 「單元」可以能對 calcResult 中的第一種課程格式有一個驗證 input 一個 output,如果測試錯誤就會馬上知道哪個邏輯被改壞了