using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace Registry_Handle
{
    class Program
    {
        static void Main(string[] args)
        {
            string regSubKey = "Software\\myTestKey";

            RegistryKey rk = Registry.LocalMachine.OpenSubKey(regSubKey, true);

            if (rk == null)
            {
                rk = Registry.LocalMachine.CreateSubKey(regSubKey);
                
            }
            
            string[] strData = new string[] { "aaa", "bbb", "ccc" };    
            rk.SetValue("asdfqwer", strData);
            string[] regStr = rk.GetValue("asdfqwer") as string[];

            Console.WriteLine(regStr[1]);
            Console.ReadLine();

            Registry.LocalMachine.DeleteSubKey(regSubKey);
        }
    }
}
Posted by lI헐헐Il
,

TDD로 개발하기

IT/IT 일반 2012. 6. 13. 11:11

출처 : http://chidoo74.blog.me/10111485824

TDD를 배운다고 배웠는데 이제 간신히 기본기를 땐 것 같다.

처음에는 사람한테 배우고 다음부터는 책에서 배우고… 시작을 좀 아는 사람한테 배우다보니까 개념에 대한 이해는 좀 빨랐는데 너무 수박겉할기 식으로 했던 것 같다. 책을 보고 사람한테 배웠던 걸 다시 한번 되새김해보니 개발이라는 걸 새로운 관점으로 볼 수 있는 기회가 만들어졌다.

특히 자바를 기본으로 하는 객체 지향 개발에서는 나름 한다고 생각을 했었는데 헛멋만 잔뜩 든 별볼일 없는 재주라는걸 깨치게 한다. ㅎㅎ 사람이라는게 정말...

TDD를 공부하면서 이제 개발의 기본이라는 것으로 알것 같다. 그런 기분을 들게 만드는건 역시 이름에도 나와있는 테스트(Test)다.

예전에 좀 개발을 할 줄 아는 친구에게 TDD를 이야기했는데 "거 뭐 JUnit 가지고 테스트만 만들면 되는거 아닌가요?" 라는 대답을 들었다. 뭐 대답이 아주 틀린 대답은 아니다. 자바 개발자가 하는 대부분을 JUnit을 알고 있거나 것도 아니면 들어는 봤을테니까 말이다. 하지만 그것만으로 테스트를 쌩~ 무시하기에는 너무 만만하게 보는 것 같았다.


그래서 TDD의 진면목을 한번 이야기해볼까 한다. 뭐가 나를 반성하게 했고 어떤 점에서 개발자라는 사람들이 이득을 얻을 수 있는지. 그래서 나에게 그런 말을 했던 좀하는 친구가 어떻게 하면 정말 좋은 개발자가 될 수 있는 길을 갈 수 있는지를 이야기해주고 싶다. (너무 과욕인가?? ㅎㅎ)

앞서 이야기한 친구는 "JUnit = TDD" 라고 이야기를 했지만 JUnit은 TDD를 하기 위한 한 도구일 뿐이지 그 자체는 아니다. 것보다는 테스트라는 것에 그 핵심이 있다. 생각해봐라. 테스트를 할 수 있는 방법이 한 두갠가??? 꼴랑 JUnit 하나로 테스트를 치부해버리면 TDD라는 이름이 너무 허방한 것 같지 않나...

TDD는 테스트를 하자라는 것과 테스트를 자동으로 하자라는 것에 초점이 있다. 즉 사람이 개입하지 않고 테스트를 돌릴 수 있어야 하고 또 자동화 방법을 써서 주기적으로 또한 원할 때 즉시 테스트를 수행할 수 있어야 한다. 꼭 JUnit이 아니더라도 테스트를 사람이 개입하지 않고 돌릴 수 있는 체계를 개발자들이 활용한다면 일종의 TDD를 한다고 이야기할 수 있다. 간단히 정리하면 아래의 말 정도로 정리되지 않을까 싶다.


TDD = 자동화된 테스트를 통해 작성된 코드로 작성된 로직이 정상적으로 동작한다라는 것을 검증하면서 진행하는 개발 방법론


이런 관점에서 본다고 하면 JUnit은 TDD를 수행하기 위한 괜찮은 도구이고, 또 찾아보면 JUnit을 지원하기 위한 괜찮은 Third Party Library들이 많이 존재한다. 이것들을 잘 활용하는 개발자라고 하면 나름 TDD틱한 개발 모델을 가지고 있을 것도 같다.


