如何提高 Web 應用的代碼質量

「我只是修改了一個 if 條件,沒有想到它致使持續集成失敗,部署也所以失敗,還影響了 QA 測試其它功能。」css

Web 應用的質量提高,是一個很是有意思的話題。咱們明知道有一系列的手段能夠提高代碼質量,可是限於多種緣由,咱們並不會去作。在我工做的第一個項目裏,因爲你們都是年輕人(Junior Consultant),咱們實施了一系列的基礎措施,來提高應用質量,諸如寫測試、追求測試覆蓋率、運行預提交腳本等等。前端

在最近的這個項目裏,咱們面臨着相似的問題——須要提高項目的代碼質量。因而,便想寫一篇文章介紹一個相關的內容。這篇文章大體能夠分爲這幾個部分:git

  • Web 應用的質量問題
  • 使用測試提高質量
  • 使用 Lint 和 Git Hooks 檢測代碼
  • 如何防範危險提交

那麼,讓咱們繼續回到老生常談的 「Web 應用的質量問題」。bash

Web 應用的質量問題

Web 應用一般面臨着上線和質量之間的博弈——只要不影響用戶體驗,小的 Bug 每每對於項目來講能夠 「容忍」 的。這樣一來講能夠早些上線,實現用戶價值。除此還有其開發的影響:一個是敏捷方式的開發週期,一個則是能夠屢次上線。app

故而,Web 開發與一些特殊領域及行業的軟件開發不一樣,在這些特殊的行業裏,一個開發成本上億的軟件,可能只會運行、部署一次,不會有第二次機會,如原子彈的控制系統。還有一些類型的案例,就是智能汽車上的自動駕駛系統,稍有不慎就是車損人忙。至關於 Web 應用雖然更新困難,可它們仍是能遠程更新的。可是在這些系統上,它們就更追求系統的質量,而不是開發速度。Web 應用部署失敗能夠回滾,雖然會帶來必定的錢力損失,可是極少帶來生命危險。編輯器

所以在質量速度方面,在 Web 開發上所以保持着一個微妙的平衡。函數

可軟件開發不只僅只有質量和速度的問題,還有一個產品問題——即,能作出符合用戶需求的產品。因而,就變成了質量-速度-需求,一個更復雜的平衡。爲了交付出更符合用戶需求的產品,就不得不常常作一些需求變動。而取決於這些變動的時間,它每每會影響到代碼質量和開發速度——實現一個需求的時間越短,那麼其測試的時間越短,Bug 出現的可能性就更高。過去我遇到過,今晚上線,下午臨時改需求。可想而知,測試人員是沒有時間測試的。工具

在這個時候,持續集成只能顯式地告訴咱們,咱們的測試掛了,咱們的某些功能 broken 了,咱們不該該部署這個新版本。然而並非持續集成出問題了,咱們就不能部署,咱們仍然仍是能部署的。post

Blabla,那麼問題來了,最有效的方式呢?單元測試

使用測試提升質量

用於保證這個項目的質量,在代碼提交以後,會通過一系列的測試:

  • 單元測試
  • 自動化 UI 測試
  • 開發人員手動進行集成測試
  • 測試人員進行 3~4 輪的測試

若是隻是宏觀來看一個項目的測試的話,那麼在一個敏捷項目裏,測試能夠分爲這麼幾個階段:

  • Dev (開發)環境的 Desk Check,主要用於演示功能是否和需求一致。
  • QA (測試)環境的測試,用於進行一些常規的測試。
  • ST (System Test)環境的測試,經常使用於與第三方系統聯調。當出現第三方系統的時候,就須要該環境來集成。
  • UAT(User Acceptance Test,用戶接受測試)環境的測試,一般用由業務方的代碼來驗收產品是否符合需求。

若是一個 Web 應用能通過這麼一系列的測試,那麼它的質量在必定程度上是獲得保障的。因此,開發人員若是不想活得過久,就能夠 「不負責任」 地直接把功能扔給測試人員。笑~

但是,在有一些公司時吧,Bug 率但是會影響績效的,又或者是有這麼多 Bug 看上去不那麼專業,等等 blabla。

