TDD : NUnit, MbUnit 그리고 xUnit CSharp

Unit Test를 하기 위해 기본적으로 사용하는 Test Framework은 NUnit과 MbUnit입니다.
새로운 TDD의 방법론으로 xUnit이 떠오르고는 있지만, 아직 사용해보지는 않았습니다.

VS.NET에서야 당연히 TestDriven.NET 이라는 툴을 사용하구요.
Mocking 테스트 시에는 Rhino Mock을 자주 사용합니다. Moq는 테스트를 해 봤긴했는데... 어쨌든...

제가 처음에는  NUnit 2.2 버전을 사용하다가, MbUnit 2.4.2.355 의 다음 기능 때문에 넘어 오게 되었습니다.
(현재 NUnit 2.5 (2.5.0.9122) 은 더 많은 기능이 추가되었습니다만, Attribute name 차이가 있습니다.)

1. Unit Test용 class를 상속해도 잘된다.
2. MultiThread Test를 지원한다.
3. 다양한 인자 값을 이용하여, 테스트가 가능하다.
4. 다국어지원 (Localization) 에 대한 테스트가 가능하다.

1. Unit Test class의 상속

public abstract class AbstractTestFixture
{
[TestFixtureSetUp]
public virtual void ClassSetUp() { IoC.Initialize(); } 

[TestFixtureTearDown]
public virtual void ClassCleanUp() { IoC.Reset(); }
}

[TestFixture]
public class DrivedTestFixture : AbstractTestFixture
{
[Test]
public void Run() { ... }
}

[TestFixture]
public class DrivedDrivedTestFixture : DrivedTestFixture
{
[Test]
public void RunDrived() { ... }
}

  이렇게 상속을 해도 abstract class가 TestFixture가 아니더라도 TestFixtureSetup, TextFixtureTeardown에 해당하는 함수를 서브클래스를 테스트 할 때, 수행시켜줍니다.


2. MultiThread Test를 지원한다.

// Run 함수를 한번만 수행한다.
[Test]
public void Run() { ... }
// MbUnit 이 5개의 Thread를 만들어, Run 메소드를 실행한다.
[Test]
[ThreadedRepeat(5)]
public void Run() { ... }

   이 기능은 Multi-thread 환경에서 안정된 기능을 구현했는지 검사하는 데, 많은 도움을 줍니다. 일반적인 Unit Test 프로그램에서 지원하지 않아, Thread Test용 Utility class를 따로 만들어서 테스트하곤 했는데, 이 기능을 이용하게 많은 thread-safe 를 요구하는 class 테스트시에 유용하게 썼습니다.


3. 다양한 인자 값을 이용하여, 테스트가 가능하다.

  보통 테스트 함수는 인자가 없는 procedure입니다. 위의 Run함수처럼요... 하지만, 특정 입력값에 따른 다른 형태를 분석하기 위해서는 테스트용 seed data를 이용해야 합니다. 결국 테스트 함수 내에서 seed 값을 지정해서 사용하게 구현해야 하죠...
MbUnit은 다음과 같이 seed 값을 제공하는 attribute 를 지정할 수 있습니다.

[RowTest]
[Row(10, "admin")]
[Row(100, "guest")]
[Row(1000, "user")]
public void Run(int count, string username) 
{
//
}

  MbUnit은 위의 테스트 함수를 3번 호출하면서, 각각 함수 인자에 지정된 값을 대입해서 테스트를 수행합니다. 경계값이나, 인자에 따라 테스트를 하고자 할 때 유용하게 사용할 수 있습니다.

4. 다국어지원 (Localization) 에 대한 테스트가 가능하다.

   별로 사용되지는 않지만 다국어지원을 테스트하기 위해서, Current Culture를 변경해가면 테스트를 수행했는데, 다음과 같이 사용하게 되면 다국어에 대한 테스트도 가능하게 됩니다.

    
[Test]
[MultipleCulture("en-US", "ko-KR", "de-DE")]
public void Run() { ... }

  당연히 Current Thread의 Culture 정보를 지정된 culture 로 지정한 후 테스트 함수를 수행합니다.
    
MbUnit의 또 다른 장점은 결과를 console에 뿌리지 않고, xml, html 파일로 제공합니다. (너무 많은 테스트를 하게 되면 html 생성 시 시간이 많이 걸립니다) 보통 로그 정보가 찍히고, 테스트 실패에 대해서는 console, 파일 모두에 찍히므로 NUnit처럼 모두 console에 찍히는 것보다 결과에만 집중할 수 있어 좋습니다.

단! 테스트 결과가 많은 경우, IE로 열지 마십시요. 구글 크롬이 테스트 결과 파일 로딩 속도도 빠르고, 보기에도 좋습니다. 
IE는 로딩도 느리고, script관련 보안때문에 번거롭습니다.

다음번에는 최신 NUnit 2.5가 MbUnit보다 더 좋은 점에 대해서 글을 써 보겠습니다.