다시 본론으로 돌아가서 테스트를 하는 목적/이유에 대해서는 누구나 다 동감을 할 것이다. 아마도 다음의 두가지 정도 목적이 주된 이유일 것이다.

  • 돌아갈 코드가 잘 돌아갈지를 확인하기 위해서. 코드를 작성했으면, 그 코드가 과연 돌아갈지 문제는 없는지 확인해야 한다. (뭐 간혹 모든 절차를 뛰어넘는 과감한 개발자들이 있긴 하지만...)
  • 문제가 있다는 이야기를 들었을 때 실제로 그 문제가 존재하는지 확인하기 위해서. 만들어준 프로그램을 쓰는 사람들이 투털이가 아닌 이상에는 뭔가 문제가 있다라는 것이고 그 문제가 뭔지를 파악할려면 결국에는 테스트를 해봐야 한다.


뭔 이유가 되었던 테스트는 필요하다. 그래서 개발자들은 돌아가는 혹은 돌아갈 것 같은 코드를 작성한 다음에 그 코드가 잘 돌아가는지를 테스트한다. 테스트를 해본다는 것은 적어도 자신의 코드가 의도한 바를 달성하는지를 검증한다는 행위다. 그리고 이렇게 테스트하는 개발자라면 상식(?)을 갖고 있는 개발자로써 훌륭한 자질을 갖췄다. ㅎㅎ 그런데 이게 최선이고 확실한 걸까???




그럼 이런 식의 개발과 TDD식의 개발의 차이점이 뭔지를 알아보자.


TDD 방식의 개발에서는 테스트를 먼저 작성(중요하다.. 밑줄 쫙~)하라고 강권한다. 왜 테스트를 강권하지??? 이유는 간단하다. 테스트를 통해서 자신이 만들 것이 뭔짓을 하는지를 먼저 코드로 생각하고 코드로 정의하라는 것이다.


만들어진 걸 테스트하는 경우를 포함해서 모든 테스트는 테스트 대상이 있다. 그 대상은 뭔가를 입력으로 받아서 의도한 동작을 수행하고 뭔가를 출력 혹은 결과물로 내놓는다. 따라서 테스트를 코드로 작성하게 되면 우리는 대상에 대해서 다음의 것들을 명백하게 드러낼 수 있다. (혹은 대상이 이걸 알아서 드러낸다.)

  • "뭘 입력으로 줘야 동작을 한다." 간단한 1,2,3의 숫자도 될 수 있고 혹은 특정 객체 자체가 입력으로 주어질 수도 있다. 것도 아니면 환경 변수라도 그 입력 가운데 하나가 될 수 있다. 대상을 동작시키는데 필요한 것들이 뭔지를 알 수 있게 된다.
  • "제대로 돌았을 때 어떤 결과를 얻을 수 있다." 결과는 함수의 응답이 될 수도 있고 테스트 대상 객체의 상태가 결과물이 될 수도 있다. 뭐라도 테스트가 실행되면 우리의 의도와 실제 결과가 일치해야 한다.


그렇기 때문에 테스트를 먼저 작성하게 되면 환경에 대한 이해와 명확하게 뭘 해야하는지를 또릿또릿하게 알 수 있다. 또릿또릿하게 알 수 있다라는 사실은 다음의 점에서 개발자에게 이점을 제공한다.

  • 도달해야 하는 명제가 명확하고 그게 코드로 기술되어 있기 때문에 헛방 날릴 확률이 적어진다. (소위 말해 뻘짓할 가능성이 적어진다.)
  • 상상의 나래를 펴 동작에 하등 영향을 주지 않는 코드를 작성하는 헛힘 쓸 기회를 안준다.
  • 코드라는 명확한 명세를 가지고 이야기를 하기 때문에 요구 사항을 낸 사람과의 대화가 수월해진다. (애매한 몇 줄짜리 요구 사항 정의서보다는 결과가 명확한 읽을 수 있는 코드가 개발자가 이해하기에 좋고 고객과 이야기하기에도 좋다.)
  • 코드로 작성된 테스트가 있기 때문에 작업 중간 중간에 제대로 하고 있는게 맞는건지 바로 바로 확인해볼 수 있다.


이제 테스트를 먼저 작성하고 진행했을 때 얻는 이점이 개발을 마친 다음에 테스트를 작성하는 것보다는 훨씬 더 이점이 많다는 걸 누구라도 이해했을 것이다. 음... 근데 테스트를 어떻게 작성하지? 어떤 방식으로 작성하지? 이런 질문이 생각날 것 같다. (안나나... ㅎ)


