728x90

계속 .NET으로 만들고 작성하다 보니, 어느새 VS 에 물이 들만큼 들어 Unit Test 할 때도 VS 에서 제공하는 Unit Test를 그럭저럭 사용할 수 있게 되었다. 그래서 어느새 C#을 이용한 프로젝트 생성시, VS의 UnitTest로 다양한 TDD 적용을 시도할 수 있었다. 게다가 UI나 기능도 나름대로 흡족했다.

 

그런데, 어느날 프로젝트의 구성을 Visual C++로 구성해야 될 일이 생겼다. 그런데 막상 VS의 테스트 기능을 보고 나니 VS에서 제공하는 UnitTest기능은 .NET의 Managed Code에서만 동작하는 반쪽짜리 UnitTest 였다. 그러니 MFC나 Win32 순수 API 프로그램에서는 VS의 UnitTest를 사용할 수 없었다. 다른 대안을 찾아야 되는 시점이 오고야 만 것이다.

만일 TDD를 몰랐다면, 예전 처럼 처음 부터 하나씩 다시 짤 생각이 꽉찼을지 모른다. (아직은 초보이긴 하지만)이미 TDD의 맛을 맛보고, 감동의 여운속에서 헤메는 나로써는 결국 결국 C++용 TDD를 찾기 시작했다.

