2017年1月15日 星期日

[iThome第8屆鐵人賽 19]靜態程式碼分析之Assembly品質分析 - Code Analysis(以前的FxCop)

在了解完如何分析測試碼的涵蓋率(也代表測試品質)之後,我們將來看另外一種保持程式碼品質的方式,也就是透過靜態程式碼分析。

在.Net的世界里,從最早期的而外工具FxCop,到後來進化成為VS一部分的Code Analysis就是專門在做這個方面工作的工具。

在這篇將會介紹如何使用Code Analysis,並且如何把它整并到我們的Build Script裡面。

廣義來說,靜態程式碼分析應該是針對源代碼(Source Code)作分析,實際上Code Analysis其實是對Assembly作分析,而Assembly也是IL,所以真的要叫做靜態程式碼分析應該也沒錯,只是 真的要嚴格說起來,Code Analysis應該不能夠稱之為靜態程式碼分析。不過以下我還是會稱之為靜態程式碼分析。(有點繞口)

什麼是靜態程式碼分析?

靜態程式碼分析其實就是一個針對原程式碼掃描並且把裡面的結果和規則(RuleSet)做比對,如果有哪些程式碼不符合規則將會爆出訊息。

舉例來說,資安風險裡面一個最常見的風險之一就是sql injection - 因此有專門規則是在找出程式碼那裡使用了可能導致sql injection的程式碼。

從某種程度來說,靜態程式碼分析和聽到的白箱資安掃描其實是同一種類的東西。

在各個語言基本上都有靜態程式碼分析的工具,尤其是像有些不需要編譯的語言(例如javascript)更是大量使用靜態程式碼分析來增強程式碼品質,這種分析工具在Javascript或者css 稱之為lint

.Net世界的靜態程式碼分析 - Code Analysis

在.net世界裡面,最早提供靜態程式碼分析的工具是FxCop。這個工具當初是一個另外下載的一個console程式,並且用它做執行。

再後來,FxCop被微軟整合到了VS裡面,稱之為Code Analysis,並且在VS裡面提供了方法方便執行這些分析。

因此,要使用靜態程式碼分析並不需要另外安裝什麼東西,VS就包含了這個工具。

在接下來將會看看在VS裡面到底如何使用此工具。

如何在VS執行Code Analysis

在VS裡面也有兩種執行的方式:

  1. 手動執行
  2. 建制的時候自動執行

手動執行

Analyze功能裡面可以先對每一個project用的規則做設定,然後就可以手動執行。

設定使用規則

  1. 在Tool bar選擇:Analyze -> Configure Code Anaysis - > For Solution
  2. 可以設定每一個專案所要使用的規則集
  3. 如果想自訂規則集也可以

image

開啟設定規則集的畫面

image
選擇專案使用的規則集

執行靜態程式碼分析

Analyze -> Run Code Anaysis -> For Solution

image
執行靜態程式碼分析image
執行結果有問題會出現在Erro List清單
預設的規則集沒有那麼嚴,所以應該不會看到任何Warning,如果這個時候把規則集改成All就會看到。

建制的時候自動執行

能夠手動執行當然好,但是不能夠自動執行嗎?

在Visual Studio其實有提供設定讓Code Analysis在兼職的時候自動執行。

對要設定建制自動執行的專案點 右鍵 -> Properties -> Code Analysis 然後把 Enable Code Analysis on Build打鉤即可

image

image
設定畫面

在這邊也可以設定要用那個規則集和更詳細調整哪一個規則要開啟:

image
規則集調整設定
image
設定畫面

在build的時候在執行靜態程式碼分析

既然能夠手動執行和在建制的時候自動執行,那為什麼不在那個時候執行就好?

原因很簡單,時間問題

當專案越來越大,每跑一次靜態程式碼分析的時間會需要越來越長。在考慮到還要執行單元測試,整個加在一起會拖累整個開發速度。

所以為了整個開發的速度能夠快,但是又不犧牲程式碼的品質,這種靜態程式碼分析通常都是在build server執行 - 因為那個時候要執行多久都不會打斷開發時間。

要在build的時候執行靜態程式碼分析,需要設定三個參數:

  1. RunCodeAnalysis=true - 表示要執行靜態程式碼分析
  2. CodeAnalysisRuleSet=AllRules.ruleset - 要用那個規則集執行 - 出入內建的規則集 如果有客製規則集,可以把規則集的路徑放入參數
  3. CodeAnalysisTreatWarningsAsErrors=true - 這個主要目的是把靜態程式碼分析出來有問題的部分當做Error而不是Warning。

最後,default.ps1調整如下:

task Compile -depends Clean, Init -description "編譯程式碼" `
    -requiredVariables solutionFile, buildConfiguration, buildTarget, buildTempDirectory `
{ 
 Write-Host "開始建制檔案:$solutionFile"

 $buildParam = "Configuration=$buildConfiguration" +
     ";Platform=$buildTarget" + 
     ";OutDir=$buildTempDirectory"
 
 $buildParam = $buildParam + ";GenerateProjectSpecificOutputFolder=true"
 $buildParam = $buildParam + ";RunCodeAnalysis=true;CodeAnalysisRuleSet=AllRules.ruleset;CodeAnalysisTreatWarningsAsErrors=true"

 exec {msbuild $solutionFile "/p:$buildParam"}
}

結語

這篇快速介紹了靜態程式碼分析,並且如何在VS和build script裡面使用。

實際上這個可以更詳細的看每一個規則,和介紹一下一般來說那些要打開,不過這個畢竟不是這個系列的重點。

希望透過這篇,就能夠立竿見影開始使用靜態程式碼分析來提升程式碼品質。

在下一篇將會介紹另外一個角度的靜態程式碼分析 - 用來統一團隊開發風格的工具StyleCop。

相關資料

  1. Disable Code Analysis for Some Projects using MSBuild
  2. How do I specify a ruleset from MSBuild
  3. TFS Build ignores configured Code Analysis ruleset
  4. Treat Warnings as Errors has no effect
  5. Visual Studio 2013 Static Code Analysis in depth: What? When and How?


沒有留言 :

張貼留言