TDD는 Test Driven Development 라고 하는데 무작정 테스트를 작성하는 것 보다는 좀 더 체계적인 방법이 있을 것 같다고 생각할 것 같다.


만약 그런 생각을 가지고 있다면 버리는게 좋다. TDD 책이 많이 나와있긴 하지만 그책 어디를 봐도 그런 체계적인 방법론에 대한 설명보다는 예제만 잔뜩 적어놓고 이게 TDD예요... 라고 이야기하는 걸 봤을 것이다. 맞다. TDD는 책 몇백 페이지를 채울만한 그런 이론은 없다. 그냥 "테스트 먼저 코드로 작성하시고 프로그램 짜세요..." 라고 최고의 이론일 것 같다.


그렇지만 뭔가 있을 것 같은데... 그래서 함 책에서 배운 내용 가지고 정리해봤다.




TDD 이렇게 함 해보세요.

테스트를 통해서 개발을 진행할려고 할 때 테스트를 적용하는 단계라는 것을 이야기한다. 당연한 것이 우리가 만들 프로그램도 덩어리가 있는 놈이고 따라서 그 덩어리를 채울 요구 받은 기능들이 있기 때문에 마찬가지로 테스트도 적용하는 절차가 있다.


절차가 복잡하냐고? 네버!!! 간단히 말하면 테스트는 "인수 테스트(AT - Acceptance Test)"와 "기능/단위 테스트(Unit Test)"로만 구분하면 된다.

  • 인수 테스트(Acceptance Test) - 인수 테스트는 고객에게 인수 시험을 받는 거랑 비슷하다고 보면 된다. 고객이 인수 시험을 받을 때 for loop이 어쩌고 이 객체가 이상하게 생겼고를 묻지 않는다. 고객이 원하는 건 자신이 원하는 기능(Functional Requirement)가 제대로 동작하는지가 궁금하지 그 디테일에 대해서는 전혀~ 궁금하지 않다. 따라서 TDD에서의 인수 테스트는 도출된 고객 관점의 기능을 테스트할 수 있는 코드로 작성한다. 인수 테스트를 작성했다는 이야기는 당신이 그 기능을 수행할 테스트 대상, 즉 실제 구현 모듈을 정의(입력과 출력)했다라는 것을 의미한다. 따라서 이제부터 본격적으로 개발을 진행하면 된다.


 

  • 기능/단위 테스트(Unit Test) - 인수 테스트를 작성한 다음에 실제 돌아가는 기능 코드를 작성하다보면 라인이 길어지게 된다. 그러면 그걸 클래스로 뽑기도 하고 함수로 뽑기도 한다. 근데 그게 제대로 돌아가는지 보장할 수 있나?? 재수 좋아서 인수 테스트가 통과되는거라는 불안감이 들지 않나??? 이런 불안감이 들때가 바로 단위 테스트를 작성할 때이다. (아,,, 물론 불안감이 없다면 작성 안해도 된다. -_-;;;) 단위 테스트는 Requirement를 만족시키기 위해 동원된 단위 객체 혹은 함수가 정상적으로 동작하는지 테스트하기 위해 작성한다. 따라서 단위 테스트의 목적은 그 단위 테스트에 집중되면 되고 그 이상을 고려할 필요가 없다.

위에서 설명한 것에서 알 수 있겠지만 단위 테스트는 인수 테스트에 대해서 종속적이다. 앞서 이야기했던 친구의 경험으로 "JUnit = TDD"라는 것은 것은 아마도 단위 테스트의 경험으로 이런 이야기를 했을지도 모르겠다.


하지만 우리가 좀 더 관심을 기울여야 하는 테스트는 단위 테스트가 아니라 인수 테스트라는 것을 명심해야 한다. 인수 테스트를 통해서 구현할 기능을 우리(개발자들) 스스로가 명확히 해야한다. 스스로가 로직의 흐름을 명확하게 해야할 시점에 단위 테스트를 통해 자신의 확신을 확인한다.




Test Driven Development? - 정말 가능한가?