言而總之,總而言之,開發人員本身寫測試會更友好一些。按照測試金字塔理論來講,咱們須要三種類型的測試:

  • 單元測試,用於保證咱們的基礎函數是正常、正確工做的。
  • 服務測試,不只僅自身的服務,也會測試第三方依賴服務。
  • UI 測試,模仿用戶操做行爲的測試。

對於一個前端項目來講,咱們一般只須要兩種:單元測試E2E 測試。實際上,理論上應該還有 UI 組件的測試,可是通常而言,咱們在選用 UI 組件的時候,會考慮到組件的穩定性。

但是在多數國內公司裏,寫測試每每是不可能的。退而求次,咱們就須要一種更簡單而友好的方式,來作這樣的事情。

使用 Lint 和 Git Hooks 檢測代碼

在代碼提交以前,咱們還能夠進行一些常見的操做:

  • 靜態代碼分析(lint),用於進行靜態代碼分析,常見的如 Lint4j、TSLint、ESLint。
  • 運行測試,爲了避免影響持續集成,咱們須要在代碼提交以前進行測試。

現代的編輯器(使用相應插件)、IDE 能夠提升很好的技術手段,在開發的過程當中靜態代碼分析,並隨時提升建議。如 Intellij IDEA 和 WebStorm 就會根據 TSLint,來提醒開發者 TypeScript 代碼的一些規範問題。

這些分析工具主要進行一些代碼上的分析,如《全棧應用開發:精益實踐》一書所說,通常會進行以下一系列的風格檢測:

  • 規範函數名及變量
  • 代碼格式規範
  • 限制語言特性
  • 函數行數限制
  • 多重嵌套限制
  • 未使用代碼
  • 等等

而這些規範,若是沒有強制,那就是個遊戲。因而,咱們一般會依賴於 Git Hooks 來作這樣的事。對於一個使用 Git 來管理源碼的項目來講,Git Hooks 能夠作這麼一些事情,能夠在 .git/hooks 目錄下查看:

applypatch-msg     post-merge         pre-auto-gc        prepare-commit-msg
commit-msg         post-receive       pre-commit         push-to-checkout
post-applypatch    post-rewrite       pre-push           update
post-checkout      post-update        pre-rebase
post-commit        pre-applypatch     pre-receive
複製代碼

通常而言,咱們只會在兩個階段作相應的事情:

  • pre-commit,預本地提交。一般會在該提交以前,進行一些語法和 lint 的檢測。
  • pre-push,預遠程提交。一般會在該提交以前,運行一些測試。

因而,在咱們的這個前端項目裏,咱們就又寫了這兩個 scripts。對應的實現以下:

{
    "precommit": "lint-staged",
    "prepush": "ng test && ng build --prod"
}
複製代碼

precommit 時,咱們配合 lint-stagedprettier 來進行代碼格式化:

"lint-staged": {
    "src/app/*.{css,scss}": [
      "stylelint --syntax=scss",
      "prettier --parser --write",
      "git add"
    ],
    "{src,test}/**/*.ts": [
      "prettier --write --single-quote",
      "git add"
    ]
  }
複製代碼

事實上,使用 ng lint --fix 也是一個不錯的方式。

隨後,咱們在 push 代碼以前,即 prepush,進行了測試及 Angular 的構建 production 的腳本。因爲單元測試運行得至關的快,它能夠在幾分鐘內完成,快速對問題作出響應。而不是等到持續集成出問題時,再去修復。

可是 Git 提升了這一種的種選項,也提供了一個 --no-verify 的參數。它可讓開發者不須要進行上面的驗證,就能提交代碼。

咱們每每沒法阻止別人作這樣的事情,特別是當出現多個團隊協做的時候。

難以防範的危險提交

本來,我想將標題取爲 「有風險的提交」,可是我以爲危險的提交更爲可靠。

常見的有要去吃飯了、要下班了、要開會了等等,臨走前提交了一下代碼。功能可能自己沒有問題,可是它 block 後續的一系列行爲。

固然了出現不可坑的因素,如地震、火災等的時候,就不須要考慮這些事情了。

只是有了這些規範和實踐,能夠幫助咱們開發出更穩定的 Web 應用。

結論

開發速度和質量,是一個難以平衡的天平。在不一樣的時間裏,咱們應該作不一樣的技術決策。

相關文章
相關標籤/搜索