달력

122019  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  
  •  
JUnit을 이용한 테스트케이스를 실행한 결과를 api형태의 보고서로 또는 그래픽으로 비주얼하게 보여줄 수 있습니다.

http://www.okjsp.pe.kr/docs/report 에서 확인할 수 있습니다.

아울러 hudson에서도 다른 형태의 리포트가 나옵니다.
우측 상단의 파란색 그래프입니다.

더 자세한 정보도 볼 수 있습니다.

http://www.okjsp.pe.kr:8080/job/okjsp%20site%20build/

아주 오래 미뤄왔던 일을 해내었습니다. 이제 버그 잡아야겠습니다.
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. Kenny  댓글주소 수정/삭제 댓글쓰기 2009.06.15 17:13

    여전하시네요. ^^ 화이팅!

  2. Richpapa  댓글주소 수정/삭제 댓글쓰기 2010.01.12 17:02 신고

    안녕하세요. 요즘 아이폰과 안드로이드에 관심이 많은지 알고 있습니다. 그래도 질문 좀 할께요.

    ANT 파일에 JUnit을 설정하고(성공), JUnit report 작성중에 있습니다. JUnit Report를 하기 위해서 일부러 에러를 냈습니다. 간단한 테이블에 로우수가 5개인데, 4개로만 어썰트 했기에 에러가 납니다.

    junit.framework.AssertionFailedError: expected:<4> but was:<5>

    1. 일단, 임으로 에러를 냈기 때문에 ANT 파일 돌리니까, 다음과 같은 결과가 나옵니다.

    junit report:
    [mkdir] Created dir: D:\WORKSPACE\PRIVATE\JdbcTemplate Snapshot\report\html
    [junit] Running test.step1.DaoTest
    [junit] Tests run: 4, Failures: 1, Errors: 0, Time elapsed: 1.234 sec

    BUILD FAILED
    D:\WORKSPACE\PRIVATE\JdbcTemplate Snapshot\build.xml:36: Test test.step1.DaoTest failed

    JUnit Report 생성 디렉토리로 가보니 html안에 파일 생성되지 않습니다. (물론 에러를 안내고 JUnit을 통과하면 생성이 되고요)

    어떻게 하면 생성이 될까요?

    2. 만일 생성이 되지 않는다면 JUnit Report를 만들 의미가 없는 것 같은데... 물론 그렇지 않겠지만... 잘 안되네요.

    • 케누 kenu허광남  댓글주소 수정/삭제 2010.01.12 17:41 신고

      <!-- ==================== test Target ==================================
      -->
      <target name="test" depends="publish">
      <mkdir dir="report" />
      <junit printsummary="on" haltonfailure="off">
      <classpath refid="test.classpath" />
      <formatter type="xml" />
      <batchtest todir="report">
      <fileset dir="dst_test">
      <include name="**/*Test*" />
      </fileset>
      </batchtest>
      </junit>
      <mkdir dir="${publish.home}/docs/report" />
      <junitreport todir="report">
      <fileset dir="report">
      <include name="TEST-*.xml" />
      </fileset>
      <report format="frames" todir="${publish.home}/docs/report" />
      </junitreport>
      </target>

      haltonfailure="off" 이 옵션때문이 아닐까요?

  3. Richpapa  댓글주소 수정/삭제 댓글쓰기 2010.01.12 19:19 신고

    먼저 답변 주셔서 고맙습니다. 저는 on으로 되어 있습니다.

daysago 0.31

java 2009. 3. 19. 18:37
재미있는 경험을 했습니다. http://code.google.com/p/daysago 라는 간단한 프로젝트를 오래 전에 열었는데 처음으로 다른 사람의 피드백을 받았습니다. 고맙게도 버그있는 코드의 수정본까지 받았습니다. 해당 코드를 패치하고 테스트케이스를 돌려보니 다른 부분에서 영향을 받는 것을 확인하고, 로직을 다시 수정해서 회귀테스트를 잘 통과했습니다. 테스트 코드가 있다는 것이 든든하게 느껴지더군요. 물론 아주 작은 코드입니다.