TDD를 보통 개발 방법론이라고 이야기를 한다. 특히 요즘 나오는 RFP를 보면 참 얼토당토않게 개발 방법론은 TDD로 해주세요… 라고 쓰여있었던 경우가 종종 있었던 것 같다. (음.. 이건 1년 전쯤의 기억이니 너무 확신하지 말길.. 근데 유행이…) "개발 방법론" 이라고 이야기를 했을 때 많이 듣던 방법론은 "폭포수" 아니면 "회전형(Spiral)" 정도였을 것 같은데 왜 이런 방법론 이야기를 할까??


아마도 그 배후에는 에자일(Agile) 혹은 XP라는 극단주의자들이 도사리고 있는게 아닐까 싶다. 그네들이 이야기하는 건 "다 때려치고 고객이 최고고 고객에게 보여줄 수 있는 프로그램을 만드는 것이 프로젝트의 성공 지름길"이라는 고객 지상주의를 펼치고 있는 사람들이니까 말이다.


이 말과 앞서서 이야기했던 TDD의 테스트들과 뭔 상관이 있지?? 눈치 빠른 사람들은 알겠지만 TDD를 함에 있어서 최상위의 테스트는 바로 Acceptance Test, 즉 고객이 요구하는 기능을 가지고 테스트를 하는 것이다. 즉 이 기능을 만들면 고객이 원하는 기능을 보여줄 수 있다라는 것이다 오 마이 갓. 정말 TDD랑 에자일(XP)는 그놈이 그놈이다라는 거다. Ok. 맞다. 이 말은 정말 사실이다. ㅎㅎ


에자일 방법론(혹은 XP 방법론)과 TDD는 차이는 사상과 실행 방법이라고 나름 결론을 내고 싶다. 따라서 두 개발 방법론이 추구하는 이상향은 동일하다.


즉 사용자와 소통하고 그걸 빠르게 전달해서 정말 사용자에게 도움이 되는 프로그램을 만든다. 그리고 실제로 사용해보면서 점진적으로 발전해 나가겠다라는 것에 둘의 초점이 모아진다. 와우~~~ 정치적인 것에 얽매여 씨잘데기 없는 걸 요구하고 구현하는 것이 아니라 실체로써 존재하는 프로그램을 가지고서 이야기를 할 수 있는 자리를 만들어주는 두 방법론이 정말 이뻐 보인다. (ㅎㅎ 술한잔 한 사람의 말투... -_-;; 사실 한잔하고 썼다.)


TDD 개발 방법론은 요구 사항(Feature)를 Black Box로 놓고 이걸 점차 White Box로 만들어가는 과정을 통해 실행된다. 최초의 Feature를 실제 테스트 코드로 옮겨야 하기 때문에 이 작업을 수행하기 위한 자질을 개발자가 갖추고 있어야 한다. 이때 필요한 자질이라고 하면 아래와 같은 것들이 필요하다.

  • 고객과 Communication 할 수 있는 Domain knowledge
  • 다루는 언어 및 플랫폼에 대한 충분한 이해


일단 이런 지식을 바탕으로 고객이 원하는 기능을 테스트로 작성했다고 하면 이제부터 화이트박스 작업을 진행한다. 화이트 박스는 실제로 해당 기능이 로직을 타고 동작하는 실체를 구현하는 작업이다. 이 단계에서는 고객의 Feature를 실제 기능적인 구분하고, 각 기능에 대한 단위 테스트를 구현한다. 이 단계를 진행할 때 다음의 자질이 개발자에게 요구된다.


  • 역할과 책임(R&R: Role and Responsibility)에 따른 객체 지향적 디자인 방법
  • 객체 지향에 따른 올바른 OOP(그냥 Java) Programming 방법
  • 배려심을 갖춘 올바른 표준 Coding Style


이 단계는 실제로 테스트를 작성하고 그리고 실제 로직을 작성한 다음에 그 단위를 완성해나가는 단계이다. 이 과정에서 특히 필요한 건 각 로직 단위를 얼마나 테스트를 쉽게 할 수 있는 융통성을 발휘하도록 정의할 것이냐라는 것이다. 이에 따라서 각각의 단위(객체)들은 자신이 가지는 역할(Role)과 책임(Responsibility)에 따라 정의되어야 한다.

뭐 말은 쉽다고 이야기할 사람들이 다분할 것 같지만... 맞다. 말만 쉽게 했다.

