[Better Code]Visualize Code Relationships

Agile Development 2009. 5. 2. 18:40 Posted by kkongchi

image

위 그림처럼 이번 Visual Studio Team System 2010에서는 Analyze(분석) 메뉴에 새로운 기능이 하나 더 추가되었습니다. 바로 Visualize Code Relationships 메뉴입니다. (아직 한글로는 어떻게 번역될 지 잘 모르겠네요)

이 기능은 제목 그대로 코드의 관계를 시각화해서 보여 줍니다. UML 다이어그램과도 조금 다르고, 모델링 용의 DSL 다이어그램과도 조금 다르긴 하지만, 꽤 괜찮은 그림을 보여줍니다.

그림을 한 번 보기 위해서, 아래와 같은 아주 간단한 Visual Studio 솔루션을 한 번 구성해봤습니다.

image

구조는 간단합니다. WebApplication1이 WebService1을 Web Reference를 해서 호출하고, 다시 WebService1은 ClassLibaray1을 내부적으로 Reference해서 호출하는, 아주 흔한 형태의 Application 구조입니다. 그리고 ClassLibrary1 내부에서 Class2는 Class1을 사용합니다.

이 구조가 어떻게 시각화 되는지 한 번 볼까요?

1. Visualize Call Dependency – By Assembly

image

오른쪽 옆의 버튼을 누르면, 내부로 펼쳐지면서, 내부에 들어있는 클래스도 보입니다.

image 

2. Visualize Call Dependency – By Namespace

image

3. Visualize Call Dependency – By Class

image

프로젝트가 성숙하고 발전되면, 코드도 따라서 많아지면서 구조도 복잡해지기 마련입니다. 복잡도가 높아지면 높아질 수록 유용한 툴이 되지 않을까 싶습니다.

하지만, 지금 그림을 보시면 아시겠지만, WebApplication1이 Web Service1를 Web 참조를 하고 있습니다만 그림에는 그 참조 관계는 표시가 제대로 되질 않네요. 결국 직접적인 참조 외에는 다이어그램에서 보기가 힘든 것 같습니다. 쉽지 않겠지만, 그런 부분들도 표시할 수 있었더라면 정말 환상적이었을 텐데 하는 생각이 듭니다.

 

지난 번 글에서 Visual Studio Team System 2010의 향상된 Unit Test 기능에 대해서 살펴 본 바가 있었습니다. 오늘 소개드릴 PEX는 Microsoft Research 그룹에서 개발한 Automated Whitebox Testing Framework 입니다. 꽤나 긴 정의입니다만, 간단히 말하자면 자동으로 코드를 분석해서 WhiteBox Unit Test를 만들어주는 Visual Studio Extension입니다.

Blackbox Test – Blackbox Test는 우리가 코드 내부에 대한 지식이 없다는 것을 전제로 합니다. Blackbox Test에서는 코드의 노출된 API를 소비하는 Consumer의 입장에서 Function을 테스트하게 됩니다. 비교적 초기에 작성되는 Unit Test들은 이 Blackbox Test가 됩니다. 아직 Code가 성숙되지 않은 상태에서 API의 Requirements, Specification 등만을 가지고 테스트를 작성하게 되기 때문입니다. 하지만 코드 개발이 점점 진행됨에 따라서 Unit Test는 Whitebox Test로 이행되게 됩니다.

Whitebox Test – Whitebox Test는 코드 내부를 알고 있다는 것을 전제로 하는 테스트입니다. 우리는 코드를 알기 때문에 모든 가능한 성공/실패 시나리오를 모두 알 수가 있고, 특정 데이터나 입력 조건이 어떤 Flow를 따르는지에 대해서 충분하게 알 수 있습니다. 이런 가능한 모든 시나리오에 대해서 Unit Test를 작성하고 수행하게 되면 그것을 Whitebox Test라고 말할 수가 있습니다.

* 이는 Blackbox Test, Whitebox Test에 대한 일반적인 정의가 아니라, Unit Test관점에서 바라본 정의입니다. 일반적인 정의에 대해서는 Wikipedia의
Whitebox Testing, Blackbox Testing 항목들을 참고하시기 바랍니다.

