NUnit with C#
번역자 : 정상영 2007/12/11 E-Mail: lycobs@gmail.com
What Is NUnit?
NUnit은 모든 .Net 언어를 위한 단위 테스트 프레임워크(unit-testing framework)이다. JUnit(JavaUnit Test)으로부터 파생되었으며, 최신 버전은 2.4이고 MicroSoft .Net을 위해 단위 테스트 툴에 기반을둔XUnit의 다섯번째 메이저 배포판이다. 전체 C#으로 쓰여졌으며, 모든 .Net 언어의 기능의 이점을 살리기 위해 완벽히구성되었다. NUnit은 모든 .Net 언어를 위한 XUnit이라고할 수 있다.
NUnit Quick Start
은행 어플리케이션을 작성하고, Account 도메인 클래스가 있다고 가정한다. Account클래스는 deposit(예금),withdraw(인출) 그리고 transfer(이체) 함수가 있다고 가정한다. Account 클래스는 아마도 이와 같이 구성될것이다.
Account클래스 테스트를 위해 AccountTest 클래스를 작성한다. 처음 테스트할 메소드는 TransferFunds() 이다.
AccountTest 클래스에 대해 첫번째로 알아야 할 것은 [TestFixture] 속성이다. 이 속성은 AccountTest 클래스가 테스트 코드를 포함하고 있다고 알려준다. 이 클래스는 "public" 으로 선언되어야 하며, AccountTest SuperClass에 대해 어떻한 제한도 없어야 한다.
이 클래스의 TransferFunds() 함수는 [Test] 속성을 가진다. 이 속성은 테스트 메소드를 의미한다. 리턴형은 "void" 여야 하며, 파미미터는 없어야 한다. 테스트 메소드에는테스트 객체의 초기화가 필요하고, 테스트할 메소드를 수행하고 그리고 객체의 상태를 확인한다. Assert 클래스는 상태를 체크할수 있는 메소드들이 정의 되어 있고, 위의 예제 샘플에서 AreEqual 메소드는 TransferFunds 메소드를 통해 얻은결과 값이 옳은지 판별한다.
위의 코드를 컴파일 하고 실행하자. 그리고 테스트 코드가 컴파일 되어"bank.dll" 생성되었다고 가정한다. NUnit Gui를 실행하고 Menu->Open 를 선택하여 "bank.dll"파일을 찾아 로드한다. 왼쪽 패널의 TransferFunds 메소드에서 마우스 오른쪽 버튼을 눌러 "Run"을 실행한다. 그러면왼쪽 패널의 테스트 트리에 오류를 나타내는 빨간색 아이콘이 표시된다.
오른쪽 "Error and Failures" 패널에서 다음과 같은 에러 메시지가 출력된다.
Message: TransferFunds : expected <250> but was <150>
그리고 위의 에러 메시지를 클릭하면,
위치: NUnit_QuickStart.AccountTest.TransferFunds() 파일 c:\nunit_quickstart\nunit_quickstart\accounttest.cs:줄 26
위와 같은 메시지가 출력되어 Test가 실패한 라인을 표시한다. "TransferFunds" 메소드는 아직 구현이 되지 않았기 때문에 실패한 것이다.
NUnit GUI 를 닫지 않고, 이전 IDE(VS2003)으로 돌아와서 TransferFunds() 메소드를 아래와 같이 구현한다.
수정한 코드를 재컴파일 하고, NUnit GUI로 가서 "Run"을 실행한다. 그러면, 상태바와 테스트 트리에 성공적인 테스트수행을 나타내는 녹색 아이콘으로 변하는 것을 확인할 수 있을 것이다. Account 클래스의 몇가지의 테스트를 더해보자. 잔액을초과하는 거래를 막기위해 계좌에 최저 잔고금액을 추가해보자.
잔액 초과를 알리기위해 예외처리를 추가하자.
AccountTest 클래스에 다음의 메소드를 추가하자.
위 메소드에 [Test] 속성값외에 [ExpectedException] 속성이 추가되었다. 이 속성은 테스트 코드에서 예외가 발생할 것이라는 것을 의미하며, 실행시간 동안 예외가 발생하지 않느다면 이 테스트는 실패할 것이다.
프로젝트를 재컴파일하고 NUnit GUI에서 "Run"을 실행하면 다음과 같은 에러 메시지를 출력하게 된다.
Message:source.TransferFunds(destination, 100.00F);
Account 클래스 코드로 돌아가 다음과 같이 수정하자.
재컴파일 하고 실행하면 녹색 아이콘이 표시될 것이다. 하지만, 여기서 잠시 코드를 살펴보자. 이 코드대로라면 은행은 실패하는 모든 계좌 이체 거래마다 돈을 잃어 버리게 된다. 왜냐하면, 돈을 받아야 하는 계좌에는 이미 입금 처리를 했는데, 돈을 보내야 하는 계좌에서 출금할 때 예외상황이 발생하여 출금이 되지 않았기 때문이다. 확인을 위해서 다음과 같은 테스트 메소드를 추가하자. !
만약 Withdraw() 메소드에서 또 다른 예외상황이 발생하면 어떻게 될까? 예외상황을 잡아내는 catch 블럭에서 이미 실행된 거래를 상쇄 시키는 또 다른 거래를 실행하거나 객체의 상태를 복구하기 위해서 거래를 감독하는 관리자에게 물어봐야 할 것이다. 이런 부분에서 발생하는 질문들에 대해서 해답이 필요하기는 하지만, 지금 당장은 아닐수도 있다. 그러나 지금 당장 테스트에서 실패하게 될텐데, 어떻게 해야 할까? 이런 부분을 모두 삭제하는 것이 좋을까? 더 좋은 방법은 일시적으로 이 부분을 무시하는 방법이다. 다음과 같이 테스트 메소드에 Ignore 속성을 사용할 수 있다:
프로젝트를 컴파일 하고 실행하면, 노랑색으로 표시될 것이다. "Test Not Run" 텝을 클릭하면 다음과 같은 메시지(이유)가 출력될 것이다.
Reason: Dicide how to implement transaction management
테스트 코드를 보고, 순서에 맞게 리펙토링해야 할 것이다. 그리고 모든 테스트 메소드는 테스트 객체의 공통 부분을 공유 해야 한다. 이 객체들을 SetUp 메소드로 초기화 하고, 이 객체들을 모든 테스트에서 재사용하도록 리팩토링 해 보자. 리팩토링이 모두 끝나고 난 후에 테스트 클래스는 다음과 같다.
Init 메소드는 공통된 초기화 코드를 가지고 있다. 또한 리턴 타입으로 void를 가지고, 매개변수는 없고 [SetUp]이라는속성을 가지고 있다. 다시 컴파일 하고 실행시켜 보자.
History
Last edited on 03/09/2008 15:33 by lycobs
Comments (0)