실제로 이걸 이렇게 할려면 Java 언어와 기반 플랫폼(Tomcat, Spring 등등)에 대한 해박한 지식이 사전에 있어야 한다. 또한 객체 지향의 일반적인 패턴(Patterns from GoF)들에 대해서도 나름 일가견이 있어야 한다. 그래야 프로그램을 개발새발 작성하는게 아니라, 테스트를 기반으로 적절한 역할과 책임을 가진 객체들을 뽑아낼 수 있게 된다. (즉 무작정 개발하는게 아니라 공부가 필요하다.)

때문에 제대로 TDD를 구사해서 개발 모델을 이끌어가기 위해서는 그만큼의 이론적인 배경과 명확한 개발의 논리를 갖추고 있어야 한다. 하지만 그렇게 쫄 필요는 없다. 코드에 대해 끊임없이 R&R 이라는 관점을 가지고 탐구를 하다보면 자연스럽게 위에서 장황하게 설명하게 된 것들을 본인이 갖춰나가게 될 것이다. 다만 시간이 좀 더 걸릴 뿐이지만. 이 과정을 간단히 그림으로 살펴보면 아래와 같이 정리할 수 있다.

[엑박] ^^ㅋ


프로젝트가 끝나면 개발이 끝난걸까?

이렇게 생각하는 사람들이 많을 것 같다. 하지만 프로젝트가 끝난 이후에도 개발은 계속~ 죽~ 이어진다. 뭐로? 바로 위 그림에서 나온 Refactoring 이라는 과정을 거쳐야 한다.


Refactoring 과정은 말대로 정제라고 표현할 수 있다. 자신이 작성한 코드를 정제해서 지속적으로 관리 가능한 코드로 유지해야 한다.


또한 TDD로 한다고 해서 버그없는 소프트웨어를 만들 수 있는 건 아니다. 버그는 항상 존재하며, 이 버그가 출현했을 때 마찬가지로 이를 테스트 코드로써 재현해야 한다. 코드로써 재현이 가능한 버그는 해결된 것이나 마찬가며 이걸 위의 그림과 같은 프로세스를 거쳐서 한번 실수가 재발되지 않도록 유지 관리해야한다.


개인적인 관점은 Refactoring과 유지 관리를 통해 최적화되는 코드를 통해서 보다 많은 개발 모델과 어플리케이션 설계에 대한 더 많은 지식을 얻을 수 있을 것으로 보고 있다.




한마디의 첨언...

절대적으로 결과에 조급함을 가지는 사람이라면 TDD를 달성하기 힘든다. 테스트를 작성하는 시간보다 코딩을 하는 시간에 마음이 앞선다면 절대로 성공못할 개발을 끌어가는 프로세스가 TDD이다. 그만큼 끈기를 가지고 명확한 관점을 유지하는 마음의 자세를 개발자가 가질 필요가 있다.

Posted by lI헐헐Il
,

소프트웨어 프로젝트에서는 많은 종류의 테스트를 수행할 수 있고 또 수행해야 한다.
이 테스트 중 일부는 최종 사용자가 광범위하게 개입해야 하고, 또 일부는 전담 QA 팀이나 또 다른 값비싼 자원들이 필요할 수도 있다. 그러나 TDD는 이런 테스트가 아니다.
프로젝트와 개인의 성공에서 필수적인 부분인 '단위 테스트'에 대해 이야기 하는 것이다.
단위 테스트는 더 나은 코드를 더 빨리 만들어 낼 수 있으며, 상대적으로 더 쉽고 비용이 적게 드는 방식이다.
많은 기업은 테스트에 관심이 무척 많지만, 프로젝트가 끝날 때에만 테스트를 하려는 경향이 있다. 그리고 정작 그때에 가서는 일정 압박 탓에 테스트 과정을 축소하거나 완전히 생략하기도 한다.
프로그래머는 테스트를 '직접 코드를 만들어 내는' 당장의 진짜 일에 집중하지 못하게 하는, 그저 귀찮고 성가신 일일 뿐이라고 생각한다.
단위 테스트는 기업의 품질 경쟁력만을 위한 것이 아니다. 최종 사용자나 경영진, 팀장들을 위한 것도 아니다.
프로그래머에 의해, 프로그래머를 위해 행해지는 것이다. 오직 우리의 이득을 위해, 우리의 삶을 더 편하게 만들기 위해 존재하는 것이다.

단위 테스트만으로도 성공과 실패가 갈릴 수 있다.

1. 확신을 갖고 코딩하기

