정말이지, 테스팅 그거 아무나 하는거 아니죠. 특히 저처럼 게으른 놈은 발을 들여놓기가 무서울때도 있습니다.
고객분들은 빠른 결과물을 얻길 원하시고, 그 고객이 여럿이면 모두가 자기의 일이 우선이니 빨리 좀 해달라고 아우성 거릴때가 많습니다. 가뜩이나 개발로도 벅찬 시간인데, 테스트라뇨.. 에잇!
하지만, 그렇게 작업을 한 후 스테이징(Staging Server - 라이브 서버에 반영하기 전 배포하여 테스트하는 서버입니다^^) 에 적용해놓으면 테스트팀에서는 온갖 방법으로(정말 어처구니 없는 입력값으로 마구 공격(?)해 들어오시죠) 테스트를 한 후 결과물들을 전달해주시죠. 그것 예외처리하는 것으로 인해 또한번의 시간이 소비되고 다시 테스트하고 다시 결과물 받고, 계속 반복되는거죠. 그렇게되면, 처음에 빨리 개발했던 시간이 무용지물이 되어버리는 것이죠.

신입시절에(지금도 신입 짬밥이죠;;) 과장님 한 분이, '야, 어떻게 너는 일을 주면 생각없이 컴퓨터로 바로 달려들어 개발하냐?' 라고 한 말씀 해주셨습니다. 먼저 그림을 그려보라고, 이면지 많잖아. 없어? 내가 줄까? 그러시며,  흐름을 생각하며, 어떤식으로 해야할지 먼저 그림을 그리라고요.
테스팅하는 것도 먼저 그림을 그려보는 작업 같습니다. 이렇게 개발을 하면 원하는 결과값이 나오겠지하며, 테스트와 병행하며 원하는 결과값이 맞게 나오는지 확인해가며 개발을 해나가는 거죠.



단위 테스트 프레임워크를 사용해보자


닷넷 프레임워크를 위한 테스트 프레임워크가 많습니다. 다들 아시는 NUnit, xUnit, MbUnit 등이 있죠. 하지만, 저 게으른 것 다들 아실겁니다. 그래서! 비주얼 스튜디오 단위 테스트를 이용하겠습니다. 위 단위 테스트 사이트들 들어가서 다운받고 설치하고, 에휴~^^;

ASP.NET MVC 프로젝트를 생성하게 되면 아래의 화면과 같이 단위 테스트를 할지 여부를 묻는 대화상자가 나옵니다. 예(Yes)를 선택하면, 프로젝트가 생성될때 테스트 프로젝트도 같이 생성하게 됩니다.


테스트 프로젝트에는 Controllers라는 폴더가 있고, 그 안에는 샘플프로젝트의 Home컨트롤러와 Account컨트롤러를 테스트하기 위한 HomeControllerTest.cs와 AccountControllerTest.cs 가 있습니다. HomeControllerTest를 열어보면 다음과 같습니다.


Microsoft.VisualStudio.TestTools.UnitTesting 네임스페이스가 임포트 되어 있는 것이 보이고, [TestClass], [TestMethod] 가 눈에 띄네요. 주석을 보니,

TestClass : 테스트 메서드가 포함된 클래스를 식별하는데 사용됩니다.
TestMethod : 테스트 메서드를 식별하는데 사용됩니다.

이렇다네요.^^



테스트와 함께 하시겠습니까?


다음은 TelDirController 소스입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace UsingTest.Controllers
{
    public class TelDirController : Controller
    {
        //
        // GET: /TelDir/

        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /TelDir/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }       
    }
}

아무것도 처리하지 않은 깨끗한(?) 소스입니다. Index(), Details() 라는 두 액션메쏘드가 있고, 두 메쏘드 모두 View를 리턴하고 있습니다.

그럼, TelDirController를 위한 테스트를 생성해보겠습니다.



테스트 만들기


테스트 프로젝트의 Controllers를 오른쪽 버튼으로 클릭한 후 추가 -> 새 테스트를 선택합니다.


테스트하려는 컨트롤러 이름 뒤에 Test 만 붙여서 이름을 만들겠습니다. TelDirControllerTest 처럼요.^^;


확인 버튼을 클릭하면 다음의 소스가 보이실겁니다^^


지금으로선 불필요한 것들을 모두 닫아놓긴 했는데요, 물론 삭제하셔도 됩니다. 이런 것도 싫다 하시면, Controllers 폴더에서 클래스를 생성한 후 TestClass와 TestMethod 속성, 그리고 UnitTesting 네임스페이스를 임포트시키시면 됩니다.



맛보기 테스트


정말 맛만 보여드리겠습니다.^^;

TelDirController.Details 메쏘드가 정말 "Details" 뷰를 리턴하는지 테스트 해보도록 하겠습니다.
먼저 테스트 메쏘드를 만들어보겠습니다.

[TestMethod]
public void DetailsTest()
{
    var controller = new TelDirController();
    var result = controller.Details(1) as ViewResult;
    Assert.AreEqual("Details", result.ViewName);
}

Assert.AreEqual 은 비교대상의 두 값이 같은지 여부를 나타냅니다. 같으면 성공, 다르면 실패.
ViewResult.ViewName은 컨트롤러에서 리턴받은 뷰명을 나타냅니다.
자~ 테스트를 진행해볼까요?


'솔루션의 모든 테스트 실행' 버튼을 클릭합니다. 단축키는 Ctrl+R,A 라고 친절히 알려주네요^^ 물론 지금은 테스트 케이스가 하나라 이렇게 하지만 모든 테스트 실행 좌측에 있는 버튼인 '현재 컨텍스트의 테스트 실행'은 현재 선택받은 곳, 즉 커서가 위치한 곳의 테스트를 진행합니다.


엥?! 실패하였습니다. 예상 값이 Details 인데 실제값은.. 실제값은.. 없네요;;

TelDirController의 Details 메쏘드를 살펴보죠.

public ActionResult Details(int id)
{
    return View();
}

이렇게 되어 있네요. 잘못된 것은 없어보이는데요. 

Details 뷰를 리턴하려면 두 가지 방법이 있습니다. 위처럼 Details 액션 메쏘드에서 return View() 를 하는 방법(이것은 액션 메쏘드의 이름에서 유추가 됩니다), 다른 하나는 명시적으로 return View("Details") 와 같은 방법입니다.

그럼, 또다른 방법을 택해서 테스트를 돌려보죠.

public ActionResult Details(int id)
{
    return View("Details");
}

결과는


통과~.
이래서, 아~ 테스트시에는 뭐든지 확실하게 명시적으로 표현해줘야하는구나~ 라는 것을 알 수 있습니다.^^



마무리요



이번 포스팅은 간단하게 테스트하는 방법에 대해서 알아봤는데요, 다음은 이 테스팅에 대해서 좀더 자세하게 알아보는 시간을 가져보겠습니다.

맛이 어떠셨나요? 다음에는 더 화끈한 맛을 보여드리도록 하겠습니다^^



참고자료 : http://www.asp.net/mvc/tutorials/creating-unit-tests-for-asp-net-mvc-applications-cs