Unit Test를 수행할 때에 대개 Code Coverage Test를 같이 수행하는 이유가 바로 우리가 작성한 Unit Test가 어느 정도 수준의 Whitebox Testing에 도달했는지를 알 수가 있기 때문입니다. 당연히 우리가 작성한 모든 코드에 대해서 완벽한 Whitebox Testing을 Unit Test를 통해서 수행했다면 Code Coverage Test의 결과는 100%가 되어야 합니다. 하지만, 실제로 Unit Test건 Manual Test Case건 Code Coverage Test결과가 100%에 도달하기는 참으로 힘듭니다. 일반적으로 80%정도를 목표로 하지만, 그 이하가 되는 경우가 대부분입니다. 그것은 복잡성의 문제이기도 하고, 비용 대비 효과의 문제이기도 합니다. 코드의 모든 경로를 통과하는 Unit Test를 작성하려면 엄청난 시간이 소요될 테니까요.

이 점이 PEX라는 제품이 나오게 된 배경이라고 할 수 있습니다. PEX는 Visual Studio의 코드를 분석해서, Input과 output 조합을 찾아서 자동으로 테스트 코드를 만들어 줍니다. 자동으로 생성된 테스트 코드이지만, 높은 Coverage를 보여 줍니다. PEX를 사용하면, Unit Test 작성에 들이는 수고를 상당히 줄일 수 있을 것 같습니다.

 

PEX 홈페이지는 http://research.microsoft.com/en-us/projects/pex/default.aspx 이며, 현재 Visual Studio Team System 2008과 2010에서 사용할 수 있다고 되어 있습니다. 즉, 현재 VSTS 2008을 쓰고 계시는 개발자 분이라면 다운로드 받아서 써 보실 수 있다는 의미입니다. 현재 정식 버전은 아니고 Pre-release 버전입니다. 그리고 Visual Studio 2008 Professional 버전을 위한 비 상업용 Academic 버전도 다운로드 받을 수 있습니다. 다운로드 링크는 http://research.microsoft.com/en-us/projects/pex/downloads.aspx 입니다.

이번 글은 개요이니까, PEX Tutorial에 나오는 간단한 샘플만 잠시 보도록 하겠습니다.

   1:  [PexMethod]
   2:  public void ParameterizedTest(int i)
   3:  {
   4:       if (i == 123)
   5:           throw new ArgumentException("i");
   6:  }

Integer 타입의 매개 변수를 받는 간단한 메소드입니다. 매개 변수가 123일 때에는 ArgumentException을 일으키는 딱 두 줄의 구현만 있을 뿐입니다. PexMethod Attribute는 이 메소드가 PEX Test method라는 것을 의미합니다. 이 메소드에 대고 마우스 오른쪽 클릭을 하게 되면 컨텍스트 메뉴에 다음과 같이 PEX 관련 메뉴들이 보이게 됩니다.

여기서 Run Pex Explorations를 선택하게 되면, PEX가 자동으로 코드를 분석해서 가능한 모든 매개 변수를 대입해 본 다음 그 결과를 바탕으로 아래처럼 결과를 보여주게 됩니다.

이 부분 – Run Pex Exploration 실행 - 에서 저는 예상치 못했던 에러를 만났습니다.

[critical] unexpected failure during exploration
System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Z3, Version=2.0.30325.1, Culture=neutral, PublicKeyToken=9c8d792caae602a2' or one of its dependencies.


위와 같은 에러였는데, 이 에러는 Visual C++을 설치하지 않았을 때에 발생하는 것으로 보입니다. 아직 PEX 설치 파일이 어떤 조건에서도 완벽하게 모든 필요한 파일들을 설치하지 못하는 것 같습니다. 이 에러는 Visual C++ 2008 SP1 Redistributable Package를 다운로드해서 설치하는 것으로 해결할 수 있습니다. 이 정보는 http://social.msdn.microsoft.com/Forums/en-US/pex/thread/5862d522-0c2e-481c-b537-864e7427a7e5 에서 얻었습니다. 혹시 Visual C++ 가 설치되지 않은 분들은 참고하시기 바랍니다.

