布前檢查到黃金盯守期的測試實踐)
1. 上線窗口前的最后檢查在發(fā)布按鈕敲下去之前測試在盯什么我見過太多項目組把上線當成一個動作實際上它是一整套流程里風險最密集的一段。很多測試同學對需求階段、開發(fā)階段、測試階段的活很熟練一到上線就發(fā)慌——因為上線這件事拼的不是執(zhí)行測試用例的熟練度而是風險判斷、環(huán)境掌控和臨場決策的能力。聊一套我自己的上線前檢查路徑不一定適合所有團隊但框架可以作為參考。1.1 上線前第一件事確認要發(fā)布的版本到底包含什么聽起來像廢話但這是翻車率最高的環(huán)節(jié)。開發(fā)說代碼已經(jīng)提了測試說測試通過了結(jié)果上線后線上跑的版本和測過的版本根本不是同一套這種事在不少團隊都發(fā)生過。我的習慣是上線前至少半天找開發(fā)要一份最終的版本變更清單然后做三件事用代碼倉庫的版本對比工具查一遍從上一個已上線版本到當前待發(fā)布版本的所有提交記錄確認提交內(nèi)容與變更清單一致沒有夾帶私貨比如順手改了某個公共類、動了某個配置項。把變更清單里的每個功能點和測試用例、缺陷單做一次映射檢查。已經(jīng)關(guān)閉的缺陷要重新確認關(guān)閉時的驗證環(huán)境、驗證版本不能拿舊環(huán)境的結(jié)論充數(shù)??醋兏鍐卫镉袥]有非功能性改動——依賴升級、框架版本調(diào)整、數(shù)據(jù)庫腳本、定時任務配置調(diào)整。這類改動往往沒有專門的功能測試覆蓋但恰恰是上線后最容易惹事的。提示如果團隊里連一個像樣的變更清單都沒有建議在上線流程文檔里把這條固化下來哪怕一開始只是維護一個簡單的共享表格也比上線前臨時翻代碼要可靠得多。1.2 風險評估上線前要說清楚萬一掛了怎么收場上線窗口前測試要做的不是拍胸脯保證肯定沒問題而是基于現(xiàn)有測試覆蓋和信息判斷風險點都有哪些。我一般從三個角度來拆分改動量維度這次是全新模塊、存量功能改造還是只更新了文案和樣式改動量越大風險面越廣上線后需要盯守的時間就越長。存量功能的改造往往比新功能更危險因為新功能影響的是增量用戶而改造影響的是所有在用用戶。影響面維度這個改動是否涉及支付、登錄、訂單等核心鏈路是否涉及底層數(shù)據(jù)結(jié)構(gòu)的變更是否會影響多個業(yè)務模塊的公共接口通過影響面分析確定回歸測試的范圍至少把主鏈路、周邊強關(guān)聯(lián)模塊、基礎(chǔ)公共能力鑒權(quán)、配置加載、日志鏈路都過一遍。回滾成本維度這是很多人會忽略的一點。有的版本發(fā)布后如果出問題回滾只需要把鏡像切回去幾分鐘就行有的版本伴隨數(shù)據(jù)庫表結(jié)構(gòu)變更、數(shù)據(jù)遷移腳本回滾就需要專門做數(shù)據(jù)逆向操作費時費力風險還高。對這類不可逆上線測試階段就要格外謹慎并且要提前和運維、開發(fā)一起把回滾預案寫好。這三步走完之后我會輸出一份上線風險評估里面明確寫本次版本的高中低風險點分別是什么、每個風險點對應的驗證情況、哪些功能做了多少輪測試、哪些區(qū)域是測試盲區(qū)需要上線后重點觀察。這份材料既是給自己上線后的盯守做備忘也是給項目組的風險告知——上線不是測試一個人的事風險要讓每個參與者都知道。1.3 上線窗口選擇不是什么時候想發(fā)就能發(fā)上線時機的選擇測試的話語權(quán)往往不夠但我建議測試還是要參與意見。從測試視角看一個好的上線窗口至少要滿足三個條件不在業(yè)務高峰時段。之前有個同事曾經(jīng)想吃肯德基工作日中午去結(jié)果排隊排了20分鐘看著前面的隊伍心里焦躁得不行。上線同理高峰時段用戶請求量大出問題后影響人數(shù)多排查問題時壓測流量也容易干擾判斷。電商、金融類項目最忌諱的就是大促時段發(fā)布大版本。留出足夠的盯守時間。別周五下午四點半發(fā)版五點半大家準時下班。上線后至少要有2到3個小時的黃金觀察期核心人員都得在線。配合灰度發(fā)布策略?,F(xiàn)在很多團隊會先發(fā)小流量比如先放給5%的用戶觀察半小時沒問題再逐步放量。測試要提前了解這次的灰度策略明確自己在每個階段的驗證動作是什么。2. 環(huán)境差異為什么測試通過的系統(tǒng)上線后還是會有問題經(jīng)歷過幾次線上問題后我深刻意識到一件事測試環(huán)境驗證通過只能說明在測試環(huán)境里沒問題不代表在線上環(huán)境沒問題。環(huán)境差異導致的上線事故比代碼邏輯錯誤更難排查也更容易被甩鍋。2.1 環(huán)境漂移配置對不上是最常見的隱形炸彈很多團隊有多個測試環(huán)境、預發(fā)環(huán)境、沙箱環(huán)境環(huán)境之間大多沒有做好嚴格的配置同步。測試環(huán)境把接口地址指向了某個Mock服務到了線上忘了切換預發(fā)環(huán)境連的是測試庫結(jié)果驗證數(shù)據(jù)的時候被一堆臟數(shù)據(jù)干擾。這些都是很典型的環(huán)境漂移問題。應對方式我是這樣做的在測試接近尾聲時拉著開發(fā)和運維做一次上線環(huán)境的預演Dry Run把發(fā)布腳本、環(huán)境變量、配置中心的值逐項核對一遍確保線上配置文件里每一項關(guān)鍵配置和測試時理解的預期一致。人工核對配置容易漏可以用腳本把測試環(huán)境、預發(fā)環(huán)境、線上環(huán)境的關(guān)鍵配置項做一次diff把差異項打印出來人工確認。這個過程哪怕只跑一次也能省掉不少上線后的折騰。配置變更要留痕。誰的配置改了、為什么改、影響了什么要有記錄臨時手滑改完就忘的行為是配置問題的最大來源。2.2 數(shù)據(jù)差異測試數(shù)據(jù)永遠比線上干凈得多測試環(huán)境的數(shù)據(jù)量級、數(shù)據(jù)分布、數(shù)據(jù)特征跟線上完全不是一個量級的。最常見的坑是測試環(huán)境一張表幾萬條數(shù)據(jù)SQL執(zhí)行得飛快線上那張表幾千萬條同樣的SQL跑了幾百秒沒出來直接把數(shù)據(jù)庫拖垮了。這類問題測試階段其實能做很多事壓測階段對核心SQL做執(zhí)行計劃分析看有沒有走全表掃描、索引失效的情況。對數(shù)據(jù)增長量有預判。比如新功能上線后預計每月新增多少數(shù)據(jù)量核心查詢的耗時增長趨勢是什么樣。特殊數(shù)據(jù)邊界比如超級長的字段、null值、空列表、超大數(shù)據(jù)量下的分頁查詢都值得專門構(gòu)造測試用例去驗證。2.3 功能開關(guān)與灰度配置改動要留后路這一點我自己吃過虧有一次功能改造涉及老版本數(shù)據(jù)展示邏輯當時覺得反正新版本數(shù)據(jù)都是新結(jié)構(gòu)就把兼容代碼刪了。結(jié)果上線后發(fā)現(xiàn)有用戶的歷史數(shù)據(jù)還是舊結(jié)構(gòu)的展示直接裂開。后來學乖了凡是涉及數(shù)據(jù)結(jié)構(gòu)變更、展示邏輯變更的都要求開發(fā)加一個功能開關(guān)默認走新邏輯但開關(guān)一關(guān)就能回退到舊邏輯。這樣上線后即使出問題也能快速止損而不是干等代碼回滾。至于開關(guān)加在哪個層級開關(guān)的默認值是什么開關(guān)關(guān)閉后對數(shù)據(jù)是否有影響這些都要在測試階段驗證一遍。上線流程文檔里也應該把這個環(huán)節(jié)寫進去。3. 上線當天的測試節(jié)奏不是發(fā)完版本就結(jié)束了很多剛?cè)胄械臏y試同學以為上線就是運維把包發(fā)出去然后測試點幾個頁面確認一遍就完事。實際不是的上線當天的測試工作要分三段走。3.1 發(fā)布過程中的觀察點一秒都不能走神發(fā)布動作從開始到完成通常有幾秒到幾分鐘的時間窗口。這個窗口內(nèi)系統(tǒng)可能處于新舊版本交替、重啟、實例切換的狀態(tài)最需要盯的是發(fā)布日志有沒有報錯。啟動報錯、連接超時、依賴初始化失敗的日志尤其是那些不影響啟動但會影響功能的warning級別日志寧可早點發(fā)現(xiàn)早點處理也不要等用戶來報。鏈路狀態(tài)。如果公司在用注冊中心、網(wǎng)關(guān)這類基礎(chǔ)設(shè)施觀察服務實例是否正常注冊、流量是否在預期范圍內(nèi)切換。關(guān)鍵告警有沒有觸發(fā)。這時候不能只看業(yè)務日志CPU、內(nèi)存、磁盤、網(wǎng)絡I/O這些系統(tǒng)指標也得盯著一旦有異常波動多半是發(fā)布出來的副作用。我的做法是準備一個發(fā)布觀察清單上面列著本次發(fā)布需要關(guān)注的服務名、關(guān)鍵日志關(guān)鍵字、重點指標發(fā)布的時候拿著清單逐項看不靠腦子記。3.2 冒煙驗證清單從主流程開始優(yōu)先級最高的事先做發(fā)布完成后最先做的是冒煙測試不是全量回歸。冒煙測試的目的是用最快的速度確認系統(tǒng)能跑通最核心的業(yè)務路徑比如用戶能不能登錄、主流程能不能走完、核心交易能不能完成。所以冒煙用例要短、要核心、要快優(yōu)先級排布可以參考這樣的邏輯第一條跑對系統(tǒng)存亡影響最大的鏈路比如登錄鑒權(quán)、網(wǎng)關(guān)轉(zhuǎn)發(fā)、數(shù)據(jù)庫連通性。第二條跑本次版本涉及的最核心功能改動點。第三條跑老版本主流程確認沒有明顯回歸。第四條看關(guān)鍵的聯(lián)調(diào)外部服務支付網(wǎng)關(guān)、短信服務、第三方推送等是否可連通。提前把這些冒煙用例寫成自動化腳本可以節(jié)省不少人力而且比起手工點頁面腳本跑出來的結(jié)果更客觀也更快速。手工冒煙的缺點就是容易遺漏而且執(zhí)行人一緊張就容易操作變形。3.3 手工探索的核心區(qū)域重點用戶路徑的抽查自動化冒煙過了不代表高枕無憂。我會再抽幾條重點用戶路徑做手工走查尤其關(guān)注和這次變更相關(guān)的邊緣場景。比如改了訂單狀態(tài)邏輯那就重點走一遍不同類型訂單的狀態(tài)流轉(zhuǎn)改了支付流程那就把各種支付方式都點一遍。這些手工走查的好處是可以結(jié)合界面上下文和各種異常狀態(tài)比腳本覆蓋的場景更靈活。4. 發(fā)布后的黃金盯守期前30分鐘到前3小時每一條告警都要當回事版本發(fā)布后的頭幾個小時是最關(guān)鍵的。用戶反饋還沒大規(guī)模擴散問題發(fā)現(xiàn)得越早影響面就越小。這段時間測試不能閑著要做的事情很多。4.1 線上回歸的執(zhí)行順序與版本風險點逐一對應我一般會做三輪線上的回歸盯守第一輪發(fā)布后15分鐘內(nèi)核心鏈路巡檢。用上面的自動化冒煙腳本跑一遍加上關(guān)鍵日志的關(guān)鍵詞掃描比如ERROR、Exception、超時等看有沒有異常情況。第二輪發(fā)布后1小時內(nèi)圍繞本次版本變更點的功能驗證。把測試環(huán)境驗證過的業(yè)務場景在線上環(huán)境各走一遍主邏輯路徑。第三輪發(fā)布后2到3小時觀察用戶行為鏈路。這個階段更多是靠日志和監(jiān)控數(shù)據(jù)比如核心接口的耗時趨勢有沒有上升、錯誤率有沒有明顯波動、用戶側(cè)有沒有形成投訴。測試階段的線上回歸目標不是把線下的所有用例在線上重跑一遍——線上環(huán)境和數(shù)據(jù)條件都不允許。真正要做的是把風險最高的那部分驗證點覆蓋掉然后用監(jiān)控數(shù)據(jù)來兜底。4.2 線上問題與Bug的處理邊界什么該提單什么該立即上報線上出問題的時候最忌諱的就是按測試階段的方式走提Bug-開發(fā)修復-驗證-關(guān)閉的流程這會耽誤事。線上問題的處理要按嚴重級別分流嚴重級別表現(xiàn)處理動作P0主流程不可用、大面積報錯、資損、數(shù)據(jù)損壞立即上報通知研發(fā)/運維/產(chǎn)品決策是否回滾測試配合復現(xiàn)和定位P1核心功能受損但有小路可走、部分用戶受影響30分鐘內(nèi)響應評估影響范圍確認是否有臨時該干的事P2非核心功能異常、不影響主流程正常提單按常規(guī)迭代節(jié)奏處理測試在線上問題中的作用不只是復現(xiàn)一下這個bug更關(guān)鍵的是快速判斷影響范圍受影響的是哪些用戶群、哪些功能模塊、什么時候開始出現(xiàn)的。這些信息能給到?jīng)Q策層做判斷是緊急修復、回滾還是先撐一下再看。4.3 回滾決策的思路什么樣的評價要在一小時內(nèi)做出來回滾是一個很重的動作但是很多問題撐到最后也只能回滾。測試要清楚一件事回滾不僅僅是一個技術(shù)動作它代表著一整套流程要倒退重來。所以回滾決策不是出了錯就要回滾而是要看幾個因素問題影響面是否還在擴大。如果影響范圍可控可能先用功能開關(guān)把新邏輯關(guān)掉如果影響面不可控回滾要趁早。問題的修復成本和時間。如果開發(fā)預計一小時內(nèi)能修復可能不必回滾先出個熱修包試試如果修復時間無法估算回滾是更優(yōu)的選擇。不可逆的變更要對沖。如果是涉及數(shù)據(jù)庫遷移之類的不可逆操作更要提前在發(fā)布方案里plan好回滾之后的補償邏輯。這里分享一個經(jīng)驗回滾決策要前置回滾方案不要等出問題的時候才臨時寫。測試在發(fā)布前評審階段就應要求研發(fā)把每次發(fā)布的回滾方案寫清楚方案里必須有明確的觸發(fā)條件、執(zhí)行步驟、驗證方法。多數(shù)團隊能做好第一項和第三項第二項的執(zhí)行步驟往往寫不細。出問題的時候運維和執(zhí)行人要么靠臨場反應要么靠不完全的方案動作變形就會在后面造成更多麻煩。5. 上線流程里的三類不顯眼但致命的問題數(shù)據(jù)、緩存、外部依賴有些問題不是邏輯錯也不是環(huán)境差而是軟件系統(tǒng)里一些底層模塊在上線流程里被忽略了。這三個大頭我單獨提出來給同行們多個參考維度。5.1 數(shù)據(jù)層面的上線動作不是只有DDL那么簡單發(fā)布單里有表結(jié)構(gòu)變更的測試階段必須驗證數(shù)據(jù)遷移腳本的可執(zhí)行性和可重復性。有的腳本只能跑一次跑第二次就報錯這種腳本在灰度發(fā)布場景下就很危險。要專門驗證腳本在空庫、有歷史數(shù)據(jù)、有大表等不同場景下的表現(xiàn)。初始化數(shù)據(jù)的冪等性也要驗證。線上執(zhí)行初始化腳本時如果腳本里包含插入默認配置之類的操作一旦執(zhí)行到一半因為某條數(shù)據(jù)重復導致中斷后續(xù)再補跑就很容易出現(xiàn)數(shù)據(jù)錯亂。規(guī)格上應要求每次發(fā)布的腳本都把冪等邏輯寫清楚。老數(shù)據(jù)的清洗和兼容性處理要有專門的測試用例。新代碼上線后老數(shù)據(jù)必須能被正常讀出來、正常展示。我知道有些團隊測試階段只造新數(shù)據(jù)不提前歷史數(shù)據(jù)這就遺漏了一個風險面。5.2 緩存層面的上線動作版本更新后緩存怎么辦緩存是上線最容易被繞過去的環(huán)節(jié)。改了商品詳情的展示邏輯但緩存里有舊邏輯生成的商品數(shù)據(jù)用戶看到的和預期不符。這個問題不致命但很容易讓項目組以為上線失敗了。處理方式有這么幾種按成本和效果排發(fā)布前評估本次改動是否會涉及緩存結(jié)構(gòu)變化如有應提前設(shè)計好緩存預熱方案別拿空緩存去扛流量。關(guān)鍵緩存設(shè)置好版本號發(fā)布時切換緩存版本新版本自然用新邏輯生成緩存。發(fā)布后巡檢緩存命中率如果出現(xiàn)命中率大面積掉下來的情況得留意是不是緩存key的變化導致緩存大量失效引發(fā)后端壓力升高。5.3 異步消息與時序問題上線后最磨人的問題來源還有一類問題測試環(huán)境死活測不出來上線后間歇性閃現(xiàn)最后定位到是異步消息或任務調(diào)度的時間順序問題。比如用戶下單后發(fā)送消息通知庫存扣減但消息消費的時序在兩個環(huán)境里不一致定時任務在發(fā)布期間被重復觸發(fā)導致數(shù)據(jù)重復寫。應對這類問題的思路測試階段要設(shè)計時序類、并發(fā)類的用例別只測單線程場景。了解本次發(fā)布涉及哪些消息隊列、哪些定時任務確認它們的消費者/執(zhí)行器的變更情況必要時在發(fā)布期間屏蔽定時任務的觸發(fā)窗口。發(fā)布方案里把消息中間件、任務調(diào)度平臺的運維注意事項寫清楚有需要暫停調(diào)度任務的話務必申請暫停時間。說句實在的這三類問題里數(shù)據(jù)問題最要命緩存問題最隱蔽異步問題最磨人。但好在它們都是可以提前設(shè)計的只要在流程里固化相應的檢查項上線風險能降一大截。6. 把上線流程固化成一個可復制的機制線上發(fā)布檢查清單與交付到這兒上線流程已經(jīng)不是某個人的經(jīng)驗而是一個有章可循的標準動作。項目團隊最怕的是一批人走了流程經(jīng)驗跟著走了下一批人重新踩坑。所以流程要落成文件、要落成清單這既是工作效率的保障也是測試團隊話語權(quán)的體現(xiàn)。6.1 發(fā)布checklist該怎么設(shè)計設(shè)計checklist的時候如果條目太多就等于沒有checklist因為執(zhí)行人根本看不完。我會把它分成兩類必做項硬性門檻變更清單完整、可回溯測試環(huán)境和線上環(huán)境的配置差異項已確認已知缺陷的影響范圍評估完成且有處置結(jié)論數(shù)據(jù)遷移腳本已驗證可執(zhí)行、可重復、可回滾回滾方案、功能開關(guān)預案已落實核心鏈路自動化冒煙用例通過職責項按角色拆分的檢查內(nèi)容開發(fā)確認代碼分支無誤、上線腳本已驗證、配置項提交完整測試冒煙清單通過、監(jiān)控告警已接入、線上回歸計劃就緒運維發(fā)布窗口已確認、監(jiān)控大屏就緒、資源水位有數(shù)產(chǎn)品運營側(cè)公告/客服話術(shù)就緒、用戶溝通預案就位這套checklist的價值不只是上線前逐項打勾更是給大家一個統(tǒng)一的溝通語言避免同一件事你說東他說西。6.2 發(fā)布復盤怎么開才有用很多團隊上線后例行開個復盤會結(jié)果開了兩張嘴皮子就散了沒留下什么可改進的東西。我的建議是復盤會不要糾結(jié)誰的責任而要復現(xiàn)三件事本次發(fā)布過程中的時間線。什么時候發(fā)布、什么時候發(fā)現(xiàn)異常、什么時候決策、什么時候解決。把這條時間線擺出來大家自然知道哪個環(huán)節(jié)花的時間不合理哪個環(huán)節(jié)的決策被拖住了。下一步需要改進的機制性動作。不能只停留在下次小心點這次多注意。要有明確的任務分配比如下次上線前測試要提前兩天檢查數(shù)據(jù)遷移腳本下次發(fā)布運維要在發(fā)布開始前確認告警通道可用。做得好的部分也要總結(jié)。別光盯著問題。哪個環(huán)節(jié)因為流程清晰節(jié)省了時間、哪個功能因為測試覆蓋到位沒有出問題把這些經(jīng)驗提煉出來變成后續(xù)流程的執(zhí)行標準。6.3 測試自動化的切入點上線流程里的自動化不只是為了省人力更是為了保證上線那一刻的動作不變形。從我的經(jīng)驗看以下幾個自動化點收益最高值得優(yōu)先投入核心鏈路的發(fā)布后冒煙腳本?;ú涣颂喙ぷ髁康看紊暇€都能跑一遍安心程度提升一大截。數(shù)據(jù)/配置差異對比腳本。測試環(huán)境、預發(fā)環(huán)境、線上環(huán)境的配置對比用腳本掃一遍比自己人肉對一遍可靠得多。發(fā)布日志的關(guān)鍵詞監(jiān)控。在日志平臺里配好ERROR、Exception、timeout等關(guān)鍵字的實時告警異常情況不用人肉眼去翻日志。線上核心接口的自動化巡檢。定時跑關(guān)鍵接口的正確率和耗時上線后如果指標掉下去能提早捕捉到問題。這些自動化的投入不一定需要多大成本先從最痛的點開始跑順了一個再逐漸擴展。我見過太多團隊一上來就想著搞一套全自動的發(fā)布流水線結(jié)果搭了三個月還沒跑通連最基礎(chǔ)的冒煙腳本都沒人寫。先小步快跑跑起來再優(yōu)化比大而全的空想方案強得多。說白了項目上線流程這一整套東西本質(zhì)上是把一個高風險的儀式變成一套可控的、可預期的標準作業(yè)。測試在這個流程里既是最后一公里質(zhì)量的守門人也是發(fā)布風險的早期預警者。這一套流程能跑順不是某個人特別厲害而是每個參與者都對流程有敬畏心知道每一步該干什么、為什么這么干。