測(cè)試用例設(shè)計(jì):從需求約束到狀態(tài)時(shí)序覆蓋)
前一陣評(píng)審?fù)碌?0x85 服務(wù)測(cè)試用例一開始看起來(lái)挺完整請(qǐng)求報(bào)文長(zhǎng)度、子功能 01/02、兩個(gè)否定響應(yīng)碼都覆蓋了。但往深一問DTC 設(shè)置關(guān)閉之后重新上電會(huì)不會(huì)恢復(fù)關(guān)閉期間故障是否還會(huì)記錄要不要先切到擴(kuò)展會(huì)話安全解鎖失敗時(shí)返回哪個(gè) NRC用例表里一個(gè)都沒有。這不是個(gè)例。做網(wǎng)絡(luò)診斷測(cè)試久了就會(huì)發(fā)現(xiàn)0x85 服務(wù)這類功能型診斷服務(wù)真正的復(fù)雜度從來(lái)不在協(xié)議層的字節(jié)解析而在把需求里的狀態(tài)、條件、時(shí)序翻譯成可執(zhí)行的用例。0x85 服務(wù)表面上是一個(gè) DTC 設(shè)置控制開關(guān)實(shí)際上是一個(gè)會(huì)影響整個(gè)故障管理行為的狀態(tài)機(jī)。所以“根據(jù)需求設(shè)計(jì)用例”這件事不能只照著 ISO 14229 抄而要把需求里的每條約束拆開、落到輸入和預(yù)期結(jié)果里。我的核心判斷是0x85 服務(wù)的用例設(shè)計(jì)重點(diǎn)不在服務(wù)響應(yīng)是否正常而在需求里的會(huì)話約束、安全約束、時(shí)序約束和存儲(chǔ)約束是否被完整覆蓋。1. 先別急著設(shè)計(jì)用例搞清楚 0x85 服務(wù)真正控制的是什么1.1 它控制的是 DTC 的“記錄開關(guān)”不是故障燈開關(guān)在 UDS 診斷協(xié)議里0x85 服務(wù)通常叫 ControlDTCSetting翻譯過(guò)來(lái)是“控制 DTC 設(shè)置”。它要控制的不是故障燈也不是故障碼存儲(chǔ)文件而是 ECU 對(duì) DTC 狀態(tài)位的更新行為。在常見實(shí)現(xiàn)中DTC 狀態(tài)字節(jié)會(huì)包含 testFailed、confirmedDTC、pendingDTC 這些狀態(tài)位。正常情況下ECU 檢測(cè)到故障后會(huì)按照故障管理邏輯更新這些狀態(tài)位。0x85 服務(wù)關(guān)閉 DTC 設(shè)置后ECU 不再響應(yīng)新的故障事件不再繼續(xù)把 pendingDTC 或 confirmedDTC 置位。但這里有個(gè)關(guān)鍵點(diǎn)它不等于清空 DTC。已經(jīng)置位的 DTC 狀態(tài)通常仍然保留清 DTC 是 0x14 服務(wù) ClearDiagnosticInformation 的職責(zé)。很多新人會(huì)把 0x85 服務(wù)理解成“關(guān)閉故障碼功能”一旦 DTC 設(shè)置了關(guān)閉就以為所有故障現(xiàn)象都應(yīng)該消失。這個(gè)理解在測(cè)試用例設(shè)計(jì)里很危險(xiǎn)。因?yàn)槿绻枨竺鞔_寫了“關(guān)閉 DTC 設(shè)置后DTC 狀態(tài)位保持不變、故障燈保持點(diǎn)亮”那測(cè)試預(yù)期就要按這個(gè)來(lái)寫而不是想當(dāng)然地認(rèn)為故障燈會(huì)熄滅。設(shè)計(jì)用例的第一步是先確認(rèn)需求要求“關(guān)閉”到什么程度是停止記錄新故障還是同時(shí)停止故障燈點(diǎn)亮還是連已存儲(chǔ)的故障狀態(tài)也被凍結(jié)。還有一個(gè)容易混淆的點(diǎn)是設(shè)置狀態(tài)本身。0x85 服務(wù)執(zhí)行成功后DTC 設(shè)置狀態(tài)是開啟還是關(guān)閉需求里通常會(huì)定義。但這個(gè)狀態(tài)是不是掉電保持是存在 RAM 還是 NVM 里不同 ECU 差異很大。有的 ECU 下電重啟后會(huì)恢復(fù)為“開啟”有的會(huì)保持在“關(guān)閉”。如果不把這個(gè)狀態(tài)作為用例設(shè)計(jì)的一部分后面測(cè)試很容易出現(xiàn)“響應(yīng)正確但行為錯(cuò)誤”的爭(zhēng)議。1.2 請(qǐng)求與響應(yīng)里的三個(gè)關(guān)鍵字段設(shè)計(jì) 0x85 服務(wù)用例至少要把請(qǐng)求和響應(yīng)結(jié)構(gòu)里的字段拆清楚。0x85 服務(wù)的請(qǐng)求通常由三部分組成服務(wù) ID 0x85、子功能、DTCSettingControlOptionRecord。子功能在通用協(xié)議里常見定義是 0x01 表示開啟 DTC 設(shè)置0x02 表示關(guān)閉 DTC 設(shè)置。具體到某個(gè) OEM 規(guī)范子功能碼可能不同甚至可能增加更細(xì)的自定義類型。所以用例設(shè)計(jì)不能只看 ISO 14229還要看項(xiàng)目里的診斷規(guī)范。DTCSettingControlOptionRecord 是更值得重視的字段。它有幾種情況請(qǐng)求里不攜帶請(qǐng)求里攜帶固定長(zhǎng)度數(shù)據(jù)請(qǐng)求里攜帶可變長(zhǎng)度數(shù)據(jù)。需求里如果定義了 option record用例就要覆蓋正確的 record 值能得到肯定響應(yīng)錯(cuò)誤的 record 值應(yīng)該返回對(duì)應(yīng) NRCrecord 長(zhǎng)度比規(guī)范定義多一字節(jié)或少一字節(jié)ECU 的響應(yīng)是否符合預(yù)期重復(fù)發(fā)送相同 record結(jié)果是冪等還是會(huì)被拒絕。一個(gè) CAN 單幀請(qǐng)求的示例大致是這樣診斷請(qǐng)求 02 85 01 # 0x85 服務(wù)子功能 0x01無(wú) option record 肯定響應(yīng) 02 C5 01 # 0xC5 0x85 0x40子功能原樣回顯 否定響應(yīng)示例 03 7F 85 33 # 服務(wù) 0x85NRC 0x33常見含義是安全訪問未通過(guò)這個(gè)示例只是常見形態(tài)具體報(bào)文長(zhǎng)度和 option record 內(nèi)容以項(xiàng)目診斷數(shù)據(jù)庫(kù)為準(zhǔn)。響應(yīng)這邊肯定響應(yīng)會(huì)回顯 SID 和子功能如果 option record 有定義也可能回顯 record。否定響應(yīng)則是 0x7F 0x85 NRC。用例設(shè)計(jì)時(shí)需要把每種 NRC 的觸發(fā)條件都對(duì)應(yīng)到具體輸入而不是只留一個(gè)“返回錯(cuò)誤碼”的模糊預(yù)期。2. 從需求到用例先建立一個(gè)可翻譯的約束矩陣2.1 需求文檔里經(jīng)常出現(xiàn)的四類約束0x85 服務(wù)的需求很少只寫一句“支持 0x85 服務(wù)開啟和關(guān)閉 DTC 設(shè)置”。真實(shí)項(xiàng)目里需求會(huì)分布在不同章節(jié)里如果不逐條拆很容易漏用例。最常見的是會(huì)話約束。比如“僅擴(kuò)展會(huì)話支持該服務(wù)”或者“默認(rèn)會(huì)話下該服務(wù)應(yīng)返回 NRC”。這類約束決定了用例的前置會(huì)話狀態(tài)。第二類是安全約束。很多 ECU 會(huì)要求安全訪問解鎖后才能執(zhí)行 0x85 服務(wù)尤其關(guān)閉 DTC 設(shè)置這種會(huì)影響故障診斷的功能。需求里可能寫著“安全等級(jí) 2 解鎖后允許執(zhí)行”也可能寫“未解鎖時(shí)執(zhí)行應(yīng)返回 0x33”。這類需求要轉(zhuǎn)化為“是否解鎖 請(qǐng)求 預(yù)期響應(yīng)”的用例組合。第三類是車輛條件約束。部分 ECU 會(huì)限制在車輛運(yùn)行狀態(tài)下不允許關(guān)閉 DTC 設(shè)置或者車速超過(guò)某個(gè)閾值時(shí)不響應(yīng)。這類約束在臺(tái)架測(cè)試?yán)锶菀缀雎砸驗(yàn)榕_(tái)架默認(rèn)供電穩(wěn)定很難意識(shí)到實(shí)車還有車速、擋位、充電狀態(tài)這些條件。第四類是存儲(chǔ)和恢復(fù)約束。這是 0x85 服務(wù)需求里最容易出問題的地方。需求里可能定義“關(guān)閉狀態(tài)在下電后保持”也可能定義“退出擴(kuò)展會(huì)話后自動(dòng)恢復(fù)為開啟”。這兩類約束如果沒寫清測(cè)試執(zhí)行時(shí)一定會(huì)產(chǎn)生分歧。用例設(shè)計(jì)階段就要把這一條找出來(lái)不能等測(cè)試執(zhí)行時(shí)再靠猜。2.2 三步法從需求條目到用例編號(hào)我一般會(huì)把“從需求到用例”的過(guò)程固定成三步避免一上來(lái)就直接寫步驟。第一步把需求拆成單一條件的條目。一條需求如果包含“擴(kuò)展會(huì)話 安全解鎖 關(guān)閉 DTC 設(shè)置 下電后恢復(fù)”四個(gè)內(nèi)容就要拆成至少四條獨(dú)立用例而不是一條大用例。因?yàn)槿绻麥y(cè)試失敗你很難定位是哪個(gè)條件沒滿足。第二步把每個(gè)條件映射成測(cè)試前置條件和輸入。比如“未解鎖時(shí)執(zhí)行 0x85 關(guān)閉”對(duì)應(yīng)的前置條件是安全訪問未完成輸入是 0x85 02預(yù)期結(jié)果是 NRC 0x33。這一步其實(shí)是在翻譯需求把模糊的描述變成可執(zhí)行的操作。第三步把這些映射結(jié)果整理成用例矩陣。矩陣?yán)镏辽侔枨缶幪?hào)、前置條件、請(qǐng)求輸入、預(yù)期響應(yīng)、用例優(yōu)先級(jí)。這樣后續(xù)評(píng)審時(shí)可以逐行核對(duì)而不是在幾十條用例里靠肉眼找遺漏。不要一上來(lái)就想著把用例數(shù)量做滿。先把需求拆出的條件一條條列出來(lái)?xiàng)l件沒拆完數(shù)量再多也說(shuō)明不了覆蓋率。2.3 一個(gè)可落地的需求-用例映射表下面是一個(gè)示例結(jié)構(gòu)不是某個(gè) OEM 的真實(shí)需求。它用來(lái)展示映射表應(yīng)該長(zhǎng)什么樣。需求描述前置條件請(qǐng)求輸入預(yù)期結(jié)果用例類型默認(rèn)會(huì)話下不允許執(zhí)行 DTC 設(shè)置控制默認(rèn)會(huì)話未解鎖0x85 01否定響應(yīng)預(yù)期 NRC 由規(guī)范定義否定路徑擴(kuò)展會(huì)話且安全解鎖后允許關(guān)閉 DTC 設(shè)置擴(kuò)展會(huì)話已安全解鎖0x85 02肯定響應(yīng) 0xC5 02狀態(tài)變?yōu)殛P(guān)閉正常路徑關(guān)閉 DTC 設(shè)置后再次執(zhí)行關(guān)閉應(yīng)保持關(guān)閉擴(kuò)展會(huì)話已解鎖DTC 設(shè)置狀態(tài)為關(guān)閉0x85 02肯定響應(yīng)狀態(tài)仍為關(guān)閉不產(chǎn)生新 DTC冪等路徑關(guān)閉 DTC 設(shè)置后重新上電應(yīng)恢復(fù)為開啟擴(kuò)展會(huì)話已解鎖DTC 設(shè)置已關(guān)閉下電再上電狀態(tài)恢復(fù)為開啟時(shí)序路徑未解鎖時(shí)執(zhí)行關(guān)閉應(yīng)拒絕擴(kuò)展會(huì)話未解鎖0x85 02NRC 0x33 或規(guī)范定義錯(cuò)誤碼否定路徑這張表的價(jià)值在于每條用例都有前綴條件和預(yù)期結(jié)果評(píng)審時(shí)能很快看出某條需求有沒有被覆蓋。如果需求變更比如把“重新上電恢復(fù)為開啟”改成“上電保持關(guān)閉”只需要在表里定位對(duì)應(yīng)行就能找出所有受影響用例。3. 用例設(shè)計(jì)核心功能路徑、否定響應(yīng)、狀態(tài)時(shí)序3.1 功能路徑設(shè)計(jì)正常開關(guān)并不是一種路徑很多測(cè)試用例只寫兩條正常路徑發(fā)送 0x85 01 成功發(fā)送 0x85 02 成功。但在 0x85 服務(wù)里“成功”不代表行為正確。更完整的正常路徑至少應(yīng)該覆蓋這些組合當(dāng)前 DTC 設(shè)置狀態(tài)為開啟時(shí)發(fā)送關(guān)閉請(qǐng)求當(dāng)前狀態(tài)為關(guān)閉時(shí)再發(fā)送關(guān)閉請(qǐng)求驗(yàn)證冪等當(dāng)前狀態(tài)為關(guān)閉時(shí)發(fā)送開啟請(qǐng)求當(dāng)前狀態(tài)為開啟時(shí)再發(fā)送開啟請(qǐng)求連續(xù)多次發(fā)送同一請(qǐng)求觀察 ECU 是否穩(wěn)定帶默認(rèn) option record 請(qǐng)求與不帶 option record 請(qǐng)求確認(rèn)響應(yīng)是否一致如果規(guī)范允許 record覆蓋最小長(zhǎng)度、最大長(zhǎng)度和正常長(zhǎng)度。設(shè)計(jì)這些路徑時(shí)不能只看響應(yīng)報(bào)文。如果條件允許應(yīng)該在每次請(qǐng)求后再通過(guò)診斷服務(wù)讀取 DTC 狀態(tài)或者讀取 DTC 設(shè)置狀態(tài)。否則可能出現(xiàn)“響應(yīng)正確但狀態(tài)沒變”的情況。這個(gè)現(xiàn)象在 0x85 服務(wù)測(cè)試?yán)锊⒉簧僖娪绕涫切枨罄锒x了延遲生效或條件不滿足但 ECU 先返回肯定響應(yīng)的情況。3.2 否定響應(yīng)設(shè)計(jì)按 NRC 矩陣覆蓋而不是“挑幾個(gè)”0x85 服務(wù)可能的否定響應(yīng)碼不能憑感覺選應(yīng)該按需求文檔和診斷數(shù)據(jù)庫(kù)列出的 NRC 一一設(shè)計(jì)。常見的 NRC 觸發(fā)條件大致如下NRC常見觸發(fā)原因用例設(shè)計(jì)建議0x12子功能不支持發(fā)送需求未定義的子功能例如 0x00、0x030x13消息長(zhǎng)度錯(cuò)誤請(qǐng)求缺少子功能或 option record 長(zhǎng)度與規(guī)范不一致0x22條件不正確在禁止條件下請(qǐng)求例如車輛狀態(tài)不滿足0x31請(qǐng)求超出范圍發(fā)送規(guī)范未定義的 option record 值0x33安全訪問失敗或未解鎖未執(zhí)行安全訪問直接請(qǐng)求0x7E當(dāng)前會(huì)話下不支持該子功能在默認(rèn)會(huì)話請(qǐng)求受限子功能0x7F當(dāng)前會(huì)話下不支持該服務(wù)在默認(rèn)會(huì)話請(qǐng)求 0x85 服務(wù)設(shè)計(jì)否定路徑用例時(shí)要特別注意觸發(fā)條件本身是否可執(zhí)行。比如 0x22 條件不正確如果需求里寫得比較模糊沒有說(shuō)清什么條件下允許、什么條件下禁止用例就無(wú)法穩(wěn)定觸發(fā)。這時(shí)應(yīng)該先和需求方澄清而不是在用例里寫“發(fā)送請(qǐng)求返回任意 NRC”。還有一個(gè)容易被忽略的細(xì)節(jié)同一類錯(cuò)誤輸入在不同會(huì)話里可能返回不同 NRC。比如默認(rèn)會(huì)話下發(fā)送不支持的子功能有些 ECU 會(huì)返回 0x12有些會(huì)先判斷會(huì)話返回 0x7E。用例如果只在擴(kuò)展會(huì)話下覆蓋一遍默認(rèn)會(huì)話的情況就會(huì)漏掉。3.3 狀態(tài)時(shí)序設(shè)計(jì)最容易遺漏的恢復(fù)場(chǎng)景0x85 服務(wù)用例里最有價(jià)值的一部分是這個(gè) H2 要講的時(shí)序路徑。因?yàn)樗皇呛?jiǎn)單驗(yàn)證一次請(qǐng)求而是要驗(yàn)證狀態(tài)管理行為。至少有幾條時(shí)序場(chǎng)景值得固定進(jìn)用例集關(guān)閉 DTC 設(shè)置后造一個(gè)真實(shí)故障條件等待超過(guò) pendingDTC 的記錄時(shí)間確認(rèn) DTC 狀態(tài)位不變化關(guān)閉 DTC 設(shè)置后執(zhí)行 0x14 清除 DTC再重新開啟 DTC 設(shè)置確認(rèn)新故障是否會(huì)被記錄關(guān)閉 DTC 設(shè)置后退出擴(kuò)展會(huì)話并重新進(jìn)入確認(rèn) DTC 設(shè)置狀態(tài)是否自動(dòng)恢復(fù)關(guān)閉 DTC 設(shè)置后重新上電確認(rèn)狀態(tài)是按 RAM 還是 NVM 恢復(fù)關(guān)閉 DTC 設(shè)置后安全解鎖狀態(tài)因?yàn)橹匦律想姸г俅螆?zhí)行關(guān)閉請(qǐng)求確認(rèn)是否需要重新解鎖開啟 DTC 設(shè)置狀態(tài)下連續(xù)執(zhí)行關(guān)閉和開啟確認(rèn)狀態(tài)切換過(guò)程中沒有殘留狀態(tài)。測(cè)試過(guò)程中最怕的不是 NRC 返回得不對(duì)而是成功響應(yīng)后 ECU 內(nèi)部狀態(tài)沒有變化。這個(gè)問題通常需要靠讀取 DTC 狀態(tài)或故障注入來(lái)暴露只靠響應(yīng)幀判斷會(huì)得出錯(cuò)誤結(jié)論。時(shí)序用例的預(yù)期結(jié)果必須來(lái)自需求描述而不是測(cè)試人員的經(jīng)驗(yàn)。比如“退出擴(kuò)展會(huì)話后DTC 設(shè)置狀態(tài)恢復(fù)為開啟”和“退出擴(kuò)展會(huì)話后保持關(guān)閉”在協(xié)議層面都是可能的區(qū)別只在 OEM 需求和 ECU 設(shè)計(jì)。如果需求沒寫清楚應(yīng)該把它記錄為需求缺陷而不是用自己猜的結(jié)果去填預(yù)期。4. 用例生成工具TestBuddy 類能幫你什么、不能幫你什么4.1 工具生成用例的原理與價(jià)值現(xiàn)在不少診斷測(cè)試團(tuán)隊(duì)會(huì)用 TestBuddy 這類用例管理或生成工具來(lái)輔助設(shè)計(jì)用例。尤其當(dāng)車型項(xiàng)目里有多個(gè) ECU每個(gè) ECU 的診斷需求都很長(zhǎng)時(shí)靠人工逐條寫用例效率太低。工具生成的邏輯通常是基于診斷需求或診斷數(shù)據(jù)庫(kù)把服務(wù) ID、子功能、會(huì)話、安全等級(jí)、NRC 列表這些結(jié)構(gòu)化信息提取出來(lái)自動(dòng)展開成基礎(chǔ)用例。這樣做的好處很明顯可以快速覆蓋“SID 子功能 會(huì)話 安全等級(jí) NRC”的笛卡爾積減少人工漏項(xiàng)。對(duì) 0x85 服務(wù)來(lái)說(shuō)工具能幫你快速生成所有子功能和 NRC 的組合這是手工表格最容易遺漏的部分。比如子功能開了、關(guān)了、不支持、保留每個(gè)組合都可能有不同響應(yīng)。用工具一次性鋪開再人工篩選效率高很多。但工具生成的用例通常只是骨架。骨架的意思是它知道“發(fā)送 0x85 02 應(yīng)該返回肯定響應(yīng)”但它不知道“發(fā)送 0x85 02 前需要先保證車速低于某個(gè)閾值”更不知道“關(guān)閉 DTC 設(shè)置后是否要在下電前再驗(yàn)證一次狀態(tài)保持”。這些內(nèi)容來(lái)自需求文本而需求文本里的條件往往沒有結(jié)構(gòu)化到工具能直接讀取的程度。4.2 生成之后必須人工補(bǔ)的檢查項(xiàng)用 TestBuddy 或類似工具生成完用例我會(huì)建議按下面這幾項(xiàng)做一輪人工審查而不是直接把生成結(jié)果導(dǎo)入執(zhí)行平臺(tái)。第一檢查前置條件是否可執(zhí)行。工具生成的用例通常會(huì)寫“安全解鎖后執(zhí)行”但它不會(huì)告訴你安全解鎖的具體流程、解鎖等級(jí)和超時(shí)時(shí)間。這些必須人工補(bǔ)全否則執(zhí)行用例的人拿到的是不完整信息只能現(xiàn)場(chǎng)猜。第二檢查狀態(tài)驗(yàn)證方式。0x85 服務(wù)的用例不能只驗(yàn)證響應(yīng)幀還要驗(yàn)證 ECU 內(nèi)部狀態(tài)。工具很難自動(dòng)判斷“用哪個(gè) DID 讀取 DTC 設(shè)置狀態(tài)”因?yàn)椴煌?ECU 的狀態(tài)地址、數(shù)據(jù)格式都不一樣。第三檢查時(shí)序場(chǎng)景。工具對(duì)狀態(tài)的遷移、掉電恢復(fù)、會(huì)話退出恢復(fù)這些場(chǎng)景生成能力普遍有限。這不是工具缺陷而是這些行為很難從靜態(tài)診斷數(shù)據(jù)里推斷出來(lái)只能靠人工從需求文本里提取。第四檢查預(yù)期結(jié)果是否可測(cè)量。如果預(yù)期結(jié)果寫著“DTC 設(shè)置狀態(tài)正確”但沒寫清楚是用響應(yīng)判斷還是用狀態(tài)讀取判斷這條用例將來(lái)執(zhí)行時(shí)很難判定通過(guò)還是失敗。人工審查時(shí)要把這類模糊預(yù)期改成可觀測(cè)、可對(duì)比的結(jié)果。工具生成的用例只是骨架。真正決定測(cè)試有效性的是人工補(bǔ)進(jìn)去的前置條件和預(yù)期結(jié)果。5. 執(zhí)行 0x85 服務(wù)用例時(shí)的前置條件與排查思路5.1 執(zhí)行前先確認(rèn)環(huán)境與診斷數(shù)據(jù)0x85 服務(wù)測(cè)試看起來(lái)是簡(jiǎn)單的診斷請(qǐng)求但執(zhí)行前需要確認(rèn)的環(huán)境項(xiàng)并不少。第一步確認(rèn)診斷數(shù)據(jù)庫(kù)。用 ODX、CDD 或項(xiàng)目?jī)?nèi)部的診斷調(diào)查表核對(duì) 0x85 服務(wù)的會(huì)話、安全等級(jí)、子功能、option record 長(zhǎng)度。如果數(shù)據(jù)庫(kù)和需求文檔不一致不能直接測(cè)要先把差異處理掉。第二步確認(rèn)總線環(huán)境和供電方式。臺(tái)架測(cè)試?yán)顴CU 供電通常穩(wěn)定但實(shí)車上有上下電時(shí)序、網(wǎng)絡(luò)管理、總線休眠。如果需求包含“下電后恢復(fù)”這種場(chǎng)景測(cè)試環(huán)境最好能模擬下電和上電不能只停留在連續(xù)發(fā)送診斷請(qǐng)求的層面。第三步確認(rèn) DTC 狀態(tài)讀取路徑。執(zhí)行 0x85 服務(wù)后如何確認(rèn)狀態(tài)真的變了一般可以通過(guò) 0x19 服務(wù)讀取 DTC 狀態(tài)或通過(guò)某個(gè) DID 讀取 DTC 設(shè)置狀態(tài)。如果沒有這個(gè)驗(yàn)證通道測(cè)試執(zhí)行時(shí)很容易陷入“響應(yīng)正常但不知道是否生效”的困境。第四步把日志記錄做好。0x85 服務(wù)用例最怕的是執(zhí)行結(jié)束后沒有請(qǐng)求幀、響應(yīng)幀和時(shí)間戳。后續(xù)一旦發(fā)現(xiàn)結(jié)果有問題只能重測(cè)。建議每次用例都保留完整日志至少包含時(shí)間、方向、CAN ID、數(shù)據(jù)場(chǎng)、NRC。5.2 一條可復(fù)用的排查鏈路如果執(zhí)行過(guò)程中出現(xiàn)問題建議按這個(gè)順序排查不要一上來(lái)就懷疑 ECU 實(shí)現(xiàn)。先看現(xiàn)象。是完全沒有響應(yīng)還是返回了否定響應(yīng)還是肯定響應(yīng)但狀態(tài)沒變?,F(xiàn)象不同排查方向完全不同。再看請(qǐng)求幀。從日志里把原始報(bào)文貼出來(lái)核對(duì) SID 是否是 0x85子功能是否寫對(duì)option record 長(zhǎng)度是否和規(guī)范一致。很多問題是腳本里字節(jié)寫錯(cuò)導(dǎo)致的。再看當(dāng)前會(huì)話。0x85 服務(wù)通常對(duì)會(huì)話有要求。如果當(dāng)前在默認(rèn)會(huì)話請(qǐng)求被拒絕是正常的。切換到擴(kuò)展會(huì)話或編程會(huì)話后再試往往就通過(guò)了。再看安全狀態(tài)。如果請(qǐng)求前沒有執(zhí)行安全訪問或者安全訪問超時(shí)返回 0x33 是正常行為。需要確認(rèn)測(cè)試步驟是否遺漏了解鎖流程。再看條件。如果返回 0x22 條件不正確要檢查是否達(dá)到速度閾值、電源狀態(tài)、整車上下電狀態(tài)等條件。最后再看內(nèi)部狀態(tài)。如果肯定響應(yīng)也正常條件也滿足但 DTC 仍然被記錄通常要檢查 DTC 設(shè)置狀態(tài)是否真的存在非易失存儲(chǔ)里。曾經(jīng)遇到過(guò)一個(gè)現(xiàn)象0x85 02 返回成功但重新上電后 DTC 又繼續(xù)記錄原因是該 ECU 的 DTC 設(shè)置狀態(tài)只存在 RAM 中掉電即失效。而需求里并沒有明確要求保持最終是需求缺陷不是軟件缺陷。這條鏈路寫出來(lái)是為了提醒排查問題時(shí)先確定是哪一層出了問題再?zèng)Q定改哪里。順序反了往往會(huì)因?yàn)橐粋€(gè)字節(jié)長(zhǎng)度錯(cuò)誤浪費(fèi)半天時(shí)間。5.3 從測(cè)試報(bào)告反推用例質(zhì)量測(cè)試執(zhí)行完成后可以反過(guò)來(lái)看報(bào)告質(zhì)量。如果一份 0x85 服務(wù)的測(cè)試報(bào)告全部是通過(guò)且用例數(shù)量很少那并不一定說(shuō)明 ECU 穩(wěn)定也可能是用例設(shè)計(jì)得不夠深。我會(huì)關(guān)注幾個(gè)信號(hào)否定路徑用例數(shù)量是否和 NRC 列表匹配有沒有時(shí)序恢復(fù)類用例有沒有狀態(tài)驗(yàn)證步驟有沒有失敗或需要澄清的項(xiàng)。如果這些信號(hào)都是空白說(shuō)明用例很可能只覆蓋了協(xié)議層正常路徑。6. 長(zhǎng)期角度看 0x85 服務(wù)用例設(shè)計(jì)的價(jià)值6.1 用例質(zhì)量要看需求變更后的回歸能力0x85 服務(wù)的用例設(shè)計(jì)不是一次性工作。項(xiàng)目開發(fā)過(guò)程中需求一定會(huì)變。比如安全等級(jí)從 Level 1 改成 Level 2或者 DTC 設(shè)置狀態(tài)的掉電策略從“恢復(fù)為開啟”改成“保持關(guān)閉”這些變更會(huì)對(duì)用例集造成連鎖影響。如果用例設(shè)計(jì)從一開始按需求矩陣組織起來(lái)需求變更后只需要把變更條件對(duì)應(yīng)的行找出來(lái)列出相關(guān)用例就能快速完成回歸。如果用例是按協(xié)議字段組織起來(lái)的沒有和需求條目關(guān)聯(lián)變更影響分析就會(huì)變成人肉排查漏項(xiàng)風(fēng)險(xiǎn)很高。這也是為什么我一直強(qiáng)調(diào)0x85 服務(wù)用例的重點(diǎn)不是“服務(wù)響應(yīng)對(duì)不對(duì)”而是“需求里的約束有沒有被拆出來(lái)、有沒有落到用例上”。真正有價(jià)值的用例是和需求條目能夠雙向追溯的用例。6.2 給新人的一條建議如果你剛開始做診斷測(cè)試我建議不要從協(xié)議文檔開始設(shè)計(jì) 0x85 服務(wù)用例而是從需求文檔開始。先把需求里和 DTC 設(shè)置狀態(tài)相關(guān)的每一句話都找出來(lái)拆成條件再對(duì)照協(xié)議理解請(qǐng)求和響應(yīng)最后才輪到寫具體步驟。哪怕用 TestBuddy 這類工具自動(dòng)生成了一部分用例人工分析這一步也不能省。工具能幫你把表格鋪開但不能替你理解“下電后恢復(fù)”“退出會(huì)話后恢復(fù)”“安全解鎖超時(shí)”這些行為和真實(shí)故障管理邏輯的關(guān)系。0x85 服務(wù)測(cè)試沒有太多高深算法它的門檻在于愿不愿意把需求當(dāng)作狀態(tài)機(jī)去拆。把開關(guān)、條件、恢復(fù)路徑都放進(jìn)用例里項(xiàng)目里的故障管理行為才真正可控。這也是我做完這一輪用例評(píng)審后最想提醒的一件事。