1)A개발자
코드를 아주 빠르게 만들어 냈다. 그리고 종종 멈춰서 코드가 제대로 컴파일 되는지 확인했다.
하지만 최상위 프로그램을 실행하자 문제가 생겼다. 디버거를 써서 단계적으로 실행해 볼 시점이다. 코드를 거슬러 올라가며 잡기 어려운 이 문제가 생기기까지 과정을 되짚어 본다.
문제의 버그를 찾고 수정을 했지만 그 과정에서 버그가 몇개 더 생겼다. 어느덧 밤이 깊어졌다.

2)B개발자
도저히 빠르다고 할 수 없는 속도로 코드를 작성하였다. 새 루틴과 함께 짧은 테스트를 작성한다. 그리 대단한 것도 아니고, 단지 원래 의도대로 수행되는지 확인을 하기 위한 간단한 테스트 이다.
테스트를 생각하고 작성하기까지 시간이 약간 더 필요했지만, 새 루틴 자체를 검증할 수 있기 전까지는 더 진행해 나가지 않았다.

A, B개발자는 지적 능력이나 경력이 동일하다. 하지만 개발 방식이 다르다.

2. 단위 테스트란?

'단위 테스트'는 테스트 대상이 되는 코드 기능의 아주 작은 특정 영역을 실행해 보는, 개발자가 작성한 코드 조각이다.
대개 단위 테스트는 특정 상황에서 특정 메서드를 실험해 본다. 이는 어떤 코드 조각이 개발자가 생각한 대로 동작하는지 증명하기 위해 수행하는 것이다.
그 동작이 고객이나 최종 사용자가 바라는 것인지 아닌지는 해결되지 않은 채로 남는다. 이 부분은 인수 테스트의 목표이다. 아직은 공식적인 유효성 검증과 확인이나 정확성에 크게 신경쓰지 않는다.
이 시점에서는 성능 테스트에 조차 관심을 두지 않는다.
단지 코드가 의도대로 동작하는지 확인하는 것이고, 따라서 코드의 기능 중에 아주 작고 고립된 부분만 테스트하기를 원한다.
개개의 부분들이 생각한 대로 동작한다는 확신을 쌓아 나감으로써, 비로서 그것들을 조립하여 전체 동작 시스템을 테스트하는 단계로 나아갈 수 있다.

3. 왜 귀찮게 단위 테스트를 하지?

■ 삶을 편하게 해준다.
■ 설계를 좀 더 좋게 만들어 주고, 디버깅에 낭비하던 시간을 극적으로 줄여 준다.

A개발자의 경우 낮은 레벨의 코드가 제대로 동작한다고 가정하고 좀 더 높은 레벨의 코드에서 그것을 사용하였다.
하지만 낮은 레벨의 코드를 신뢰할 수 없다면 그 낮은 레벨의 코드만 고친다 해서 문제가 해결되지 않는다. 낮은 레벨의 문제를 고쳐도 그 영향은 더 높은 레벨의 코드에 미치고 이젠 그 코드도 고쳐야 하는, 그런 일이 계속 이어진다.
수정에 의한 영향은 전체 코드로 바이러스 처럼 퍼져 나간다.

B개발자의 경우 코드에 대한 확신을 얻기 위해서 코드에게 무슨 일을 하고 있는지 물어봐야 했고 그 결과가 기대한 바와 같은지 확인해 가며 프로그램을 완성해 갔다.
이 간단한 개념이 좀 더 나은 코딩을 위한 가장 확실하고 가장 효과적인 기법인 단위 테스트의 핵심이다.

4. 무엇을 이루길 원하는가?

자신의 삶을 그리고 동료들의 삶을 더 편하게 만들기 위해 단위 테스트를 한다.

1) 내가 원하는 일을 하는가?
"이 코드가 내 의도를 충족시키는가?"
자신이 생각한 그대로 코드가 동작한다는 것이 증명되기를 바란다.

2) 언제나 내가 원하는 일을 하는가?
자기가 테스트를 한다고 주장하는 많은 개발자는 줄곧 테스트 하나만 작성한다. 이런 것은 전체 코드에서 모든 것이 완벽하게 돌아가는 '올바른 한 길'만을 택한 반쪽짜리 테스트다.
하지만 당연하게도 항상 완벽하게 진행된다는 보장은 없다. 예외는 발생하고, 디스크는 꽉 차고, 네트워크는 끊어지고, 버퍼는 오버플로우되고, 그리고 버그를 만든다.
정해진 최상의 가정으로만 테스트 한다면 단편적인 경우만 검증될 수 있다. 코드가 어떤 여러가지 상황에서도 항상 내가 원하는 대로 움직이는 것을 확인해야 한다.