예상대로 123이라는 매개변수가 입력되었을 때에 ArgumentException이 발생한 것을 볼 수가 있습니다. 그리고 여기서 또 다시 마우스 오른쪽 컨텍스트 메뉴를 통해서 Go To를 선택하게 되면 실제 자동으로 생성된 테스트 코드를 아래 그림처럼 볼 수가 있습니다.

   1:  [TestMethod]
   2:  [PexGeneratedBy(typeof(HelloWorldTest))]
   3:  public void ParameterizedTest01()
   4:  {
   5:      this.ParameterizedTest(0);
   6:  }
   7:   
   8:  [TestMethod]
   9:  [PexGeneratedBy(typeof(HelloWorldTest))]
  10:  [PexRaisedException(typeof(ArgumentException))]
  11:  public void ParameterizedTest02()
  12:  {
  13:       this.ParameterizedTest(123);
  14:  }

간단한 샘플이긴 하지만, PEX의 강력한 자동 테스트 코드 생성 기능을 볼 수 있으셨을 거라고 생각합니다. 다음 포스팅에서는 PEX에 대해서 더 깊이 들어가 보겠습니다. 아 물론, Code Analysis에 대한 글들도 계속 올릴 예정입니다. 읽어주셔서 감사합니다.

지난 번 포스팅에서 말씀 드렸던 것처럼 Visual Studio Team System 2010에서 이루어진 Code Analysis 기능 개선에 대해서 더 깊게 다뤄 보겠습니다. 그 첫 번째로 새롭게 추가된 Rule Sets 개념에 대해서 알아보도록 하겠습니다.


Visual Studio 2005, 2008에서의 코드 분석 설정

Visual Studio의 코드 분석 시스템에는 약 200개 정도의 규칙이 있습니다. 하지만, 사실 이 규칙들을 모두 준수를 해야 하는 것은 아닙니다. 모든 규칙이 나름의 이유와 정당성을 갖고 있다고 해도, 프로젝트의 성격에 따라, 모듈의 성격에 따라서 꼭 지켜야 할 규칙, 그렇지 않은 규칙, 심지어는 어쩔 수 없이 위반해야 하는 규칙도 있을 수 있습니다.

그래서 코드 리뷰를 할 때, 대부분의 경우 모든 규칙을 다 검사하지는 않습니다. 각각 케이스 바이 케이스로 규칙을 적절하게 조절하게 됩니다.

Visual Studio Team System 2005와 2008 버전에서는, 이런 설정을 Visual Studio Project Configuration에서 각 프로젝트 별로 할 수가 있습니다.

이 규칙 설정은 프로젝트 파일(.vbproj 혹은 .csproj)에 CodeAnalysisRules라는 Property 이름으로 아래와 같이 저장되게 됩니다. 내용을 보면 아시겠지만, “-“ 기호와 규칙 ID를 붙여 놓은 모양으로 되어있습니다. 즉, 거기에 열거된 규칙 ID를 Analysis Rules에서 빼는 형태로 저장이 되는 것입니다. 아래 샘플은 그래서 이 프로젝트는 코드 리뷰를 할 때에 Design Rule의 CA1000번 규칙을 검사하지 않는다라는 의미가 됩니다.

<CodeAnalysisRules>-Microsoft.Design#CA1000</CodeAnalysisRules>

이런 형태로 Visual Studio 프로젝트마다 다른 규칙을 적용할 수 있다는 것은 대단히 유연한 디자인이긴 하지만, 많은 수의 Visual Studio Project가 존재한다면, 관리가 참으로 어렵습니다. 그래서 예전에 Visual Studio Team System 2005 를 사용했던 프로젝트에서 전체 Visual Studio 프로젝트의 분석 규칙들을 통일하기 위해서, 개별 개발자들에게 위임하지 않고 제가 직접 모든 프로젝트를 텍스트 에디터로 열어서 저 부분만 Copy & Paste로 넣어서 Check-In하는 엄청난 단순 반복 작업을 한 적도 있습니다.

 

Visual Studio Team System 2010의 Rule Sets Feature

