// 不管什麼方法,都是這樣一個結構 const fn = () => { };
好比,我要寫一個接口,查詢組織下的設備列表 /api/device/list
api
const deviceList = (params) => { // 傳入一些參數 return []; // 返回一個列表 };
我須要哪些參數:數組
輸出結果很簡單,爲一個數組。session
第一步分析,存在成功和錯誤(錯誤類型先不考慮)兩種類型的結果。框架
// 成功 // 錯誤 const deviceList = async (ctx) => { // 錯誤 if(someError) { // 返回錯誤結果 } // 成功 return getDevicesByOid(oid); };
這是一個大概的設想,沒有必要將代碼寫出來。而後潤化該思路,寫出第一段框架。async
首先,傳入的參數爲組織 oid,用戶的信息能夠經過 session(或其餘方式)從內部得到。單元測試
// 成功 // 錯誤 // 錯誤1:用戶未加入組織 // 錯誤2:傳入參數組織不存在 // 錯誤3:用戶無組織權限 // 傳入參數: 要查詢的組織 oid // 可以經過 session 取到的信息: user const deviceList = async (ctx) => { // 用戶信息 ctx.user // 判斷用戶是否有組織 if (ctx.user.oid === 0) { // 錯誤1:用戶未加入組織 } // 若是不傳該參數,查詢當前用戶組織的設備 const { oid = ctx.user.oid } = ctx.request.body; if (oid === ctx.user.oid) { // 成功 return getDevicesByOid(oid); } // 根據oid查詢組織信息 // 錯誤2:傳入參數組織不存在 // 判斷是否有權限 const checkRights = await checkUserOrgRights(ctx.user.uid, oid); if (!checkRights) { // 錯誤3:用戶無組織權限 } // 成功 return getDevicesByOid(oid); };
// 成功 // 錯誤 // 錯誤1:用戶未加入組織 // 錯誤2:傳入參數組織不存在 // 錯誤3:用戶無組織權限 // 傳入參數: 要查詢的組織 oid // 可以經過 session 取到的信息: user const deviceList = async (ctx) => { // 用戶信息 ctx.user // 判斷用戶是否有組織 if (ctx.user.oid === 0) { // 錯誤1:用戶未加入組織 } // 若是不傳該參數,查詢當前用戶組織的設備 const { oid = ctx.user.oid } = ctx.request.body; if (oid !== ctx.user.oid) { // 爲何這裏不用等於判斷:若是等於的話,則當時就須要返回出去,這樣的話該方法會有兩個成功的 return // 根據oid查詢組織信息 // 錯誤2:傳入參數組織不存在 // 判斷是否有權限 const checkRights = await checkUserOrgRights(ctx.user.uid, oid); if (!checkRights) { // 錯誤3:用戶無組織權限 } } // 成功 return getDevicesByOid(oid); };
完成其餘的業務代碼。測試
按照上面推薦方式完成代碼後,須要進行代碼的測試。優化
首先須要明確業務的流程,理清測試的思路。ui
錯誤設計
主要有兩種設計思路:
這是傳統的單元測試衍生而來的 BDD 測試方式。
這裏測試用例的個數應該爲8
次:
成功:
其中,測試3-5能夠優化爲一次測試(即根據全部管理員 uid 的數組比較是否包含當前用戶 uid),最終優化後的結果應當爲6
次。
但因爲該思路中不明確用戶,因此用戶行爲沒法準確表達,在建立測試數據的時候較爲困難,不仔細思考分析,沒法優化須要建立多少條測試數據。
而實際上 BDD 測試爲用戶行爲測試,能夠以幾類用戶的情形分別進行測試。
以此循環,直至覆蓋全部。
用戶1(非組織管理員,查詢本身的組織)
用戶2(上級某組織管理員)(組織3)
用戶3(未加入組織用戶)
很是簡潔明瞭的關係,須要3個測試用戶,3個組織(上下級關係進行數據複用,一個無權限的組織),便可涵蓋全部範圍。
最終優化版設計:
用戶1(某組織管理員,有下級組織)
用戶2(未加入組織用戶)
兩個用戶,三個組織。完成全部覆蓋。
能夠從上述測試思路二中進行反推。
實際上思路多是在寫代碼或者寫測試的過程當中不斷的改進和完善的。