버그는 몇 개월 전에 발견했지만 누군가 보고 관심을 두고 있다는 것이 버그를 패치하게 된 큰 동기였습니다. 자극을 주신 분께 감사드립니다.

Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. tsday  댓글주소 수정/삭제 댓글쓰기 2009.03.20 17:00 신고

    저희 프로젝트에도 그런 분이 계셨으면~!!!^-^

  2. okgosu  댓글주소 수정/삭제 댓글쓰기 2009.03.21 01:12 신고

    오옷...오픈소스 프로젝트가 그래서 좋은 듯...
    부럽네...

    with okgosu

  3. lovedev  댓글주소 수정/삭제 댓글쓰기 2009.03.24 09:59

    형..잘 지내죠?
    복오싶어요 :)

고전적인 자바 클래스의 테스트는 main() 메소드에 값을 찍어보는 코드를 넣어서 콘솔에서 확인합니다. 이클립스에 익숙해진 덕에 JUnit에서 System.out.println() 집어 넣는 것은 초딩같은 습관이라고 생각을 "저만"했었습니다. 하지만, 찍어본다는 것 그리고 그것을 눈으로 확인하는 것은 굉장한 심리적 안정감을 주기는 합니다. 아직 assertEquals() 는 보이지 않는 신뢰가 필요하기 때문이죠.

httpunit의 테스트코드를 보니 재밌는 부분이 있었습니다. 상당히 많은 수의 테스트케이스에 main() 메소드가 있었고, 그 메인메소드는 JUnit을 기반으로 해당 테스트코드를 수행하도록 만들어주는 것이었습니다.


suite() 메소드를 inline 리팩토링하면 junit.textui.TestRunner.run( new TestSuite( EncodingTest.class ));  를 통해서 실행을 합니다. Java Application 으로 실행한 결과는 다음과 같습니다.

..............
Time: 3.813

OK (14 tests)

물론 이 클래스는 JUnit을 통해서도 실행됩니다.

다른 사람의 코드를 읽는 것, 프로그래머 소통의 시작이 아닐까 생각해봅니다.

참고로 HttpUnitTest 클래스의 상속구조입니다. ctrl+T 로 이클립스에서 볼 수 있습니다.


 

Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. iolo  댓글주소 수정/삭제 댓글쓰기 2008.11.03 22:33

    대부분의 assertXXX 메소드들은 첫번째 파라메터로 메시지를 줄 수 있지 않나요?
    제 경우엔 unit test 안에서만 System.out과 System.err을 쓴답니다^^;

    • 케누 kenu허광남  댓글주소 수정/삭제 2008.11.04 01:55 신고

      메시지가 성격이 다르죠. 보통은 파라미터에 값을 찍어보니까요.
      하긴 실제 코드에서 System.out , System.err 쓰는 것보다는 테스트코드에서 쓰는 게 훨씬 낫죠.

최근 TSS에 재밌는 기사가 하나 떴습니다. 테스트케이스가 공식적으로 개발과정에 포함되는지 아니면 비공식적으로 만들어지는지에 관한 조사였습니다. 2006년에 이어서 2년 후인 2008년 설문을 진행했습니다. 데이터는 다음과 같습니다.

Answers 2008 (2006)
Unit testing is not performed: 17% (13%)
Unit testing is informal: 40% (46%)
Unit tests cases are documented: 9% (11%)
Unit tests cases and their executions are documented: 14% (16%)
We use a Test Driven Development approach: 20% (14%)