3) 의존할 수 있는가?
의존할 수 없는 코드는 쓸모가 없다. 설상가상으로 의존할 수 있다고 갱각되는 코드는 버그를 찾아내고 디버깅하는데 아주 많은 시간이 들 수 있다.
완벽하게 코드를 작성하는 사람은 없다. 그래도 괜찮다. 문제가 어디에 있는지 알기만 한다면 말이다.
우리가 작성한 코드에 의존할 수 있고 그 코드의 능력과 한계를 정확히 알 수 있으면 된다.

4) 의도를 문서화하고 있는가?
단위 테스트의 멋진 부대 효과중 하나는 의도한 코드의 사용법을 전달할 수 있게 해준다는 것이다. 실제로 단위 테스트는 개발자가 다양한 조건하에서 어떻게 코드가 동작할 것을 기대했는지 보여주는, 실행 가능한 문서화 역할을 한다.
팀원들은 테스트를 보고 코드를 사용하는 방법을 알 수 있다. 만약 누군가가 고려하지 못했던 테스트 케이스에 맞닥뜨리면 그 사실을 빨리 팀원들에게 경고할 것이다.
그리고 당연하게도, 실행 가능한 문서란 것은 정확한 상태의 유지라는 이점이 있다.

5. 단위 테스트를 어떻게 해야 하는가?

① 코딩전 문제가 되는 메서드를 테스트할 방법을 결정.
② 단위 테스트 실행.
③ 단위 테스트를 통한 통합 테스트 실행.(모든 테스트를 통과 시키기)

6. 테스트를 하지 않는 사람들의 변명

■ 테스트 작성까지 시간이 너무 많이 걸린다.(단위 테스트에 입문한 대부분의 불평 1위)
- 코드를 디버깅하는데 얼마나 시간을 쓰는가?
- 제대로 동작한다고 생각했지만 중대하고 심각한 버그가 드러난 코드를 다시 뜯어고치는데 얼마나 시간을 쓰는가?
- 드러난 버그가 발생한 위치를 파악하는데 얼마나 시간을 쓰는가?

■ 테스트 실행이 너무 오래 걸린다.
대부분의 단위 테스트는 굉장히 빠른 피드백을 준다 하지만 때론 지나치게 오래 걸리는 테스트가 나올수 있다.
이 경우에는 짧은 테스트에서 더 오래 걸리는 테스트를 분리하고 싶을 것이다. 오래 걸리는 테스트는 하루에 한 번이나 적절히 며칠마다 한 번씩 정도로 실행해보고, 짧은 테스트는 자주 실행해 보면 된다.

■ 내 코드를 테스트하는 것은 내 일이 아니다.
이쯤되면 막가는 말이 나올법 하다. 진지하게 말해서, 그렇다면 정확이 내가 할 일인 것은 무엇인가?
코드가 제대로 동작한다는 아무 보증도 없이 벽 너머의 테스트 팀에게 코드를 내팽개친다면, 자신의 일을 완수하지 않은 것이다.
극단적으로 말하자면 자신이 어질러 놓은 것을 다른 사람이 치워주길 기대하는 것은 교양있는 처신이 아닐뿐 아니라, 출세를 막는 수가 될 수 있다.
실제로 지식과 능력을 겸비한 우수한 개발자가 버그를 종종 발생하여 테스터들을 신나게 한다면(앗싸! 버그다!) 오히려 지식과 능력은 다소 부족하지만 꼼꼼한 개발자 보다 인정받기 힘들어 진다.

■ 난 코드가 어떻게 동작해야 할지 정확히 모르기 때문에 테스트할 수가 없다.
코드가 무엇을 해야 할지 알지 못한다면, 어떻게 정말 그 일을 한다고 확인할 수 있는가?
지금은 그것을 작성할 적기가 아닌 것이다.

■ 컴파일된다면 괜찮은거 아닌가?
컴파일러는 로직을 검증하는게 아닌 코드의 정확성을 검증하는 것이다.

7. TDD효과

■ 자가 테스트 : 자신의 실력 평가 및 개선할 수 있는 기회 제공
■ 테스트를 통해서 요구사항을 좀 더 명확히 하고 질 높은 소프트웨어 개발 가능

 

[출처: http://ingenuity.egloos.com/1834544/ ]

Posted by lI헐헐Il
,