지난 번 글에서 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 공식 블로그에 새롭게 참여하게 된 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를 가능하게 해주는 최고의 도구가 될 것 같습니다.

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

    신고