我們時時在踩坑,有時也忍不住埋怨前人給我們留下了無數的坑,可回頭想想,自己是不是也在挖坑等別人踩…
上次聽 趙海平 的講座,他提到 Facebook 沒有測試人員,以前和現在都沒有,以後也不打算有。還提到上線之後就開發者坐在系統前等著,只要有bug,系統能夠在五分鐘之內檢測到,並提供快捷方式修復。我驚歎的是他們能夠在五分鐘之內監控到所有的問題,實時回饋並及時修復。
當然在探討質量保障這個話題前,我們需要明確幾個關鍵點:編碼前、提交程式碼、測試、上線、回滾、上線後。針對這幾個點,下面我談一談我的看法。
一、編碼前
上家公司實習期間印象最深的交流是參與編碼規範討論,當時我還呼呼的整理了兩份文件:前端編碼規範之JavaScript,前端編碼規範之CSS。後來也看到團隊在各種工具上新增控制和提示,如 Sublime Text 新增 jslint 配置,專案目錄下新增 .jslint 配置,打包工具提示程式碼的不規範,強制修復等等。
上面提到的程式碼規範主要是程式碼展現層面的規範,他可以讓團隊寫出來的程式碼就跟一個模子刻出來似的,結構、命名、函式體大小等等很接近,看著很舒服。舉幾個例子說明他的重要性。
1. 統一使用 UTF8 編碼
我平時開發都是使用的 UTF8 編碼。有次從倉庫拉下來發現很多檔案都是 GBK 編碼,修改時一個檔案忘記轉換編碼,提交發現 錕斤拷 出來了。
2. TAB 縮排
我比較喜歡使用四個空格作為 TAB 縮排。一次多人開發的時,發現同事的程式碼是兩個空格的縮排,結果,我改成了四個空格提交之後,又被改回來兩個空格,然後我接著改回去…
3. 加不加分號
以前寫過一篇文章,談了下自己對分號的看法:Javascript分號,加還是不加?,我的回答是加但非必須。
程式碼的規範,對程式本身的意義並不是很大,他不會作用在程式的邏輯上,作用點在於團隊合作。一個專案可能是多人開發,也可能是今天我開發,明天託付給你。如果兩個人在編碼習慣上的差異很大,就會偏頭痛…有一點需要特別提出來,就是寫註釋!某次排查一個線上問題,找到了問題所在的檔案,但是檔案中的邏輯實在是太過複雜,四五百行程式碼僅三行註釋,眼睛都看花了。其實只要在大段的程式碼前加幾句註釋,說明本段程式碼的大意,在排查定位問題的時候就可以忽略一部分程式碼塊,可以為修復線上bug爭取不少時間。
二、提交程式碼
這部分特指工具。可以說過了工具這一道關卡,程式碼基本就獲得自由,bug 也就開始橫飛了。目前工具可以為我們做的事情:
1. 檢測
- 現在並沒有做 jslint 之類的配置,所以程式碼的展示是沒怎麼規範的。
- 編碼應該統一為 UTF-8 格式,如果不是這種格式,工具應該有所提示。
- 程式碼塊過長提示,一個函式不應該寫到幾百上千行,拆分程式碼剛開始是辛苦,一旦後續複用的時候,就會很爽很爽了(當然,剛開始編碼的時候就應該考慮一個函式的顆粒度控制)。
更重要的是對語法的檢測,我們可能把 document
拼寫成了 doucment
,甚至使用 for in
來遍歷一個陣列,這種問題時而出現,工具是否考慮幫助我們處理掉一些簡單的愚蠢的錯誤。
2. 壓縮
壓縮程式碼的時候,我踩過坑:gulp打包壓縮css遇到的坑,我相信很多人都認識 grunt 和 gulp,但是一定鮮有人自己配置過這些東西,並投入到專案中。
程式碼的壓縮,一方面可以減少線上流量,一方面也是出於安全的考慮。壓縮後的程式碼線上報錯很難定位到準確的位置,有些問題只能在使用者的電腦上覆現,“代理到本地這個法子”遠端操作的時候是不靠譜的。壓縮不僅僅應該把程式碼縮短,還要考慮線上排查問題的難度。
在壓縮的時候可以考慮新增空行,將網頁錯誤定位範圍縮減到單個檔案。也可以使用 sourceMap 之類的輔助方式。在這篇文章中有過一些討論。
3. 合併
很多事情,別人不考慮,工具就得考慮。
這裡有一個思考,HTTP2.0 支援多路複用,一個連線可以進行多次 HTTP 的傳輸,那以後的 sprite 圖、檔案的合併等是不是也應該重新考慮了。檔案的全部合併真的是最省資源的方式麼?是否可以考慮更多的合併方案?
三、測試
趙海平 說,技術實踐中的三件套:功能 + 測試 + 監控。很多大公司的工程師,深諳功能開發之道,測試方面也能達到 60 分的水平,但是程式的監控上,做的很差,包括 Facebook 的程式設計師。三件套,對一個優秀的工程師來說,缺一不可。
這裡要說的是程式開發三板斧的第二板,測試。
我們很自然地聯想到了QA,阿里有一大波的測試人員。寫完程式碼提測,好像剩下的就只是測試同學找BUG,我們等著修BUG。前端的測試跟後端還不太一樣,邏輯可以測,但是 UI 效果、互動效果不好測,只能靠幾雙眼睛盯著看,幾個滑鼠不停地點點點。。。
雖說邏輯可以通過寫測試用例進行測試,會去寫測試用例的人卻不多。我記得當時學習 AOP 程式設計的時候,給 ajax 新增了一些 mock 功能,可以在頁面上模擬請求測試效果(如jquery-mockjax)。
編寫測試用例確實可以解決很多的問題,但是如何培養編寫測試用例的習慣,如何更加便利的測試我們的測試用例,這又是一個值得思考的話題。
自動化工具一大缺點是很難捕獲到特定環境下的錯誤。據統計,不管你的程式碼寫得多健壯,在一千個使用者下,總有那麼一個使用者,因為瀏覽器安裝了外掛、網路問題等導致程式碼報錯,再比如我們在做灰度測試的時候,讓使用者名稱首字母為 a-m 的使用者命中灰度時出現的錯誤等等,這些錯誤自動化測試工具是無法發現的。
所以我們要把 錯誤日誌統計 靈活地使用起來,他能夠使你深入使用者,拿到最原始的錯誤資訊。
四、上線
現在涉及到前端上線的,有多個地方(公司有很多釋出系統):
- TMS釋出
- aone2釋出
- gitlab釋出
- awp釋出
- etc.
gitlab釋出通過域名嚴格區分測試、預發和線上環境,操作界限明確,出錯的概率還是很低的(這要求開發者對 git 命令的操作十分熟練),如果幾次 reset revert stash 之後便開始犯蒙,那出問題的概率就增大了。每次打下 tag 之前,我都會很仔細地 diff 下程式碼,看看本次釋出和上次釋出之間做了哪些修改,確認這些修改點再 push tag。
aone2的釋出,並不是每個人都用過,它的靠譜在於有三種釋出方式:
- 全網釋出,半小時完成
- 小淘寶環境灰度釋出,兩小時完成
- 分三次釋出,小流量上線,一天完成
同時也提供了十分方便的回滾機制,只要擁有應用的許可權,可以隨時回滾程式碼,效率極高。
TMS 的釋出,我覺得是問題最多的。首先,前端和運營都會擁有釋出許可權,運營喜歡“瞎搞”,部分頁面(如JSON輸出)並沒有提供頁面預覽,運營填完之後也不會跑到頁面檢視效果,於是就出問題了。。TMS釋出每次修改只釋出一個檔案,CDN 釋出一個檔案的速度是很快的,當你點選發布的那個瞬間,整個同步就基本完成了。可是,當某個節點同步出錯,TMS 並沒有給出提示,這是第二個隱患。第三個點,TMS坑爹的沒有灰度,對一些重要的釋出,沒有灰度就需要十分十分的謹慎,雖說出錯可以及時回滾,但萬一沒有看到隱性的錯誤,那就悲慘了。
五、回滾
沒人可以保證自己寫的東西絕對不出問題,因為有太多的環境因素是我們想也想不到的,比如最近某類控制元件在小淘寶環境下全掛了,試問,前端怎麼會想到這是Nginx 的灰度系統出問題了,在灰度釋出的時候檔案沒有同步成功,導致整個灰度環境出錯。
所以,一定要給你的程式想一套快速回滾方案。尤其是在做 ABTest 的時候,新版的效果不好需要回滾到之前的狀態,這種事情經常有。
回滾需要注意兩點:
- 要快。
- 上一個狀態要保證無錯誤。
只要我們能夠保證發到線上的每一個版本都是穩定版,那回滾就是 0 風險的事情。
六、監控
程式開發三板斧的第三板,監控。前端對測試就不太重視,更不用提監控了。沒有監控就只能提心吊膽的過日子。
其實我們使用自動化工具測試、每天用肉眼頂著自己的頁面看,這些都屬於監控,但是深入到使用者的監控,我們做的太少!
七、小結
看到老大在群裡發了幾條研發相關的紅線:
1、禁止程式碼未經測試釋出;
2、禁止程式碼釋出後不進行線上驗證;
3、禁止核心應用釋出沒有對應的回滾方案。
毫無疑問,這些都是必須嚴格遵守的。規範會先把壞習慣壓住,進而被理解,最後被消化吸收。
前端質量保障之路,任重而道遠!