그래서 새롭게 출시될 Visual Studio Team System 2010에서는 Rule Sets라는 개념이 도입되었습니다. 이 Rule Sets 기능은 이름에서도 알 수 있듯이 Rule들을 미리 정해진 Set으로 관리할 수 있는 기능입니다. 이제 Visual Studio 프로젝트 별로 Rule을 하나 하나 빼는 수고를 할 필요가 없이 Visual Studio 프로젝트에 Rule Set을 지정하는 것으로 Code analysis를 커스터마이징할 수 있게 된 것입니다. 아래 그림에서 볼 수 있듯이, 하나 이상의 Rule Set을 선택하는 것도 가능합니다. (가장 아래의 Choose Multiple Rule sets를 선택하면 됩니다.)


Visual Studio Solution 전체에 Rule Set을 적용하는 것도 가능합니다. Solution Property에서 아래와 같이 설정할 수 있습니다.

 

위 그림에서 보시는 것처럼 마이크로소프트는 기본적으로 7개의 기본 Rule Set을 제공합니다. 이 기본 Rule Set의 목록은 다음과 같습니다.

  • Microsoft All Rules – 전체 Rule이 모두 포함된 Rule Set입니다.
  • Microsoft Basic Correctness Rules – 로직 에러와 자주 저지르는 실수를 예방하는 규칙들로 이루어진 Rule Set입니다.
  • Microsoft Basic Design Guideline Rules – Framework API 작성 상의 Best Practice에 집중된 Rule Set입니다.
  • Microsoft Extended Correctness Rules – Basic Correctness Rules를 확장하여, COM Interop이나 Mobile Application에도 사용 가능하도록 만들어진 Rule Set입니다.
  • Microsoft Extended Design Guideline Rules – Basic Design Guideline Rules를 확장해서, 사용성이나 유지 보수성도 체크할 수 있도록 만들어진 Rule Set입니다.
  • Microsoft Globalization Rules – Application의 Globalization에 있어서 문제가 있는지 검증하는데 집중된 Rule Set입니다.
  • Microsoft Minimum Recommended Rules - MS가 제안하는 최소한의 Rule Set입니다. 50개 정도의 규칙으로 이루어져 있습니다. 다른 대부분의 Rule Set들이 이 Rule Set을 포함하고 있습니다.
  • Microsoft Security Rules – 이름 그대로 보안에 집중된 Rule Set으로, 모든 Security 관련 규칙들이 모두 포함되어 있습니다.

 

물론 이 외에도 사용자가 직접 Rule Set을 편집할 수 있습니다. Rule Set은 .ruleset이라는 확장자를 가지는 XML 파일 포맷으로 되어 있습니다. 기본적으로 Visual Studio 2010에서 아래와 같은 UI를 통해서 편집할 수 있도록 되어 있습니다.


 

아래는 Rule Set 파일을 직접 Notepad로 열어본 것입니다.

<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Microsoft Basic Correctness Rules" Description="These rules focus on logic errors and common mistakes made in the usage of framework APIs. Include this rule set to expand on the list of warnings reported by the minimum recommended rules." ToolsVersion="10.0">
  <Localization ResourceAssembly="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.dll" ResourceBaseName="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.Localized">
    <Name Resource="BasicCorrectnessRules_Name" />
    <Description Resource="BasicCorrectnessRules_Description" />
  </Localization>
  <Include Path="minimumrecommendedrules.ruleset" Action="Default" />
  <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
    <Rule Id="CA1008" Action="Warn" />
    <Rule Id="CA1013" Action="Warn" />
    <Rule Id="CA1303" Action="Warn" />
    <Rule Id="CA1308" Action="Warn" />
    <Rule Id="CA1806" Action="Warn" />
    <Rule Id="CA1816" Action="Warn" />
    <Rule Id="CA1819" Action="Warn" />
    <Rule Id="CA1820" Action="Warn" />
    <Rule Id="CA1903" Action="Warn" />
    <Rule Id="CA2004" Action="Warn" />
    <Rule Id="CA2006" Action="Warn" />
  </Rules>
</RuleSet>

 

Team Foundation Server Check-In Policy

이 Rule Set 기능은 Team Foundation Server의 Check-In Policy에도 쓰이게 됩니다.

 

맺으며..