Participants: 384 (2006: 460)
Ending date: October 2008 (February 2006)
Source: Methods & Tools (http://www.methodsandtools.com/)

TDD 접근법을 사용하는 것은 20%로 증가한 것에 비해 단위테스트에 대한 노력은 오히려 감소했습니다. 그리고 의외인 것은 외국에서도 아직 단위테스트가 보편적이지 않다는 것이었습니다.

오픈소스 프로젝트 하나를 앞서 살펴봤습니다. 여기에는 test라는 테스트케이스를 모아놓은 폴더가 있었습니다. 소스의 양은 얼마나 될까요. httpunit 이라는 단위테스트용 프로젝트이기 때문에 좀 더 많이 있을 거라 예상했습니다.
예상대로 제가 회사에서 만든 테스트코드들과는 비교할 수 없이 많더군요.

요기까지가 패키지 하나에 들어있는 소스 코드들입니다. 이 코드들을 테스트하는 테스트케이스는 다음과 같습니다.
그리 많은 것은 아니지만 대략 1/5 정도 테스트케이스의 클래스들이 있지않나 생각됩니다. 각 테스트케이스 내의 테스트 메소드들이 애플리케이션에 대한 코드 커버리지를 책임지겠지요.

테스트케이스를 모아놓은 것이 테스트스위트입니다. *Suite.java 로 찾아보면 다음과 같은 스위트들이 보입니다.

빌드 스크립트에서도 테스트 관련 배치작업을 찾을 수 있습니다.



test 타겟을 실행해보니 다음과 같은 결과가 나오는군요.
test:
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .....................................F....
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .....................................
     [java] Time: 22.656
     [java] There was 1 failure:
     [java] 1) testCookieAge(com.meterware.httpunit.cookies.CookieTest)junit.framework.AssertionFailedError: cookie2 expiration expected:<1223798608260> but was:<1112124642000>
     [java]  at com.meterware.httpunit.cookies.CookieTest.testCookieAge(CookieTest.java:202)
     ...
     [java]  at com.meterware.httpunit.HttpUnitSuite.main(HttpUnitSuite.java:49)
     [java] FAILURES!!!
     [java] Tests run: 775,  Failures: 1,  Errors: 0
BUILD SUCCESSFUL
Total time: 36 seconds

디버깅을 할 것은 아니지만, 이렇게 테스트케이스를 775가지 이상 갖고 있는 애플리케이션을 관리하는 것은 좀 더 수월하지 않을까 생각됩니다. 작업환경의 차이에서 발생하는 버그도 찾을 수 있고, 코드 변경으로 인한 틀어짐도 놓치지 않기 때문입니다.

읽어주셔서 감사합니다. 알찬 11월 되시길...
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. coolengineer  댓글주소 수정/삭제 댓글쓰기 2008.11.01 13:01

    http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx

    연관글을 따라가다 보니 재밌는 서베이가 있군요..

  2. 정의의소  댓글주소 수정/삭제 댓글쓰기 2008.11.01 13:11

    Test Case가 많은 Coverage를 가질 수록 코드 변경에 대한 자신감이 생기죠.. 최소한 이 Coverage에는 문제가 없다는... 그러나 Unit Test 를 단지 품질적인 측면만 보면 도입이 꺼려지지만 향후 생산성.. 파생되는 과제들(저희 회사의 경우)을 생각하면 나중에 다 많은 위력을 발휘하는 것 같습니다. - Unit Test 예찬론자... ^^:

앞서 오픈소스를 통해서 소스 저장소에 등록되는 디렉토리 구조를 살펴보았습니다. 그리고 프로젝트 소스를 일괄처리하는 build.xml 도 살짝 들여다 보았습니다. 이클립스 툴을 쓰면 다 되는 작업을 왜 Ant 빌드스크립트를 만들어야하는지 질문을 종종 들어봤습니다. 지속적인 통합 빌드 같이 주기적으로 반복되는 작업이나 단계가 복잡한 작업들은 빌드스크립트가 효과적입니다. 클릭클릭하는 일도 지겨울 때가 있거든요. 이클립스 작업의 자동화가 빌드 스크립트라고 생각하시면 될 것입니다.

지난 번 소스 가져오기(import) 이후로 소스의 빌드 경로를 잡아보려고 합니다. 로컬pc에서 컴파일되나 안되나 확인하는 것이죠. 소스가 패키지에 맞게 제자리에 있어야 할 것이고, 참조하는 jar파일의 경로도 함께 지정해줘야 합니다.

일단 이클립스 자바 프로젝트에서 소스 폴더를 추가합니다. 자바소스가 있는 폴더를 소스폴더라고 합니다. *.java 파일과 *.properties 파일들이 위치합니다. httpunit-1.7 아래 src 폴더가 바로 소스폴더입니다. 그리고 httpunit-1.7 아래 test 라는 곳도 소스 폴더로 추가합니다. src 아래 있는 클래스들을 테스트하는 테스트케이스들의 소스 폴더입니다.