C++ 언어를 위한 TDD Framework를 찾아보면 알겠지만, 무척 다양하다. 그래서 처음 찾아본 내 입장에서는 무엇이 좋고, 나쁜지를 명확히 알 수 없었다. 그 중 나름대로 평이 좋다는 이런 저런 블로그 이야기를 듣고
UnitTest++를 선택했다. ( http://unittest-cpp.sourceforge.net )


하지만 이 UnitTest 방법은 VS의 UnitTest와는 다른 형태였고, 어떻게 하는지 전혀 알 수 없었다. 겨우 겨우 하나씩 따라 갈 수 있을 정도까지 익히고 보니, 이젠 결과물이 문제였다. 실제로 샘플코드를 시작해보았더니 왠 까만 화면만 휙 나타나다 휙 사라져버렸다. 맨날 녹색 깃발이라고 불리는 테스트 All Green은 커녕, 오로지 텍스트 기반의 메시지 밖에 없을 뿐이였다. 


그러다가 찾은 것이 Visual UnitTest++( http://code.google.com/p/vutpp ) 이였다. 이 도구를 사용하면 UnitTest++의 결과를 Visual Studio에서 Add-on 형식으로 녹색깃발을 구경할 수 있다는 것이였다.

그래서 하나씩 적용해 보았고, 그 실행 결과에 대한 내용을 적어보록 한다.

 

기본작업 환경.

개발자들은 각 개발내용이나 프로젝트에 따라 개발자별 개발 환경이 다를 수 밖에 없다.
그래서 아마 이 작업을 할때도 그 변경된 사항이나 구성된 제품들에 따라 조금씩 다를 수 있다.
이에 이 작업이 성공한 환경을 먼저 언급하고 정리하도록 한다.


- 개발 운영 체제 : MS Windows 2003 Enterprise 한글판.
- 개발 도구 : MS Visual Studio 2005 Team Suite
- SDK : Windows SDK 6.0A

 

UnitTest++ 설치(?) 하기.

맨 먼저 다음 위치(http://sourceforge.net/projects/unittest-cpp/files/) 에서 최신 버전의 UnitTest++을 받도록 한다. 이거 압축 풀면 소스 밖에 없다. 즉 컴파일을 할 수 있어야 된다는 의미다. 지금까지 계속 Visual Studio로 개발을 해왔다면, 이런 형태의 결과물은 받자마자 많이 당혹스럽다.

 

일단 이 소스를 적당한 위치에 넣도록 한다. 여기서는 압축 푼 내용을 모두 D:\Works\UnitTest++\ 에 모두 복사했다. 복사된 결과값을 보면 그 안에, VS 2003과 2005용 솔루션 파일을 볼 수 있다. ( 2008은 솔루션과 프로젝트 파일을 업그레이드 한 뒤 작업을 해야 할 것 같은데, 아직 해본적은 없다.)

파일  들 중에, UnitTest++.vsnet2005.sln 파일이 VS 2005 솔루션 파일인데, 이 파일을 열도록 한다.

솔루션 탐색기에서 보면  다음과 같이 보일 것이다.

이 프로젝트 내용 중 “UnitTest++.vsnet2005”를 컴파일 하도록 한다. 그러면 폴더 아래 쪽에  debug 라는 폴더가 자동으로 만들어지면서, 그 안에 UnitTest++.vsnet2005.lib 파일이 생성된다. 이 파일이 이 UnitTest++의 핵심 파일인데, 이 파일의 위치를 나중에 넣어서 사용하니까, 명확히 경로를 기억하도록 하자.

여기 까지가 UnitTest++ 설치 작업이였다.

 

UnitTest VisualUnitTest++ 설치.

UnitTest의 메인은 위의 단계까지 하면 끝이긴 하다. 하지만, All Green Flag와 같은 Unit Test 만의 로망인 결과값을 보기가 어렵다. 모든 결과값이 텍스트로 Success와 Fail 밖에 없기 때문이다. 그래서 이 내용을 그림으로 보여고 싶으면 이런 별도의 솔루션을 설치하는 것이 좋다. ( 혹시 DOS 창에서 Success와 Fail 로 표시되는 Text에 로망이 가득하신 분은 무시해도 상관 없다.)

 

현재(2009/8/29 기준) 최신 버전은 0.4 버전으로 다양한 UnitTest 솔루션을 지원한다. 하지만 현재로 사용할 내용은 UnitTest++ 이며, 원래 이 Visual UnitTest++도 UnitTest++을 지원하기 위해 태어난 존재이기 때문에 호환에 아무런 문제가 없다.

일단 사이트에서 최신 버전을 다운로드 받는다. ( http://code.google.com/p/vutpp/downloads/list  )

여기서 꼭 받아야 되는 파일이 두가지인데, 한개는 확장자가 .msi 로 끝나는 파일로 이 파일이 Visual UnitTest++을 실행해주는 중요한 파일이다. 그리고 vuppsample.X.X.zip 파일을 받는다. ( X.X는 버전을 의미) 설치 파일이야 당연히 필요하지만, 대개  sample 파일은 잘 받지 않는 편이다. 하지만, 이 도구로 작업 결과를 보려면 sample 파일이 꼭 필요하다. 문서화가 조금 부실해 설명 내용으로 잘 이해되지 않는 부분이 많은데, 이런 부족한 설명은 바로 이 Sample을 보고 터득해야 되기 때문이다. 여튼 설치 파일과 Sample 파일은 꼭 받기를 바란다.

 

다운로드가 되었다면, 먼저 .msi를 실행하고 설치한다.

시스템에 문제가 없다면 정상적으로 설치되며 VS를 실행해서 메뉴 항목을 보면 다음 그림과 같이 도움말 옆에 떡하니 붙어 있게된다.

일단 실행하지 말고, 이제는 아까 받은 샘플 파일 압축을 풀도록 한다.
이건 굳이 정해져 있는 것이 아니기 때문에, 바탕화면과 같이 적당하게 풀고 그 프로젝트를 열도록 한다.
그러면 C++ 용 UnitTest Framework 별로 프로젝트가 달랑 달랑 붙어 있다.  자 여기서는 최소한 Unit Test가 어떻게 되는지를 보고, 설정이 제정신으로 되었는지를 체크하는데 그 주안점을 둘 예정이다. 그래서 다른 프로젝트는 일단 두고, 이 Samle 에서 제공하는 SampleUnitTest++.2005 만 이용하여 설정 관련 확인 작업을 할 예정이다.

자 이제 Unit Test를 그럴싸 하게 할 모든 준비가 되었다.
이제 본격적으로 진행할 시점만 나왔다.

 

UnitTest 프로젝트 생성.

이 UnitTes++은 그 프로그램이 무척 간단하기 때문에, Windows UI로 동작되는 부분이 전혀 없다. 그래서 이 Test용 프로젝트는 단순 “Win32 콘솔 응용 프로그램”로 생성해주면 된다.

자신이 진행 중인 솔루션이 있다면 그 솔루션에서 오른쪽 버튼을 클릭한 뒤, 새 프로젝트를 해주도록 한다.

그러면 생성할 새 프로젝트에 대한 템플릿들을 보여주는데, 그 중 Visual C++의 Win32 항목에 있는 Win 32 콘솔 응용 프로그램을 선택해주면 된다.

적당한 프로젝트 이름을 주고(가급적이면 맨 앞의 이름을 test 라고 붙이는게 좋을 것이다. ) 만들기 하면 정상적으로 완료될 것이다. 그러면 stdafx.h와 cpp 파일 그리고 프로젝트 이름과 동일한 CPP 파일이 생성된다.
일단 stdafx 파일들은 그냥 삭제하시고 프로젝트 이름의 cpp 파일만 남겨놓도록 한다.

이제 프로젝트를 수정하도록 한다.

제일 먼저 구성 속성의 C/C++의 일반 속성 에서 “추가 포함 디렉터리” 부분에 아까 압축을 풀어 넣었던 "UnitTest++” 프로젝트의 Src 경로를 걸어주도록 한다.

이제 C/C++ 트리 안쪽에 있는 전처리기 항목에 들어가 “전처리기 정의” 에서 VUTPP_UNITTEST++ 을 추가한다.

아래쪽에 있는 미리 컴파일된 헤더 항목으로 이동해서 이번엔 “미리 컴파일된 헤더 만들기/사용” 항목 중 미리 컴파일된 헤더 사용 안 함을 선택하도록 한다. ( 그래야 아까 뺀 stdafx.h 와 cpp 파일을 찾지 않는다. )

마지막으로 아래의 링커 부분에서 입력 부분에 들어가 “추가 종속성”에서 아까 만들어진 UnitTest++을 컴파일해서 만든 .lib 파일을 연결하도록 한다.

이렇게 한 뒤, 이제 마지막으로 프로젝트 이름의 .cpp 파일을 열도록 한다. 연 뒤에, Visual UnitTest++의 샘플 파일 중 VUTPPBind.cpp 파일 내용에서 전부 복사 해오도록 한다.

자 이제 테스트 로직을 하나 추가한다. 적당한 이름의 .cpp 파일을 만들고 아래의 코드로 넣도록 한다.

#include <windows.h>
#include "UnitTest++.h"

namespace
{
    TEST(testUnitTest)
    {
        bool bResult = true;
        CHECK(bResult);

    }
}

그리고 컴파일 해보자.


컴파일 오류가 났다면 에러의 내용을 보고 위의 내용을 참고하여 수정하도록 한다.

정상적으로 컴파일 되었다면, 이제 VS의 메뉴에 있는 VUTPP –> UnitTestBrowser를 실행하도록 한다.
화면 상에 VisualUnitTest++이 뜰 것이고, Run All을 하면 아래의 화면과 같은 결과를 볼 수 있다.

 


UPDATE : 2009 / 12 / 24

주의사신 님 댓글을 보고 저도 잠시 이 포스팅 내용을 조금 읽었습니다. 약간 쇼크.
제가 다시 보는데 이게 무슨 말이야… 라고 생각이 들었습니다.

조금 다듬어 보려고 했지만, 결과는 비슷한듯 싶군요.

단지 보기가 조금이나마 편하라고, 약간의 정리만 해봤습니다.

728x90
  1. Favicon of http://sainthkh.codex.kr 주의사신 2009.12.24 09:44

    정말 고맙습니다. 다 설치해놓고 어떻게 하는 건가 고민하고 있었는데, 좋은 해결책이 되었습니다.

    • 하인도 2009.12.24 15:23

      도움이 되셨다니, 저로써는 기쁘기 그지없습니다.
      원래 XUnit Test는 리플렉터가 작동이 잘 되는 코드일 수록 쉽게 동작하기 때문에, C++ 의 Unit 테스트는 참 어렵더라구요. 가시 밭길이긴 하지만, 다양한 시도를 하면 재미있는 결과를 얻을 수도 있습니다! 파이팅!

728x90
배열형태의 클래스를 만들다 보면, 항상 인덱스 오퍼레이터를 가지고 있다.
C++에서 종종 이 operator를 오버라이딩해서 구현하곤 했는데,
내가 기억하는 C++ operator 처리 방법때로는 계속 에러를 뿜어 댔다.
문법을 정확히 기억하지 못해 헤매다가,
MS에서 제공하는 csharp language specification.doc 라는 파일을 구해서
간신히 찾아서 해결했다.

C#에 있는 Property 문법을 사용해서 구현하면 operator [] 를 생각보다 간단하게
구현할 수 있었다.

public object this[string sKey]
{
     get
     {
          return this.GetData(sKey);
      }
      set
      {
          this.SetData(sKey, value);
      }
}


대략 코드를 보면 알 수 있긴 하지만,
키 코드는 this 이 부분이다. 즉 보통 배열의 인덱스를 사용하는 방법을 보게 되면,
 KK[i] = 44; 

라는 형식으로 KK 부분이 바로 해당 클래스의 변수 자체를 가르키게 된다. 그러므로 operator
에서 this를 쓴다. 그리고 난 뒤 , [  ] 안쪽에 무슨 값으로 구분하는지에 따라,
해당하는 변수를 구성해주면 된다.
만일 숫자인 경우 [int nIndex] 형식으로 써주면 되고, 지금 필자 같이 문자열이라면
[string sKey] 이런 식으로 쓰면 된다.

나머지는 C#의 get / set 의 구현 방법에 맞게 원하는 코드를 넣기만 하면 된다.


728x90
728x90

C#에 있는 WinForm을 이용하여 ListBox 상에 데이터를 추가할 때 여러가지 방법이 있지만
나름대로 상당히 좋은 방법이 있어 여기에 기록합니다.

ListBox 상에 데이터를 넣는 방법은 보통 ListBox 객체 내에 있는 items를 이용하여
추가/삭제를 시도하게 됩니다. 하지만, 만일 ListBox 내에 표시되는 내용과 실제 사용하게
될 데이터가 틀린 경우에는 조금 다른 문제가 발생합니다.

여기서는 두가지 방법을 제시하려 합니다.
첫번째 방법은 가장 일반적인 방법으로 ListBox.items 라는 콜렉션 내에 추가하는 방법입니다.
가장 직관적이고 빠르게 처리할 수 있는 방법이죠.
두번째 방법은 DataSource 속성을 이용해 별도 데이터를 담은 콜렉션을 만들어 이 ListBox와 연결해주는 방법입니다.


1. ListBox.items 를 이용하는 방법

2. DataSource를 이용한 방법


3. ListBox 데이터 바인딩 팁.
이 글을 쓰게된 가장 중요한 사항인데, 사실 DataSource를 이용해 데이터 객체와 바인딩 하고 난뒤 이후의 처리가 굉장히 황당한 경우가 있습니다. 특히 원본 데이터 부분을 업데이트 했는데도 불구하고, ListBox내의 내용이 전혀 변화가 없는 경우입니다.
처음에 저는 다음과 같은 함수를 만들어 위의 문제를 해결해 보려고 했었습니다.

[CODE] private void UpdateList(ListBox listbox, List<DataType1> list)        {            try            {                BindingManagerBase bm;                bm = listbox.BindingContext[list];                bm.CancelCurrentEdit();                bm.ResumeBinding();            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }            listbox.Refresh();        } [/CODE]
보통 컨트롤 내에 데이터 바인딩 기법을 사용하게 되면 데이터 바인딩에 관련된 기능들을 이용할 수 있는데, 여기서 데이터 바인딩 매니저를 이용하여 업데이트 하게 끔 만든 것입니다.
그러나 최악의 문제가 원본 데이터가 완전히 비어 있는 경우 입니다.
이 경우 원본 데이터가 비어 있으므로 ListBox의 컨트롤 데이터가 전혀 변화가 없게 됩니다.
그래서 결국 위의 내용을 다음과 같이 변경 했습니다

[CODE] private void RebindingListBox(ListBox listbox, List<DataType1> list, string DisplayName, string ValueName)        {            listbox.DataSource = null;            listbox.DataSource = list;            listbox.DisplayMember = DisplayName;            listbox.ValueMember = ValueName;        } [/CODE]

코드를 보시면 알겠지만, 바로 바인딩 작업을 완전히 리셋한 뒤 다시 바인딩을 시도했습니다.
이 경우 바인딩 정보가 완전히 리셋되기 때문에, 원본 데이터 내용이 비어 있어도,
정상적으로 처리가 됩니다.

물론 위의 방법은 제가 발견한 팁일 분, 프로그래밍의 정답은 아닙니다.
개인적으로도 위의 방법은 비용이 조금 비쌀듯 해보입니다. 바인딩 정보를 완전히
날리고, 다시 재 바인딩 하기 때문에, 무언가 비용이 많이 들어갈 것 같습니다.
하지만, 현재 제가 발견한 방법 중에 확실하게 처리되는 것 같아 제시한 것입니다.

더 좋은 방법이나 다른 의견 있으시면 댓글을 통해 말씀해주시면 고맙겠습니다.
728x90
  1. waterbell 2012.05.18 16:59

    안녕하세요. 님의 글을 보고 도움이 많이 되었습니다.
    다른 곳(http://arstechnica.com/civis/viewtopic.php?f=20&t=554717)에서 본 내용을 약간 접목해서 다음과 같이 수정 해봤습니다...

    private void UpdateList(ListBox listbox, List<ParsingItems> list)
    {
    try
    {
    //BindingManagerBase bm;
    //bm = listbox.BindingContext[list];
    //bm.CancelCurrentEdit();
    //bm.ResumeBinding();

    CurrencyManager cm = (CurrencyManager)BindingContext[list];
    if (list.Count() == 0) // 다만, 요 부분이 맘에 걸리네요...
    cm.List.Clear(); // 어째 깔끔하지 못한 듯...
    cm.Refresh();
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }

    listbox.Refresh();
    listbox.ClearSelected();
    }

    모르겠는 점은... 'CurrencyManager cm = (CurrencyManager)BindingContext[list];' 에서
    cm의 DataSource의 count는 '0'가 되었는데, List는 '0' 되길 거부하는 듯... ㅠㅠ
    그래서 강제로 cm.List.Clear();를 한 것입니다.

    이만 줄이겠습니다..

728x90
가급적 모든 리소스는 리소스에 넘기는 것이 좋습니다.
특히 스트링 부분.
다국적 형태로 만들려다 보면 여러가지 애로 사항이 많습니다.
하드 코딩을 통해 내부적으로 각종 String을 양산하게 되는데,
나중에 다국적 코드로 만들려면... 생각만 해도 아찔합니다.

이를 해결 하는 방법은 Resource를 따로 빼내어 처리하는 방법입니다.

다음과 같은 것들을 고려해서 작성하게 되면 수월하게 작성할 수 있습니다.

Main Module Handle을 가져 옵니다.
EXE 같은 경우에는 GetModule 을 통해 가져오면 됩니다. 매개 변수에는 파일이름을 넣으시면 되구요.
DLL 같은 경우에는 DLLMain 부분에서 얻으시면 됩니다.
DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)

여기서 얻은 핸들을 저장하는 방법인데, 여러가지 방법이 있겠지만, 저 같은 경우에는
전역 변수를 통해 넣었습니다.
특히 stdafx.h 와 stdafx.cpp 에다 넣었는데,
stdafx.h에는 extern HANDLE g_hModuleHandle; 을 넣고
stdafx.cpp 에는 HANDLE g_hModuleHandle; 을 써서 넣었습니다.

여기서 주의하실 것은 여러개의 모듈이 난무하는(다양한 DLL을 참조해서 쓰는)경우에는
가급적 Unique한 이름으로 만들어야 합니다.
저 같은 경우에는 XXXX.DLL 인 경우 g_hXXXXModule 이라고 이름을 지어버렸죠.


728x90
728x90
1) 파일 맨위의 상단에 붙이게 되는 Box 입니다.
//----------------------------------------------------------------------------
// FILENAME : ..... .h
//
// Classes
//    * 클래스1 이름
//      - 설명
//    * 클래스2 이름
//      - 설명
//
// Handlers
//    * 작업자 명 : ID
//
// Memo
//   [05/04/20 12:00] id [catergory] :  메모 네용
//
// Update List
//   [05/04/20 12:00] Update 내용1
//   [05/04/20 12:00] Update 내용2
//----------------------------------------------------------------------------

* FILENAME
설명이 필요하겠습니까? 그냥 파일 이름

* Classes
여기에는 현재 .H 에 등록된 Class들을 적습니다. 물론 VC 스타일로 작성하게
되면 이상하게 한개의 파일안에 한개의 Class가 상주하게 되지만, 꼭 그럴 필요는 없죠
여러개의 Class가 한개의 파일안에 상주 할 수 있으니깐요.
설명은 굳이 방법은 제시하지 않지만 외부에서 사용하는 사람이 편하게 내용을 서술해
주는 것이 좋죠.

* Handler
작성자인 author 라고 쓸수도 있지만, 이 파일을 여러사람이 만지는 경우에는 꼭
그렇지는 않죠. 작성한 사람이나 편집하는 사람이 있으니깐요.
그렇다고 Author, Editor 나누기도 그렇고... 그냥 Handler 조작하는 사람들이라고
해버렸습니다 .
여기에는 이 파일에 손대는 사람들을 기록하는 부분입니다.
일단 "실명 : ID " 형태를 취하는데, 이유는 메모나 업데이트 부분에 그 밖에 여러가지
기록할때, 실명을 일일히 적는 것보다 ID로 적는게 타이핑 수도 줄이고 알아보기도 편하니깐요.
저 같은 경우에는 "김형진 : neohind" 라고 적을 예정입니다.
아, 여기서 Main Handler는 최상단에 위치해야 됩니다. 최소한 소스 책임질사람이
있어야 되니깐요.

* Memo
일단 각종 잡담 부터 시작해서 경고 요청 등등의 내용을 기록하는 부분입니다.
항목(Category) 부분은 계속 업데이트 하겠지만... 일단 간단하게 다음 정도로
적고 싶습니다.

  TODO : 해야 될 내용 - 추후에 첨가되길 바라는 것들
  DEL : 삭제되어야 될 내용 - 릴리즈시 삭제되길 원하는 내용
  ETC : 진짜 잡담 - 그냥 소스로 대화하고 싶을때(笑)
  CAU : 주의 사항 - 소스 사용시 주의 사항
  REF : 참고사항, 다른 소스(코드가 아닌 정보)를 참조할 필요가 있을때,

작성 예는 다음과 같습니다.
[xx/xx/xx xx:xx]  id [????] : 내용
  xx 부분은 당근 날짜와 시간이 들어갑니다.
  id 는 위에서 Handler에 기록한 ID를 적으면 되구요
  ???? 는 Category를 의미합니다.
  내용에는 당근 자세한 설명이 되겠죠. 가급적 1줄로 해결을 봤음 합니다(笑)
   예) [05/04/20 12:00] neohind [ETC] : 이봐.. hind, 소스가 웃기잖아!!!

* Update
이 부분은 Versioning에 관련된 부분입니다. 가급적 소스의 메인 핸들러가
작성하는 부분이 되는데, 소스 버젼 업그레이드 될때 마다 기록해 줍니다.
어떻게 업데이트 되었는지를 로그로 남기는 부분입니다.

--------------------------------------------------------------------------
2) 코드 재 참조 방지용 #ifndef 작성
보통 Header 부분은 많은 곳에서 #include를 수행하게 됩니다.
이 때 Header의 재참조를 막기위해서 전처리기용 예약어를 이용해서 만드는데,
이 부분에 대한 설명입니다.
#if !define ??? 뭐 이렇게도 적을 수 있지만.. 통일성을 위해 아래와 같이 이용합니다.

#ifndef __[HeaderFilename]_
#define __[HeaderFilename]_
    .....
#endif // __HeaderFilename_

__HeaderFIlename_ 이 부분은 "__"  + 파일명 + "_" +확장자 + "_" 의 구성으로
작성합니다. Header의 Filename을 서술시에는 반드시 전체 대문자로 기록합니다.
Service.h 를 작성한다면 __SERVICE_H_ 라고 합니다.



728x90
728x90
코딩하는 방식은 사람마다 틀리기 때문에, 고집시킬 수는 없습니다.
물론 팀작업을 하게 되는 회사에 소속되면 그 팀/회사에 코딩 규칙을 맞추어야 하죠
하지만, 일단 솔로/프리인 저 같은 경우에는 그 다지 없군요.

MS사는 헝그리안 코딩 규칙에서 벗어났더군요. Type 형태를 변수 앞에다 적는..
물론 그것이 정답일 수도 아닐 수도 있습니다.

일단, 저 같은 경우에는 어떻게 결정할 지는 이 문서를 통해 정리해 나가야 겠습니다.




728x90
728x90
Visual SourceSafe 6.0 #2

4. Check Out / Check In

소스등록을 완료 했으면 이제 준비작업은 다 끝난 겁니다. 지금까지 걸어온 길은 이제 소스의 버전관리를 위한 준비과정이었습니다.
여기까지 셋팅이 완료되면 이제 진짜 버전관리에 들어가는 것입니다.

맨 처음에 언급한 버전관리라는 부분을 읽고 기억하시는 분도 계시리라 믿지만
혹시나 하는 노파심에 다시 버전관리에 정의를 다시 알려드리겠습니다.
 

버전 관리의 핵은 변화된 시점을 정확히 체크해주는 것입니다. 물론 VSS가 어느 정도의 자동화를 해준다고 하지만, 실제 변화된 시점을
알려주는 것은 바로 개발자의 몫입니다. 물론 이렇게 간단하게 끊어 버리면 많은 분들이 의문을 가질 수 있습니다.
무엇을 끊고 무엇이 변화된 시점인지... 전혀 감이 안 잡힌다는 문제죠.
일단 제가 가진 소스를 가지고 어떻게 표현을 하는지 한번 언급을 하도록 하겠습니다.

소스의 변화라는 것은 단순 주석 변경이나, 엔터키 입력, Space 키 입력을 의미하는 것이 아닙니다.
일 예를 들기위해 제 나름대로의 기준은 클래스 추가, 변경, 삭제 입니다.
물론 정책별로 들립니다. 실행되는 모듈을 기준으로 잡을 수도 있고, 기능의 세세한 부분의 변경도 될 수 있겠지만,
저의 기준은 클래스를 두고 봅니다. 그래서 클래스의 추가가 발생하거나, 클래스 내부가 변경되거나, 삭제 될 때
소스의 버전 업 단계를 둡니다.

하나의 가상의 이야기를 적어 보겠습니다.

제가 이 VSS를 설명하기 위해 제 나름대로의 프로젝트인 naoko를 예로 들겠습니다.
하지만 아직 이 naoko는 현재 Dialog-base MFC Application 형태로 Wizard를 사용하여 자동 생성해놓은 상태입니다. (笑)
일단 설명을 위해 작성한것에 불과하니깐요.
그럼 본격적인 설명으로 들어가죠.
일단 모듈을 하나 추가하고 싶습니다. 자동으로 만들어진 클래스 3개 중에 Dialog 부분에서 LButtonDown 시에 확인창을 띄우는 기능을 추가하고 싶어졌습니다.
일단 제 소스형태를 보여드리죠.

  

보시면 알겠지만 뭐 들어 있는 건 거의 없습니다. Dialog-base로 Wizard로 만들어 놓고, 설계만 하고 코딩은 전혀 안 한 상태죠.

모듈 추가이므로 이 부분을 VSS에게 알려야 합니다. 즉 CNaokoDlg 에 LButtonDown을 추가한다는 사실을 VSS에게 알려줘야
하는 것입니다. 게다가, 이 소스는 바로 앞장에서 말씀 드렸듯이 모든 Source에 Read-only가 되어있다는 사실입니다.
어차피 소스의 수정은 안 된다는 의미입니다.

일단 VSS를 띄우고 해당하는 소스부분을 선택합니다. 지금 수정할 Class가 CNaokoDlg 이므로 naokodlg.h 와 naokodlg.cpp를
수정하게 될 것입니다. 이 부분을 VSS 상에서 선택 처리 해야 합니다.


보시면 아시겠지만 왼쪽 트리에서는 naoko를 선택하고 오른쪽 소스 리스트에서는 해당하는 소스 파일이름을 멀티 셀렉트했음을 알 수 있습니다.
일단 이렇게 선택하시고 메뉴의 SourceSafe -> Check Out을 선택합니다.
즉 소스의 수정의 시작을 의미합니다. 이렇게 선택하면 아래와 같은 대화창이 뜹니다.


여기서 보면 각종 여러 가지 옵션들이 있는데, 이 부분은 나중의 연구부분으로 두고 일단은 간단하게 넘어가도록 하죠.
Comment에 무언가를 쓰게 되어 있고, To에는 현재 프로젝트의 소스파일 위치를 알려주고 있죠.
거기에 Don't get local copy 와 Only show this dialog when the Shift key is down 의 체크가 있고,
Advanced 라고 해서 무언가 더 펼쳐 질것 같고요.
체크와 Advanced 쪽은 넘어가죠.
현재 중요한 것은 Comment 정도니깐요.

Comment에 현재 왜 이 소스를 Check-out 하는 지를 적어 줍니다. 물론 Check-out에서 굳이 내용을 적을 필요는 없습니다.
VSS 로그 상에서는 그 부분은 기재하지 않거든요. 그럼 왜 적어 줄까요?
혼자 작업하는 경우에는 거의 쓰이는 경우가 없지만 단체로 작업할 때는 쓰입니다.
즉 A라는 사람이 해당 Source를 Check-out 해버리면 다른 사람들은 VSS상에서 Check-out을 승인 받지 못합니다.
즉 소스를 전혀 수정하지 못하게 되죠. 이 때 Check-out 승인을 받지 않은 사람은 왜 승인을 못 받는지에 대해서
간단한 메시지를 이 Comment를 통해 받게 되죠.

즉 혼자 짤 경우에는 Comment를 비워놓고 OK 하셔도 됩니다. 하지만 팀 플레이 하게 되는 경우가 발생할 수 있으며
좋은 버릇은 처음 부터 들여 놓는 것이 좋으니깐, 가급적 써주세요. 번.거.롭.더.라.도. 말이죠.
원래 버전관리는 무척 번거로운 작업입니다.


Check-out 하시면 드디어 무언가 변화된 모습을 보실 수 있습니다. naokoDlg.cpp와 naokoDlg.h 아이콘에 check 표시가
되어 있죠. 바로 Check-out의 시작입니다. 즉 이 소스는 User에 적힌 ID로 접근한 사람만이 변경을 할 수 있다는 의미입니다.
Check Out Folder의 의미는 해당 ID로 접근한 사람의 로컬 PC내의 Working Folder를 보여줍니다.
사람마다 소스를 넣는 위치는 다 틀리므로 어디에 있는지 알려주는 것이죠 ^^


자, 이제 LButtonDown의 모듈을 넣습니다.


아주 웃기는 내용이지만 일단 모듈 추가를 한 것이죠. 일단 해당 소스를 컴파일 해서 실험을 합니다.
컴파일은 제대로 되는지 정상적으로 작동하는지. 이 부분의 기준은 개인적으로 가지고 있는 점검표를 가지고 점검을 해보세요.
꼭 점검을 제대로 하시는 것이 좋죠. VSS에 등재하기 전에 꼭 이런 테스트를 가지도록 하세요.
번거로운 작업이지만 나중을 위해서는 꼭 해두는 것이 좋습니다.

그리고 난 뒤에 변경된 소스를 저장하세요. 가급적 Files -> Save All을 통해 저장을 해두시기 바랍니다. 단순히 소스상의
변경된 내용이야 소스파일을 선택해서 저장하면 되지만, 파일을 추가하거나 삭제한 경우 *.dsp 파일이 변경이 되는데
대부분 이 파일을 저장하는 것을 잊어 먹는 경우가 많습니다. Save All 하시면 이 파일도 저장이 되므로 꼭 전체 저장을 해주시기
바랍니다.

자 대망의 Check-in.
체크인전 중요한 점을 잊지 않으셔야 될것 같습니다.
물론 추후 Versionning 이라는 주제로 다시 언급하겠지만, 여기서 간단하게 언급을 하자면, Check-in 전에 반드시 정상적으로 실행되는 모듈이여야 합니다.
Check-in 하게되면 VSS 상에 등록이 되는데, 원래대로 돌아가는데 컴파일 오류나 버그가 있으면 굉장히 곤란한 상황에 빠집니다. 반드시 컴파일 하고, 자신만의 테스트 후에 등록하세요


이제 VSS 상에 변경된 내용을 적용을 해야 합니다. 아직까진 자신의 PC내의 소스만 변경된 것이지 VSS 상에서는 저장이 된 것이 아닙니다. 즉, 이젠 변경된 내용을 VSS에 올리는 작업을 해야 합니다. 바로 전에도 언급했듯이 반드시 전체 저장을 해주시기 바랍니다.
오로지 로컬상에 저장된 파일을 올리지, VC에 떠 있는 파일을 올리는 것이 아닙니다 !!!!



check-in 메뉴가 이전과는 다르게 활성화 되어 있죠?
Check-out이 된 상태의 소스만 저렇게 활성화가 됩니다.
일단 저 두 개의 파일을  Check-in 해줍니다.


Check-out과는 다르게 Comment의 크기가 압도적이죠? Check-in이 되는 순간 VSS상에 기록이 완전히 되버리기 때문입니다.
가급적 상세하게 적어주세요. 물론 빈 채로 두어도 되지만, 자신이 왜 현재 소스를 Check-in 했는지의 여부를 나중에 알 수 있게 되기 때문입니다.
나중에 문득 왜 이렇게 수정이 되었는지를 알 수 있게 되는 중요한 단서가 될 수 있기 때문이죠.

여기서 잠깐! Check-out 이라는 단어의 의미를 먼저 아시면 헷갈릴 위험이 적죠. 지금 check-out을 사전에서 찾아보시면 "기계의 점검"을 의미합니다.
즉 여기서는 소스의 점검이 되겠죠. check-in은 점검 완료의 등재를 의미하게 되죠. 이 부분을 헷갈리지 마세요.
Check Out으로 시작해서 Check In으로 끝난다는 사실을 기억하시면 됩니다.
728x90
728x90
Visual Source Safe 6.0 #1

이제 준비 작업 중 2/3는 끝났습니다. 이제 이용하기 위한 준비를 하도록 하죠.

VSS를 이용하는 방법은 크게 2가지가 있습니다.

1. Microsoft Visual SourceSafe 6.0를 띄워서 하는 경우
2. Visual C++ 에서 직접 하는 경우

1번째 방법은 Visual Source Safe 클라이언트를 직접 띄워 하는 방법입니다. DB에 저장된 내용을 한눈에 볼 수 있고
소스 관리는 한눈에 보면서 합니다. 게다가 버전관리에 관련된 다양한 기능을 다 쓸 수 있습니다. 게다가 소스 위치만
잘 정해 주시면 VC말고도 다른 언어 소스도 버전관리도 할 수 있습니다.  
VC의 자동화 기능을 쓰다가 쓰면 아주, 아주, 불편해 보일 지도 모릅니다.
게다가 소스 창과 이 창을 계속 왔다 갔다 하다 보면 어느새 손이 Alt + Tab을 하염없이 누르고 있는 자신을 바라보게 됩니다 -_-;;;;

2번째 방법은 어차피 VC에서 지원하는 방법인지라 그냥 하시면 됩니다. 거의 완벽에 가까운 자동화죠.
개인적으로는 권장합니다. 편하거든요. 그냥 VC 하면서 자동적으로 버전 관리도 해주고 그냥 그냥 씁니다.
Source 편집 시에 자동으로 Check Out을 해주고 자동으로 VSS 의 DB에 연결해줍니다.
Check In이 되어 있는 경우에 자동적으로 편집도 안되게 해줍니다.

하지만,  여전히 버그는 있는지라 완전 맹신하면 크게 뒤통수 한번 맞습니다. VSS 기능을 뛰어넘는 기묘한 작업
(VSS 설정 파일 손대기 및 소스 위치의 변경 등등)을 하게 되면  갑자기 Check In/Out이 지원 안되거나
이상한 폴더에 소스를 복사해 놓고 멋대로 작동하는 경우가 발생합니다.
자동화에도 한계가 있음을 다시 한번 확인할 수 있다고나 할까요?
- VS 2003 에서는 제대로 되겠죠? 잘 모르겠습니다. 여전히 VC 6.0 Sp5를 쓰는 입장이라 ... -

일단 1번째 방법을 먼저 설명하겠습니다. 그  VSS 6.0 Client  이 Tool 이용하는 법을 어느 정도 익숙해지면 VC에서는 손쉽게 적용이 가능합니다.
게다가 기능도 무지 많아서, 추려서 자주 쓰는 기능들을 언급하도록 하겠습니다.

1.로그인

Visual Source Safe 6.0 을 실행 시키면 제일 먼저 아래와 같은 화면이 뜹니다.


자신이 쓰는 DB 이름이면 그냥 ID와 Password를 넣으시면 됩니다. 만일 아닐 경우
(예를 들면 COMMON 이거나 전혀 다른 DB 이름인 경우) Browse를 눌러 아래와 같은 창이 뜨면 해당하는 DB를 선택해 주시기 바랍니다.
역시 리스트에 없으면 창에서 Browse를 선택해서 해당 DB위치를 잡아주셔서 등록해 주시기 바랍니다.


뭐 이 부분은 앞에서 VS Admin 부분을 통해 알려드렸으니깐 하실 수 있겠죠? VSS에 로그인을 하시면 됩니다.

 

2. VSS Main Window



로그인을 하면 위와 같은 화면이 뜹니다. 일단 간단하게 번호를 매겨서 위치를 설명해 드리겠습니다.

1번 위치 : DB에 저장된 프로젝트 폴더 리스트 입니다. Explore의 폴더 보기와 동일한 트리구조 입니다.
2번 위치 : 선택된 폴더에 있는 파일 리스트 입니다. 1번위치에 해당하는 폴더를 선택하면 그 안의 파일들을 보여 줍니다.
3번 위치 : 각종 기능들이 작동된 Log를 나열합니다. 각종 기능 결과값을 보여 줍니다.
4번 위치 : 메뉴 입니다. (번호를 매기고도 민망합니다.)
5번 위치 : 툴바 입니다. (역시.. 민망 ... _nollll .... )

DB안에 많은 프로젝트를 담을 수도 있고 하나의 프로젝트를 담을 수 있습니다. 일단 $/ 위치 바로 아래 부분을 보통 프로젝트라고
합니다. 물론 루트에다 해당하는 소스를 걸 수 있지만, 일반적으로 바로 아래 단에 프로젝트 이름을 담은 폴더를 만들어 두곤 합니다.
뭐 정책은 자신의 기준에 맞추어 세워 두시면 됩니다.

그리고 원래는 해당하는 부분에서 마우스 R-Click 하면 해당 메뉴들이 쏟아져 나오는데, 이것까지 연동하여 캡춰하기가 그러니깐,
가급적 설명은 메인 메뉴와 툴바를 이용하여 처리하도록 하겠습니다. 마우스 R-Click 메뉴 부분은 알아서 비교 연구를..(죄송 ;;;; )

 

3. 프로젝트 생성과 소스 등록

대충 설명하고 갑자기 실제 기능적인 설명에 어이 없을지는 모르겠지만, 제가 이 VSS에 대해서 이론적인 바탕이 거의 전무합니다.
오로지 사용하닥 깨달아서 나온 경험을 근간하기 때문이죠. 그러므로 실제 설명도 제가 사용해 보았던 방법을 근간으로 말씀드립니다.

여기서는 Folder가 하나의 프로젝트로 생각한답니다. 프로젝트라고 적혀 있어도 그냥 폴더라고 생각해 주시기 바랍니다.

  

먼저 1번 폴더 리스트에서 루트를 선택하시고, Files -> Create Project 를 골라주시기 바랍니다.
그러면 오른쪽과 같은 다이얼로그가 뜨는데, 위 창에 이름을 아래 창에 해당 프로젝트 설명을 넣어 주시기 바랍니다.
물론 Project 이름은 가급적 영어로 써주세요.
한글로 써 본적이 한번도 없어서 잘 모르겠지만, 왠지 위험. 그래서 가급적 영어로 써주세요.

그러면 아래와 같이 등록이 됩니다.



프로젝트 폴더 리스트가 보이는데 거기서 naoko가 등록된 것을 볼 수 있습니다. naoko를 선택하시면
역시 아무것도 등록하지 않았기 때문에 보이는 건 저것 밖에 없지만.. 이제 실제 프로젝트로 사용할 내용을 등록해야 합니다.


등록할 때 쓰는 메뉴는 File -> Add Files ... 입니다. 잠깐 여기서  Add Files 하는 것은 다 좋은데 먼저 파일을
add 할 폴더를 왼쪽 프로젝트 트리 창에서 선택을 해주세요.
루트에 체크된 상태에서 Add 해봐야, 루트에 Add 될 뿐입니다.  꼭 해당하는 위치에서 Add 하세요.
혹시 잘못 Add 했으면 꼭 Add 된 파일을 지우세요.
여기서 Add 된 것은 DB에 기록되는 것 뿐이니깐, 지워도 원래 위치에 있는 파일은 안 지워 집니다.
Add Files를 하시면 아래와 같은 다이얼로그가 뜹니다.


해당 소스가 있는 위치를 잡으세요. 그리고 난 뒤에 List files of type에서 VC 부분을 선택하세요. 모든 파일을 add 할 수 있겠지만, 쓸데 없는 DB 낭비일 뿐이죠.
그러므로 꼭 해당하는 파일만 Add 하시길. 일단 VC로 필터링 된 파일은 다 Add 해도 됩니다.

Add 하면 아래와 같은 대화 창이 뜹니다.


각 파일을 등록할 때 지금 등록된 파일에 대한 설명을 넣으시면 됩니다. 물론 귀찮으신 분은 Apply same comment for all 을 체크하시고 대충 쓰시고 OK 하시면 됩니다.
그러면 지금 Add 파일 모두 로그상으로는 지금 적은 Comment로 등록됩니다. 귀찮더라도, 친절하게 Comment를 넣으시면 나중에 History를 보면서 도움은 많이 됩니다.

첫 Add를 할 때, Set working Folder를 지금 Add한 파일 위치에 넣겠냐고 묻는 대화창이 뜨는데,
그건 그냥 OK 하세요. Working Folder 부분에 대해서는 나중에 설명 드리죠. 일단 이렇게 Add를 했죠.
그러면 아래와 같이 뜹니다.


하지만 다 한 것이 아니랍니다.
보통 Wizard를 통해 VC프로젝트를 만들면 res라는 폴더가 자동으로 생깁니다. 이것도 넣어 주셔야겠죠. 애석하게도 Add File 안에는 Recursive(재귀호출) 방법으로
하위 폴더 까지 Add를 못해주기 때문에 번거롭더라도 프로젝트를 이하에 생성해 주어야 합니다. 마찬가지로 트리에서 해당하는 프로젝트를 선택하시고
위에서 언급한 프로젝트 생성과 동일한 방법으로 res를 생성해 주시기 바랍니다. 그러면 아래와 같은 화면으로 뜹니다.


위에서 마찬가지로 해당하는 소스를 더해서 처리하면 아래와 같이 됩니다.


이런 식으로 소스를 등록해 주시면 됩니다.


------------------ 수정 2005/02/25 ---------------------------------------------------
Add 하는 방법에 대해서 추가적으로 말씀 드릴 것이 있습니다.
위의 방법은 File 한개 한개를 등록하는 방법으로, 만일 프로젝트가 여러개의 폴더일때는..
정말이지 노가다에 가까운 작업을 하게 됩니다.
저도 한동안 VSS를 안하다 보니, 갑자기 빠트리게 되었습니다. -_-;;;;;
요근래 프로그래밍을 하다고 보니, 그 방법을 알게 되었습니다.

앞에서는 Project를 Add 할 때, 위에서는 Add 할 위치를 Create Project를 이용하여 생성했습니다.
하지만, 이번에 하는 방법에서는 그럴 필요가 없습니다. 폴더 채로 등록하는 것이니깐요.

현재 프로젝트 폴더가 어딘지 그 위치를 보세요. 위치상으로는 1번 창에 나오는 부분인데, 지금 커서가
등록할 위치에 해당하는지를 확인하는 것입니다.

그리고 등록을 할 폴더를 Add 하는 작업입니다. Add는 물론 위에서 처럼 File -> Add Files ... 를 통해
시작합니다. 그러면 다음과 같은 화면이 뜹니다.


여기서 이전에는 소스를 선택했다면, 이번에는 폴더를 선택하는 것입니다.
예제 화면을 기준으로 하면 오른쪽에 보이시는 NAOKO라는 폴더를 선택하시면 됩니다.
왼쪽의 소스부분말고, 오른쪽의 폴더를 선택하는 것입니다.
물론 맨 아래에 있는 파일 종류를 선택해 주시기 바랍니다. 그러지 않으면 잡스런 파일이 다 Add되니깐..
가급적 파일 종류를 선택해 주세요. 물론 지금은 VC용이니깐, 당연히 VC용을 선택하시면 됩니다.
그리고 OK 하세요.
그러면 파일 등록할 때와는 약간 다른 화면이 뜹니다.

저 창의 아래부분을 보시면 색다른 체크가 있습니다.
바로 RECURSIVE. 이것이 바로 이하 폴더까지 전부 긁어 주는 훌륭한 기능을 하는 체크 버튼 입니다.
이 체크 버튼을 체크 해주시고 OK 해주세요.

그러면 이전에 파일만 등록하는 것과는 다르게, 이하 폴더의 내용까지 전부 Add 하게 됩니다.

--------------------------------------------------------------------------------


자, 등록된 파일을 확인해보도록 하겠습니다. 현재 VSS 등록된 파일들을 열어보시면 신기한 광경을 구경할 수 있습니다.


현재 VSS에 등록된 파일들이 전부 Read-only가 되었다는 사실입니다. 즉 아무렇게나 편집되지 않도록 Read-only를 자동으로
걸어주는 것입니다. 요즘은 Read-only에 대해서 그다지 특별한 안전장치는 아닙니다. 간단하게 Read-only를 풀수는 있죠.
하지만, 중요한 것은 Read-only가 걸린 파일은 꼭 VSS를 거쳐 달라는 의미라는 것입니다.
즉 소스 편집을 한다고 무조건 Read-only를 멋대로 풀고 소스 작업을 하는 것이 아니라, 꼭 VSS 를 통해서 작업을 해달라는 것입니다.
이점을 꼭 기억하세요!!!!!
728x90

+ Recent posts

728x90