이번 Rule Set Feature를 통해서 확실히 이전 버전보다는 Code Analysis를 사용하는 것이 쉬워지고 편리해진 것 같습니다. 하지만, Code Analysis에서 중요한 것은 편의성보다는, Rule의 문제라고 생각됩니다. 그런 면에서 아직 FxCop이 처음 나왔을 때의 200개 정도의 Rule에서 많은 추가가 없다는 것은 굉장히 아쉽습니다. 특히 직접적인 경쟁 제품이라고 볼 수 있는 Compuware의 DevPartner Code Review가 처음 버전부터 600개 이상의 Rule을 가지고 있다는 점에 비교해 본다면 더욱 그렇습니다.

이어지는 포스팅에서는 새롭게 Code Analysis에 추가된 Phoenix 엔진과 그에 따라 다시 복귀한 Data Flow 관련 규칙들에 대해서 한 번 알아보겠습니다.

Visual Studio Team System 2005 에서 코드 분석(Static Code Analysis) 기능이 처음 소개된 바가 있습니다. 이 코드 분석은 Microsoft에서 제안하는 닷넷 프레임워크에서의 디자인 가이드라인과 성능이나 보안, 신뢰성 등의 요소에 대한 Best Practice 등으로 이루어진 200개 이상의 Rule을 기반으로 Code를 검사하고 결함을 발견해 줍니다.

 

원래 이 Code Analysis는 FxCop이란 이름의 독립된 툴로써 세상에 먼저 선을 보인 바 있습니다.

이 FxCop이 Visual Studio 2005 Team System에서 통합되면서 현재의 코드 분석 기능이 나오게 된 것입니다. 실제로 비주얼 스튜디오에서 코드 분석 기능을 담당하는 실행 파일의 이름은 아직도 FxCopCmd.exe입니다.