자동 빌드가 일어나면서 에러가 무진장 일어납니다. jar 파일 연결이 안되서 그렇습니다.

왼쪽 패키지 익스플로러에서 프로젝트를 선택하고 Properties 창을 엽니다. 컨텍스트 메뉴에서 제일 아래 Properties 메뉴를 선택하면 됩니다. 단축키는 alt+Enter
Java Build Path 항목을 선택하고 Libraries 탭을 클릭합니다.

우측의 Add JARs... 버튼을 클릭해서 httpunit-1.7/jars 폴더의 *.jar 파일들을 선택합니다.

오호, 에러가 줄기는 했는데, 하나 남았네요. fnfe를 클릭해서 해당 소스를 열어보겠습니다. 흠, 겁을 상실했군요. 에~ 뭐 꼭 고친다는 뜻은 아닙니다. ^^;

소스를 살짝 보니 캐릭터셋 문제로 Roger Lindsj 이름 옆에 이상한 문자가 생긴 것 같네요. 그것 때문에 아랫줄 if라인이 주석 줄로 따라 올라온 듯 합니다.

if 앞에서 엔터로 줄바꿔주니 고쳐졌습니다. ^^; 잠시 우쭐~

Problems 탭에 에러는 싹 사라졌군요. Warnings는 살짝 봐주기로 하죠. ^^;

소스 폴더가 추가된 모습입니다.

작업공간은 에러 없는 코드로 관리되는 것이 개발자 심리에 좋다고 생각을 합니다. ^^;
Posted by 케누 kenu허광남

댓글을 달아 주세요

JUnit overview

java 2008. 6. 6. 23:19
6월 14일 발표할 내용의 일부입니다.
JUnit에 관한 책들은 많이 있습니다.

사용자 삽입 이미지


Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. zpzgsk  댓글주소 수정/삭제 댓글쓰기 2008.06.07 08:54

    정말 참가하고 싶었는데..;지방을 내려가는 관계로..ㅠㅠ
    아쉽네요...흑흑..

2008년 제9회 JCO 자바컨퍼런스에서 발표할 내용입니다.
대략의 줄거리는 다음과 같습니다.

레거시 코드 관리 전략
허광남
GS이숍

목차
레거시 코드란?
남이 짠 코드 빨리 알아보기
리팩토링 방법
테스트케이스라굽쇼?
인터페이스의 역할
복사할 것인가 상속할 것인가
기능 추가 방법
팀역량

수많은 방법론 중에
개발 방법론은 넘쳐나지만 유지보수에 관한 방법론은 어디에?
소프트웨어의 변경주기는 짧아지고 있다.
웹 비즈니스 애플리케이션은 기민하고 안정적으로 변경하는 것이 관리의 목표

레거시 코드
누군가 나에게 맡겨놓은 코드
자기가 직접 짜지 않은 누군가가 만들어 놓은 코드
많은 의문의 그림자와 중압감을 내포한 코드
얽히고 설킨, 아둔하게 짜놓은, 갈아엎고 싶지만   그럴 자신이 안 생기는 코드

레거시 코드
기능 하나 추가하려면 몇 일 밤 새게 만드는 코드
어느 누구도 선뜻 나서지 않는 코드
손을 대면 댈수록 나락으로 빠져버리는 코드
“차라리 날 죽여줘”라고 절규하게 만드는 코드
개선한다는 생각 자체가 몸서리처지는 코드

남이 짠 코드 빨리 알아보기
들여쓰기 (Indent)
Code Formatter
IDE 코드 네비게이션 기능
- F3
- ctrl+K
- 형광펜

남이 짠 코드 빨리 알아보기
팀원간 용어의 일관성
변수명, 함수명의 기능에 따른 변경
- buy() -> order()
남이 짠 코드 빨리 알아보기
프레임워크 사용시 명명규칙은 절대적
- /order/order.jsp
- /js/order/order.js
- /css/order/order.css
- OrderController.java
- OrderService.java
Open Resources(ctrl+shift+R)
Convention over Configuration

