最近在與長庚大學的學生協作開發畢業學分的計算工具,如果有興趣可以參考之前寫的:畢業學分計算工具開發心得 | 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 前先執行測試,減少程式碼的錯誤。之前並無單元測試經驗,因此在規劃及實作上有任何建議,也歡迎指教,謝謝!