앞으로 나오게 될 Visual Studio Team System 2010에서는 현재까지 알려진 바로는 다음 세 가지 부분에서 코드 분석의 기능 향상이 이루어 졌습니다. (출처: http://blogs.msdn.com/fxcop/archive/2008/10/30/new-code-analysis-features-in-visual-studio-2010-september-08-ctp.aspx)

  1. Rule Sets – 드디어, 규칙을 프로젝트 별로 하나 하나 빼던 수고스러움을 덜 수 있게 된 것 같습니다. DevPartner Code Review와 같은 상용 툴에서는 진작에 제공되던 기능이었지만, 이제 드디어 Visual Studio 2010에서는 Rule들을 Set으로 만들고 그 Rule Set 기반으로 코드 리뷰를 할 수 있게 되었습니다.
  2. Check-In Policy – 당연한 말이겠지만, 바로 위에서 소개한 Rule Sets 기능이 Team Foundation Server의 Check-In 정책에도 적용할 수 있게 됩니다.
  3. 8개의 새로운 Data-Flow 규칙MSDN Code Gallery의 VS2005와 VS2008 코드 분석 비교 문서를 보시면 아시겠지만, VS2008에서 7개의 규칙이 빠진 바 있습니다. Data-Flow Analysis Engine의 각종 버그와 낮은 성능으로 말미암은 결과라고 하는데, 이번 Visual Studio Team System 2010에서는 Phoenix라는 새로운 분석 엔진의 탑재와 함께 다시 7개의 규칙들이 복귀했고, 새롭게 추가된 하나를 합쳐서 총 8개의 새로운 규칙이 추가되었습니다. 그리고 이번에 추가된 Phoenix 분석 엔진은 당연히 기존 엔진이 가지고 있었던 버그나 성능 문제를 해결한 새롭고 강력한 엔진입니다.

그러면 다음 포스팅을 통해서 이 세 가지 개선점들에 대해서 더 자세히 다뤄보도록 하겠습니다.

안녕하세요. 이번에 Visual Studio Team System 2010 공식 블로그에 새롭게 참여하게 된 LazyDeveloper.Net의 kkongchi라고 합니다. Better Code 시리즈를 통해서 Code Analysis, Unit Test 등에 대한 포스팅을 해보도록 하겠습니다. 부족한 부분 많이 지적해 주시길 바랍니다.

 

TDD?

eXtreme Programming의 창시자 중 하나인 Kent Beck의 eXtreme Programming explained라는 책을 보면 Test를 작성하는 방법에 대해서 이렇게 기술하고 있습니다.

  • If the interface for a method is at all unclear, you write a test before you write the method. (메서드의 인터페이스가 클리어하지 않다면, 메서드를 작성하기 전에 테스트를 먼저 작성해라)

  • If the interface is clear, but you imagine that the implementation will be the least bit complicated, you write a test before you write the method. (메서드의 인터페이스가 클리어하더라도 당신이 생각하기에 구현이 조금 복잡할 것 같다면, 메서드를 작성하기 전에 먼저 테스트를 작성해라)

  • 이런 eXtreme Programming의 Test-Before-Writing 전략을 개발 프로세스에 전면적으로 도입하는 것을 Test Driven Development, 즉 TDD라고 합니다. TDD에 관한 위키피디아 페이지에서 소개하는 TDD의 개발 사이클은 다음과 같습니다. “Red, Green, Refactor”라고 표현하기도 합니다.

    다들 아시다시피, Visual Studio에서는 2005 버전에서부터 Team System의 일부로써 Testing Framework을 제공하고 지원해왔습니다. 그리고 드디어 이번 Visual Studio Team System 2010에서는 완벽하게 TDD의 개념이 Visual Studio Team System안으로 녹아 들어가게 된 것 같습니다. 바로 새롭게 추가된 기능 “Generate” 기능을 통해서, Test를 먼저 작성한 후에 그 Test로부터 코드를 자동으로 Generate해주는 기능이 추가된 것입니다.

     

    TDD Development in VSTS 2010 by “Generate”

    지난 11월에 나온 Visual Studio 2010 and .NET Framework 4.0 Training Kit의 Lab을 통해서 이 기능에 대해서 좀 더 자세히 알아보도록 하겠습니다.

     

    당연히 먼저 테스트를 작성하는 것부터 시작합니다. 하지만, 아직 만들어지지 않은 클래스이기 때문에 아래 그림처럼 빨간색 물결 라인으로 경고가 뜹니다. 여기서 마우스 오른쪽 버튼을 눌러보면, 새로운 “Generate” 기능을 볼 수가 있습니다.

    Generate class를 선택하면 같은 프로젝트에 Class가 추가됩니다. 하지만 Generate other..를 선택하면 아래와 같은 팝업 윈도우가 나옵니다. 클래스를 만들 수 있는 Wizard 개념이라고 보시면 되겠습니다.

    이 Wizard를 통해서 클래스의 Access 한정자, Type, 그리고 파일을 만들 프로젝트까지 설정을 할 수가 있습니다. 이 과정을 통해서 우리는 완벽하게 Test로부터 시작해서 뼈대 코드를 만들어 낼 수가 있습니다. 아래 그림처럼 말이죠..

    이제 이 자동으로 만들어진 뼈대 코드에 구현을 추가하게 되면 여러분들은 다음과 같이 Test를 통과했다는 기분 좋은 화면을 보실 수 있으실 것입니다.


    위에서 보신 Demo Code의 시연은 http://channel9.msdn.com/shows/10-4/10-4-Episode-5-Code-Focused-in-Visual-Studio-2010/#Page=4 에서 Video로도 감상하실 수 있고, http://www.microsoft.com/downloads/details.aspx?FamilyID=752CB725-969B-4732-A383-ED5740F02E93&displaylang=en 에서 Lab Document와 소스 코드도 얻으실 수 있습니다.
     

    지금까지 보신 것처럼 앞으로 출시될 VSTS 2010에서는 IDE 자체에서 완벽한 TDD 지원 기능이 통합되었습니다. TDD가 만능의 도구는 아닙니다. 하지만, 적어도 개발자가 자신의 코드에 대한 이해도가 통상적인 개발 방법보다는 훨씬 크고 깊을 것이라 기대합니다. 어설픈 문서보다는 잘 만들어진 테스트 코드들이 오히려 실제 구현 코드를 이해하는 데 더 도움이 되는 경우도 많습니다. Visual Studio Team System 2010은 효율적인 Test Driven Development를 가능하게 해주는 최고의 도구가 될 것 같습니다.

    부족한 글 읽어주셔서 감사하고, 많은 의견 부탁 드립니다.