리팩토링 방법
Re + Factor + ing
- 소스(Factor)의 재(Re)구성(ing)
Martin Fowler
- Refactoring, 1999
- 외부 동작은 바꾸지 않으면서    내부 구조를 개선하는 방법

사연 많은 JSP 리팩토링
JSP 파일 하나에 11,000 라인의 코드
7년간 산전화수전화 다 겪은 전설의 코드
그와 결부된 사촌형제 코드들 각각 6,7천라인
1차 프로젝트 Java와 Javascript의 분리
자바스크립트의 분리
객체를 이용하기

자바스크립트의 분리
함수에 파라미터를 통해 전달

자바스크립트의 분리
JSP, Javascript 스파게티 분리
리팩토링 고려사항
소스의 증가
- 선별적 js로딩으로 효율화
보안이슈
- 권한 및 로직 유효성 체크는 이중화 또는 서버단으로 이동
JS캐쉬 이슈
- 자주 변경되는 내용은 jsp 안에서 처리
- js파일에 날짜별 버전
서버단과 클라이언트단 혼재된 로직
- 로직을 단순화하거나 jsp에서 처리하고 분리하지 않는다.

JSP,JS 분리 효과
서버단의 속도 개선효과
  1005.352223 -> 757.8979948

javascript를 잘 하는?전문가가??js 파일을 따로 최적화 작업할 수 있다. (관리 포인트의 전문성 확보)

js 변경시 기존 jsp를 수정하지 않아도 된다.

전체 소스의 가독성과 이해력 향상 (jsp, js)

인터페이스의 역할

복사할 것인가 상속할 것인가

테스트케이스라굽쇼?

Edit & Pray
        vs
Cover & Modify

Backup, Cover Fire!
Acrobatic Net

기능 추가 방법

팀역량
깨진 유리창 비유
코드리뷰, 짝 프로그래밍
- 버그의 최소화
- 코딩 공감대 확장
- 더 이상 겁나지 않는 휴일 전화
낳은 정보다는 기른 정

정리
레거시 코드는 비운의 코드입니다.
좋은 유모를 만나서 제대로 리팩토링하면 버그 없고, 건강하게 자랄 수 있습니다.
함께 키우려면 코드 리뷰, 짝 프로그래밍 등을 이용하면 됩니다.
잘 키운 레거시 코드 하나, 열 개발자 안 부럽다

참고자료
Working Effectively With Legacy Code, Michael C. Feathers, Prentice Hall, 2005
리팩토링, 마틴 파울러, 대청, 2002
소프트웨어 공학의 사실과 오해, Robert L. Glass, 인사이트, 2004
GS이숍 주문리팩토링 보고서, 김현,김현기, GS이숍, 2008

CCL


Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. lovedev  댓글주소 수정/삭제 댓글쓰기 2008.02.10 00:37 신고

    화이링입니다~!! Happy new year!!

  2. ologist  댓글주소 수정/삭제 댓글쓰기 2008.02.12 09:46

    재미있는 주제들 많이 하네요.

  3. redhawk  댓글주소 수정/삭제 댓글쓰기 2008.02.13 11:11

    따로 세미나 추진 부탁드립니다... ^^

  4. Progressio  댓글주소 수정/삭제 댓글쓰기 2008.04.11 11:23 신고

    전 그날 참석해요 ㅋㅋ
    무척이나 기대됩니다~ ㅎㅎ

  5. 아이리스818  댓글주소 수정/삭제 댓글쓰기 2008.04.24 09:14

    어제 정말로 유익한 강의였습니다 ^0^
    sm -> si 로 일하고 있는 저한테 공감 or 정말 필요한 내용들이었습니다

    담에 좋은 강의 있을때 또 쫓아갈께요 ~

Working Effectively With Legacy Code 내용 중에 테스트 가능한 프로그래밍 기법이 있는데, 재밌는 예제였습니다.
올바른 값을 가져오는지 테스트하기 위해서 탐침(probe)과도 같은 클래스를 만들어냅니다. 보통 메소드 안에서 흘러가는 흐름을 테스트 때문에 감지를 위한 것이지요.

package net.okjsp;
public class Car {
 public void 급정거(int level) {
  // ...
  System.out.println("버럭! "+level+"번");
  // ...
 }
}

저 부분을 테스트하기 위해서 코드를 분리합니다.

package net.okjsp;
public class Car {
 public void 급정거(int level) {
  // ...
  CarSpeaker speaker = new CarSpeaker();
  speaker.yell("버럭! "+level+"번");

  // ...
 }
}

CarSpeaker 는 내용을 감지하기 위한 미끼역할을 하게 됩니다.
package net.okjsp;
public class CarSpeaker {
 public void yell(String string) {
  System.out.println(string);
 }
}

테스트를 위해서 인터페이스를 뽑아냅니다.
package net.okjsp;
public class CarSpeaker implements Speaker {
 public void yell(String string) {
  System.out.println(string);
 }
}

package net.okjsp;
public interface Speaker {
 public void yell(String string);
}


그리고 speaker를 외부에서 지정할 수 있도록 필드로 만듭니다. 지정은 생성자에서 담당합니다.
package net.okjsp;
public class Car {
 private Speaker speaker;
 
 public Car(Speaker speaker) {
  this.speaker = speaker;
 }
 
 public void 급정거(int level) {
  // ...
  speaker.yell("버럭! "+level+"번");
  // ...
 }
}

이렇게 코드의 구성이 끝나면 감지를 전담하는 FakeSpeaker를 만들 수 있습니다.
package net.okjsp;
public class FakeSpeaker implements Speaker {
 String string;
 public void yell(String string) {
  this.string = string;
 }

 
 public String getString() {
  return string;
 }
}

테스트케이스는 다음과 같이 됩니다.
package net.okjsp;
import junit.framework.TestCase;
public class CarTest extends TestCase {
 public void test급정거() {
  FakeSpeaker speaker = new FakeSpeaker();
  Car car = new Car(speaker);
  car.급정거(1);
  assertEquals("버럭! 1번", speaker.getString());

 }
}


처음 코드 보다 설계는 복잡해졌지만, 테스트를 자동화하는 효과를 얻었습니다.
선택의 시간입니다. 그냥 System.out.println(">>>>"+level); 로 원본 클래스를 바꿔서 테스트할 것입니까, 아니면 테스트 케이스를 위해서 소스 코드의 설계를 바꿔서 하시겠습니까.

참고자료
Working Effectively With Legacy Code, Michael C. Features, Prentice Hall, P23-28
까오기님이 정리한 글
http://kkaok.pe.kr/servlet/KBoard?cmd=view&tableName=kmytip&flag=0&search=&findword=&gotoPage=1&seq=124
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. CoolGuy  댓글주소 수정/삭제 댓글쓰기 2007.12.12 09:11

    좋은글 감사합니다.
    따라해 봐야겠네요 ^^

  2. pungjoo  댓글주소 수정/삭제 댓글쓰기 2007.12.12 10:13

    good..!

  3. 보리  댓글주소 수정/삭제 댓글쓰기 2007.12.12 14:44

    좋은글 감사합니다.. ^^

  4. 하수개발  댓글주소 수정/삭제 댓글쓰기 2007.12.14 17:53

    다형성을 이용한 패턴적용은 만들어 진걸 보면 참 멋지고 이해가 잘되는데
    왜!!! 설계할때는 저리 안그려지는 건지..-_-;

  5. 하수개발  댓글주소 수정/삭제 댓글쓰기 2007.12.14 18:03

    아참 본문과는 상관 없는 질문 인데요.
    저번에 Refact 신촌에서 세미나 진행 하실때 작성 하셨던 ppt자료는 어디에 있는건가요?
    링크를 잃어 버려서요 ^^;.
    전에 작업 하시던거 보고 바로 유로파 깔아서 테스트 해보고 있는데 참고좀 하려구요.
    이야기 하시던거 적어 가지 못한게 몇가지 있어서 그거 보면서 하면 기억이 좀 날까 하네요.