2008년 9월 30일 화요일
스몰빌로 영어공부를 해보자!![Smallbill Season 08-01 Odyssey]-03
아이고 몇일쉬었더니 하기가 싫으네..
하지만 열심히 하자 아자아자아자!!
You missed a spot.
얼룩을 놓쳤군요
spot
1.a 반점(斑點), 얼룩점, 얼룩;(피부의) 점 2.a (특정) 장소, 지점 3. [보통 pl.] 《구어》 행락지, 관광지 4.【의학】 사마귀, 발진(發疹), 종기, 여드름 5.a (순번 등의) 순위, 위치;(방송의) 나올 차례
And the floors...They've lost their sheen
그리고 바닥은 광택을 잃었군요.
floor
1. 방바닥;마루;[pl.] 마루청, 마루 까는 널판 2. (건물의) 층 3.a (바다·굴 등의) 바닥, 밑바닥;(바닥처럼) 평평한 곳, 길바닥, 노면(路面);【항해】 화물창 속의 평평한 부분, 선상(船床);【조선】 늑판
sheen
sheen〔〕 n. 광휘, 광채;광택, 윤;현란한 의상;광택 있는 천 sheen·ful a. sheen·less a. sheen·ly ad
You're not getting lazy, are you?
당신 나태해진건 아니죠?
lazy
1. 게으른, 나태한(opp. industrious), 굼뜬 2. 졸음이 오게 하는, 나른한 3. 움직임[흐름]이 느린
I didn't realize Lex's secretarial staff could / spot a speck of dust from across the room.
나는 건너편 방의 얼룩의 먼지를 확인하는 비서가 있는줄 몰랐습니다.
secretarial
1. 비서(관)의, 서기의
realize
1. 실감하다, 깨닫다, (명확히) 이해하다, 분명히 파악하다 2. [종종 수동형으로] 실현하다, 달성하다, 실행하다 3. 여실히 보여주다, 실감나게 그리다, 사실적으로 묘사하다 4. <재산·수입·이익을> 얻다, 벌다 5. 현금으로...
speck
1. 작은 얼룩[흠], 작은 반점(斑點);(과실의) 멍, 작은 흠 2. 《비유》 오점 3. 잔 알맹이, 아주 작은 조각 《of》;[보통 부정문에서] 조금, 소량 《of》
I have been so looking forward to meeting the intrepid reporter Lois Lane.
나는 대담한 로이스래인 기자를 만나기를 기대하고있었어요.
look forward to
~을 기대[고대]하다, 기다리다
intrepid
in·trep·id〔〕 a. 무서움을 모르는, 용맹한, 대담한(fearless)(opp. timid) intrepid·ly ad. intrepid·ness n.
So, you like to play dress-up?
그런데 당신은 속이는걸(상황상 코스프레) 좋아하나보죠?
성장[분장]시키다; 보기[듣기] 좋게 하다, 꾸미다, 분식하다 《as, in》; …으로 가장하다 《as, in》; 정렬시키다
If you're not a secretary, who are you?
당신이 비서아니라면 누구죠?
Lex's 4:00 P.M. Booty call?
렉스가 오후4시에부르는 콜걸인가요?
booty call
Sex를 목적으로 하는 전화
I realize Mr. Luthor gave you quite a bit of journalistic rope, knowing you'd eventually hang yourself.
Me, on the other hand... I'm a little less patient.
나같은 경우는 참을성이 더 없어요.
on the other hand
다른 한편으로는, 반면에
patient
1. 인내심[참을성] 있는, 끈기 있는, 느긋한 《with》;참을 수 있는 《of, with》 2. 근기있게 일하는, 근면한;<연구 등이> 지속적인 3. 허용되는, 여지가 있는 《of》 1. 환자, 병자 2. 어떤 행위를 당하는 것[사람], 수동...
I'm not here as a reporter.
I'm here to find my
cousin, Chloe Sullivan.
I doubt she's hiding
under the furniture.
Lex had her arrested by the
Department of Domestic Security,
but the DDS claims to
have no record of her.
I want access to Lex's phone records
from the day he made the call.
I want that agent's name.
Mr. Luthor is a firm believer
in truth and justice, Miss Lane.
You can rest assured, if he had
your cousin arrested, she was guilty.
The only thing Chloe's been guilty of
is standing up for what she believes in.
Ms. Mercer?
Please escort Miss Lane out.
Yes, ma'am. / Hands off.
By the way, next time,
you might want to try microfiber.
- Works wonders.
- I'll keep that in mind.
//356
linux 패스워드변경, 사용자정보, 파일검색, 파일의 접근권한
* 사용자 삭제 : userdel user_name(디랙토리는 수동으로삭제해야함.)
* cat /var/log/messages | more
↑pipe line : 파이프라인을 기준으로 왼쪽 명령어의
실행결과를 오른쪽 명령어의 입력으로
넘겨주는 역할
가. 시스템에 접속한 사용자 정보 확인. (who, w, whoami, id)
1 - who : 현재 시스템에 로그인한 사용자의 정보를 간략하게 출력.
shell>who
shell>who 접속한 사용자 ID
2 - w : 현재 시스템에 로그인한 사용자의 정보를 상세히 출력
shell>w
3 - whoami - 현재 시스템에 로그인한 자신의 정보를 확인
shell>whoami or who am i
4 - id : 현재 시스템에 로그인한 자신의 id값 정보를 확인
shell>id *uid(user id) : 사용자id 500부터 시작 , gid(group id) : 그룹id
나. 터미널 장치
1 - tty : 콘솔모드를 통해 접속
2 - pts : 윈도우 환경에서 접속
다. 파일 검색 명령어(locate, whereis, which, find..)
1 - locate : 리눅스 시스템 내에 존재하는 모든 파일과 디렉토리의 목록을
데이터베이스 파일내에 저장시켜두고 그 안에서 찾고자하는 파일이나
디렉토리명을 검색
->사용법 : shell>locate 찾고자하는파일명
*locate 명령어는 인자로 들어오는 파일명을 포함하는 모든 파일들을 검색
*새로운 프로그램의 설치나 기존프로그램의 삭제등으로 인해 디비내용을
업데이트 시켜야 할 경우에는 updatedb 명령어를사용 (shell>updatedb)
2 - whereis : 인자로 들어오는 파일명을 PATH에 등록되어 있는 경로에서만
검색을 하여 출력함
->사용법 : shell>whereis 찾을 파일명 *PATH확인 : echo $PATH
*PATH를 관리하는 파일
ⅰ - glbal 설정파일(/etc/profile)
(전역,전체)
ⅱ - local 설정파일($HOME/.bash_profile)
(지역,자기자신)
3 - which : whereis 명령어와 동일 , 실행파일만 검색
4 - find : 검색하고자 하는 파일명을 자신이 알고 있는 조건들을 활용해서 해당 조건에
가장 부합되는 것들만 검색하고자 할 때 사용
->사용법 : shell>find 검색할디렉토리 -[검색조건] -print
->검색조건 : ①파일명을 기준으로 검색 : -name
②파일의 소유자를 기준으로 검색 : -user
③파일의 소유그룹을 기준으로 검색 : -group
④파일의 퍼미션을 기준으로 검색 : -perm
↑접근권한
->사용예 : ①/home 디렉토리 내의 어딘가에 abc123.ppt라는 파일이 있는데 어디
있는지를 모름 shell>find /home -name abc123.ppt -print
②/var 디렉토리내에 존재하는 파일들중 소유자가 hani로 되어있는
파일 검색 shell>find /var -user hani -print
라. 파일의 접근권 변경 (chmod : change mode) : 퍼미션 변경
-특정 파일이나 디렉토리의 접근권한 정보를 자신이 원하는 대로 변경
-사용법 : shell>chmod ±권한 파일명/디렉토리명
권한종류 : r(read) - 읽기권한
w(write) - 쓰기권한
x(execute) - 실행권한
*리눅스에서 파일이나 디렉토리의 권한 정보는 user, group, others 에 따라서
다르게 설정가능하다
-|rwx|r-x|r-x abc.txt
파일의 |use|gro|others
종류 | r|up |
-user : 해당 파일의 소유자의 접근권한을 의미
-group : 해당 파일의 소유그룹의 접근권한을 의미
-others : 해당 파일의 소유자와 소유그룹을 제외한 사용자의 접근권한을 의미
ex)rwxr-xr-x hani hani ```` abc.txt
①위의 abc.txt 파일의 접근권한중 소유자에게 쓰기권한을 뺏어버리고싶은 경우
=>shell>chmod u-w abc.txt
②소유그룹의 권한중에서 실행할 권한을 뺏어 버리고 others에게는 읽기권한을
뺏고 싶은 경우
=>shell>chmod g-x,o-r abc.txt
③소유자에게 쓰기권한 부여, 소유그룹에게 읽기 쓰기권한 부여, others에게
실행권한 뺏기
=>shell>chmod u+w,g+rw,o-x abc.txt
ex2)rw-r-xr-- hani hani abc.txt
①abc.txt 파일의 권한을 아래와 같이 변경
user : 읽고 쓰고 실행할권한
group : 읽고 쓰기권한만 가짐
others : 실행할 권한만 가짐
②①번과정을 거친후 다시 다음과 같이 변경
user : 읽고 쓰기권한만 가짐
group : 읽기권한만 가짐
others : 아무런 권한도 주지 않음
ex3)shell>chmod 654 abc.txt (8진수사용)
*특수 퍼미션 - 4000 값을 가지는 setuid(set user id) 파일
2000 값을 가지는 setgid(set group id) 파일
-setuid- 특정파일을 실행시킬때 실행되는 동안만큼은 해당 파일의 소유자 권한을
가지도록 작동하는 특수비트 파일
-setgid- 특정파일 실행시킬때 실행되는 동안만큼은 해당파일의 소유그룹권한을
가지도록 작동하는 특수비트 파일
-setuid가 설정된 파일은 소유자권한중 x권한이 setuid를 나타내는 s권한으로
변경됨
rwxr-xr-x abc.txt(일반파일)
rwsr-xr-x abc.txt(setuid가 설정된 파일) shell>chmod 4755 abc.txt
rwxr-sr-x abc.txt(setgid가 설정된 파일) shell>chmod 2755 abc.txt
* 백도어(Back door) : Backdoor 프로그램을 실행하면 root권한을 획득하수있는 프로그램
-setuid가 부여된 프로그램이 백도어일 가능성이 높음
Linux 시스템 정보.
우선 top 란 명령어를 치시면 전체적으로 나옵니다.
df 랑 명령어를 치시면 하드디스크 사용현황이 나옵니다.
cat /proc/cpuinfo 하시면 cpu 정보가
cat /proc/meminfo 하시면 메모리정보가
cat /proc/diskstats 하시면 디스크 정보가 나옵니다.
dmesg 하셔도 부팅할때 읽어들인 하드웨어 정보가 나옵니다.
/proc 디렉토리에서 알아내기
/proc/asound 사운드카드 정보
/proc/cpuinfo CPU의 정보 (CPU의 타입, 모델, 제조회사, 성능 등)
/proc/devices 현재 커널에 설정되어 있는 장치의 목록
/proc/dma 현재 사용 중인 DMA 채널 정보
/proc/filesystems 커널에 설정된 파일시스템 정보
/proc/ide IDE-인테페이스와 연결된 IDE-device들에 대한 정보
/proc/interrupts 현재 사용 중인 인터럽트 정보
/proc/ioports 현재 사용중인 I/O 포트 정보
/proc/loadavg 시스템의 평균부하량(load average)
/proc/meminfo 메모리 사용량 (실제 메모리, 가상 메모리)
/proc/modules 현재 사용 중인 커널 모듈
/proc/partitions 분할 영역(파티션) 정보
/proc/pci PCI(주변장치연결)-BUS와 PCI-카드, PCI-BUS를 사용하는 다른 device들에 관한 정보
/proc/scsi/scsi SCSI-인테페이스와 SCSI-device들에 대한 정보
/proc/stat 시스템의 상태에 관한 정보 (e.g. 부팅된 후 발생한 page fault 횟수)
/proc/uptime 시스템 동작 시간 ( 부팅후 시스템 사용 시간)
/proc/version 커널의 버전
/proc/filesystems 사용중인 파일시스템
/proc/swaps 스왑 파티션의 크기와 사용량
/proc/interrupts 사용중인 IRQ 정보
/proc/ioports 사용중인 Input/Output 포트 정보
/proc/modules 로드된 모든 모듈 정보 ('lsmod' 와 동일)
/proc/ide/ide0/hda/model 하드디스크의 모델명
/etc/redhat-release 레드햇 리눅스 배포본 확인
운영체제 정보
uname -a 운영체제의 호스트이름, 커널 버전과 릴리즈된 날찌와 프로세서(CPU)의 타입을 정보
uptime 부팅한 이후로 시스템의 사용된 시간과 로그인한 유저의 수, 시스템의 Load Average (시스템 부하량의 평균치) 등의 정보
runlevel 시스템의 현재 런레벨 정보
메모리 정보
free
more /proc/meminfo
디스크 정보
fdisk -l
df
df -lh
기타 시스템 정보
top
2008년 9월 25일 목요일
[스크랩] 미국 드라마로 영어공부하는 방법
미 국 드라마를 좋아하는 사람들이 많아지면서 드라마 속 배우들의 대사를 있는 그대로 더 생동감 있게 느끼고 싶어 원어로 듣고 이해해 보려고 하는 사람들도 늘어나고 있다. 지겹고 귀찮아서 기피하던 영어 공부를 자신이 좋아하는 드라마를 더 보기 위해서 자발적으로 즐기려는 사람들이 증가하고 있는 것이다. 영어 공부를 억지로 하는 게 아니라 좋아하는 드라마를 보면서 할 수 있으니 그야말로 ‘일석이조’다.
드라마 등 방송매체를 통해 영어 공부를 하는 것은 실제로 표현력과 발음 교정 등을 위한 공부에 있어서 효과적이다. 그렇다면 어떻게 해야 좀더 효과적으로 영어 공부를 할 수 있는지에 대해 정리해봤다.
우선 자막을 보지 않는 것이 중요하다. 내 용 이해 차원에서 보는 것이 아니라면 한글·영어 자막은 모두 보지 않는 것이 좋다. 자막에 의지하다 보면 소리에 집중하지 못하기 때문에 듣기 실력 증진에는 도움이 되지 않는다. 가능하다면 스크립트를 구해서 모르는 단어부터 쭉 정리를 한 후 시청하기 전 따로 한 번 읽어 보는 것도 좋다. 모르는 단어와 표현은 아무리 들어도 모를 수밖에 없기 때문에 미리 단어 공부를 해두는 것이 효과적이다.
시청할 때는 같은 부분을 여러 번 반복해서 보는 것보다는 우선 처음부터 끝까지 보는 것이 좋다. 이후 다시 반복해서 볼 때 부분적으로 못 알아 듣는 부분은 여러 번 반복 재생해서 보는 것이 필요하다. 그러나 여러 번 반복해서 들어도 잘 들리지 않는 경우가 비일비재하다. 그런 부분은 나중에 다시 스크립트를 확인해 보고 발음을 공부한다. 어디에 힘이 빠지고 어디에 연음이 되었는지 어떤 발음이 생략되었는지를 확인하는 작업을 거쳐야 한다. 그리고 그 부분을 그대로 따라 하며 반복한다. 다시 들으면 알아 들을 수 있게 된다.
이러한 작업을 여러 번 거치게 되면 드라마 한 편은 자막 없이 다 이해하며 볼 수 있게 된다. 물론 시간이 꽤 걸리는 과정들이지만 좋아하는 드라마를 보며 하는 공부이기 때문에 상대적으로 덜 지겹게 느껴지고 학습 효과는 기대 이상일 수 있으니 모든 단계를 철저히 지키며 시청하는 것이 중요하다.
영화를 통해 영어를 공부하는 방법도 이와 유사하다. 가족 코미디나 로맨틱 코미디 영화가 좋고 애니메이션 영화도 대체적으로 쉬운 표현이 많이 나오기 때문에 학습용으로 좋다. 액션 영화, 판타지 영화, 조폭 영화 등은 욕설이 난무하거나 표현 자체가 일상적이지 않은 것들이 많아서 학습용으로는 가급적 피해야 한다.
미드를 통해서 하는 가장 효과적인 영어 공부는 발음을 흉내 내는 것이다. 우선 스크립트를 구해서 여러 번 반복해서 읽는 것이 필요하다. 반복 청취하면서 발음과 억양을 확인한 후 소리에 맞춰가며 같이 읽는다. 대부분의 배우들은 (물론 다른억양을 쓰는 배우들도 있지만..) 일반 네이티브 스피커이기 때문에 이를 훈련하면 네이티브와 같은 자연스러움을 배울 수 있다. 스크립트를 따라 읽을 때 가장 신경 써야 하는 부분은 소리의 강약을 찾아내는 것이다. 전치사, 관사, 접속사의 경우 예외적인 경우를 제외하고는 최대한 힘을 빼고 읽어야 한다. 그 부분들만 신경 써도 훨씬 더 부드럽게 읽을 수 있다.
1.자신에게 맞는 미드를 선택하자
어학공부는 즐겨야 실력이 늡니다. 다른 사람의 추천에 의존해 미드를 선택하지 말고, 진정 자신이 재미있게 느끼는 미드를 선택하고 반복적으로 볼 각오를 합니다.
2.처음에는 무(無)자막으로 보자
처음으로 미드를 시청할 때는 즐겁고 편안한 기분으로 임합니다. 주인공의 정서, 전체적 분위기를 이해하려고 노력합니다. 갈등구조와 같은 큰 줄기만 이해해도 성공이라 할 수 있습니다.
3.두번째 볼 때는 영어자막과 함께 보자
무자막으로 드라마를 보며 전체적 구조를 파악한 뒤 영어 자막을 보면 독해가 한결 수월합니다. 전체 스토리에 견주어 봤을 때 "주인공이 이 상황에서 대충 이런이런 이야기를 하겠구나"라고 예상할 수 있거든요.
전체 문장의 이해도가 50% 미만이라면 장면당 끊어보기를 추천합니다. 모르는 단어는 사전을 찾아가며 '독해 연습'을 해봅니다. 결국 미드를 보는 주된 이유가 영어공부라면 한글 자막은 필요 없습니다.
4.듣기 실력 향상을 위해 받아 적어 보자
어 느 정도 영어 자막을 보며 독해가 쉽게 이루어지는 분들은 대사를 받아적는 연습을 합니다. 물론 자막은 꺼야겠죠? 가끔 너무 빨리 말하거나 정말 이해할 수 없는 대사가 있을 수도 있는데 이 때는 스트레스 받지 말고 과감히 그 부분을 건너뜁니다.
5.말하기 실력 향상을 위해 스스로 연기를 해보자
언 어란 것이 왜 있는 것입니까? 언어는 타인과 의사소통하기 위한 도구입니다. 한국인의 취약점인 스피킹을 극복하기 위해서는 지속적인 연습을 통해 자신감을 쌓는 수밖에 없습니다. 주인공의 대사를 계속 따라해 봅니다. 이땐 억양, 발음도 정확히 연습해야 됩니다.
그냥 밋밋하게 교과서 읽듯 따라하지 말고, 주인공의 감정을 최대한 살려 말해야 합니다. 이렇게 연습한 문장은 머리 속에 훨씬 더 오래남으며, 실제 외국인과 이야기할 때도 그들의 정서에 맞게끔 대화를 이끌어 나갈 수 있습니다.
6.일반 사전에서 찾을 없는 속어(slang)는 인터넷 상으로 검색하자
진정한 영어의 실력자 되기 위해서는 속어 공부도 매우 중요합니다. 이런 속어들이야 말로 우리의 영어 교과서 속 "I'm fine, thank you. And you?" 보다 10배, 100배 더 많이 쓰이기 때문입니다.
요 즘 고등학교 영어 교과서를 보면 외국인 사이에서는 별로 쓰이지도 않는 단어를 중요한 단어로 취급하는 반면, 일상생활에서 흔히 쓰이는 단어를 소홀히 다루는 경향이 있습니다. 이러한 부족분을 미드 시청으로 보완할 수 있는 것이죠. 저는 Urban Dictionary(urbandictionary.com)를 많이 이용합니다.
7.대본(script)을 활용해 마음에 드는 대사나 장면은 통째로 암기해 보자
한 두 장면에 해당하는 대본은 뽑아서 자투리 시간마다 반복해서 보는 습관을 길러봅니다.
처 음부터 너무 욕심내는 것은 좋지 않습니다. 이해 안 된다고 조바심 느낄 필요도 전혀 없습니다. 매일 조금씩 공부하다보면 어느새 탄탄한 영어실력을 갖추게 될 겁니다. 이런 말이 있다죠. "아는 자는 좋아하는 자만 못하고, 좋아하는 자는 즐기는 자만 못하다." 이는 정말 불변의 진리인 것 같습니다. 영어 공부로 스트레스 많이 쌓이셨다구요? 오늘부터 우리 모두 즐겨봅시다!
출처 : 웰컴영어 (http://cafe.daum.net/WelcomeEnglish)
또한 http://www.goldpitcher.co.kr/confluence/pages/viewpage.action?pageId=23330826
이곳에 가면 미드로 공부하기 좋은.. 정보가 있음.
2008년 9월 24일 수요일
스몰빌로 영어공부를 해보자!![Smallbill Season 08-01 Odyssey]-02
오늘로써 둘째날.. 그럼.. 다시 시작해보자..아자아자..
1. Trust me, Lex Luthor did not meet his end on some dwindling ice cap.
trust
1. 신임, 신뢰, 신용 《in》; 믿을 수 있는 사람[물건] 2. 희망, 기대, 확신 3.【상업】 신용, 외상 4. (신뢰·위탁에 대한) 책임, 의무 5. 위탁, 신탁;보관, 보호;감독; 위탁물
"믿다"는 뜻의 trust는 상대방의 말, 행동 등을 있는 그대로 받아들여 믿는다는 뜻
만일 누구에게 어떤 얘기를 했을 때 그 사람의 얘기를 사실 혹은 진심이라고 믿으면 I trust you. 혹은 I trust your story.라고 할 수 있겠죠.
Trust in
어떤 사물/사람의 존재 여부, 존재 가치, 성품, 인간성 등을 믿는다는 뜻
I trust in nothing but money. "난 돈만을 믿어.(돈이 최고라는 믿음을 가진다는 뜻)"
I trust in God. "난 하나님을 믿어.(신의 존재여부와 가치를 믿는다는 뜻)"
I trusted him very much. "난 그를 아주 신뢰했어.(그의 인간성과 됨됨이를 믿는다는 뜻)"
dwindle
1. 점차 감소하다, 점점 작아[적어]지다(⇒ decrease [유의어]) 2. 여위다;<명성 등이> 떨어지다;<품질이> 저하되다, 타락하다;<가치 따위가> 없어지다
icecap
1. (산꼭대기·극지 등의) 만년설, 빙원(cf. ICE SHEET)
end on
끝을 앞으로 하고[바싹 대고]; 해사】고물[이물]을 정면으로 향하여
나를 믿어요. 렉스 루더는 점점 줄어드는 만년설에서 끝(죽음)을 맞지 않았을것이에요.
2.Sonar's picking something up.
소나(수중음파탐지기)에 뭔가 잡혔습니다.
3. 6.4 meters deep.
6.4미터 밑에서요
4.What is it?
뭔가요?
5. Not sure, but based on the imaging,it could very well be human remains.
very well
확실히, 명백히; 좋아 ★ 때로 마지못한 동의[승낙]를 나타낸다
확실치 않아요. 하지만 이미지상으로는 사람의 흔적 같습니다.
6. There's a reason the cowboys won the west.Playing with bows and arrows can only get you so far
play with
① ~와 놀다 ② ~을 가볍게 다루다[보다] ③[생각 따위]를 막연히 품다 ④ ~와 말장난을 하다
so far
① 지금까지(는) ② 이[그] 점[정도]까지(는)
카우보이들이 서부에서 승리한 이유가있지. 활과 화살을 써서는 이길수 없었거든.
7. You two gonna keep stroking each other, or are we gonna go find Clark
keep stroke
템포를 맞춰 노를 젓다 인대 서로 칭찬하다 대화하다로 통할듯..
둘이 서로 대화만 하고 있을꺼야 아니면 클락을 찾을꺼야.
8. Well it looks like they found something in that trench.Check it out.
look like
① ~할 것 같다 ② ~인 것처럼 보이다
우물에서 뭔가 발견 한거 같아.확인해보자.
9. Oh, no.Clark, where are you?
안돼. 클락 어디있는거야?
2008년 9월 23일 화요일
스몰빌로 영어공부를 해보자!![Smallbill Season 08-01 Odyssey]-01
자 그럼 영문 자막을 가지고.. 공부를해보려고 한다...
자막가지고 공부하면 좋을것 같은이유는 정답이 있으니깐..^^
영문 자막이있으면 당연히 한글자막도 있다는..ㅋㅋ
자 그럼..이제 시작해보자..... 첫 시작이니깐. 첨에 나온것부터..^^
1. Previously on smasmallbill -나레이션
previously
pre·vi·ous·ly ad. 이전에;미리, 사전에 《to》
스몰빌 지난이야기.
2. And now the season premiere of "smallville." -나레이션
premiere
pre·miere [F=first〕
n.1 (연극의) 초일, 첫날, 초연;(영화의) 특별 개봉
2 주연 여배우━
vt. 초연을 하다━
vi.1 초연을 하다2 처음으로 주연을 하다━
a.1 최초의;주요한 a premiere showing 초연 2 주연 여배우의
and now
그런데, 그건 그렇고
그러면 스몰빌 시즌첫회를 시작합니다.
3.[Tess Mercer]Who's Regan.What have you been doing all this time, building snowmen?
all this time
Have you been running all this time?
여태까지 뛰고있었니?
얼마나 오랫동안 무엇이 얼마나 했나 often 이나 sometimes
리건이누구죠?여태 눈사람이라도 만들며 여기서 노닥거렸나요?
4.[Regan] Who do you think you are? This site is off limits.
A : How can you wear such a short skirt in this cold weather?
- 이 추운 날씨에 그렇게 짧은 치마를 입어요?B : Who do you think you are? What do you care what I wear?
- 어머, 별꼴이야. 남이야 뭘 입고 다니든 무슨 상관이래?
Expressions
How can you~
How can you say that? : 무슨 말씀을 그렇게 하세요?
How can you be so sure? : 어떻게 그렇게 확신하는 거지?
How can you do this to me? : 어떻게 나한테 이럴 수가 있어?
How can you eat at a time like this? : 이런 상황에 밥이 넘어가냐?
How can you go back on your word now? : 이제 와서 말을 뒤집으면 어떡해요?
off-limits
off-limits 《미》 a. 출입[사용] 금지의 ━ ad. 출입 금지 구역에서
당신은 뭐요? 이곳은 출입금지 구역입니다.
5.[Tess Mercer]Tess mercer. My access is unrestricted.
unrestricted
un·re·strict·ed〔〕 a. 제한[구속]이 없는, 자유로운 unrestricted·ly ad.
테스머서.나에겐 제한 따윈 없죠.
6.[Tess Mercer]Per lex's written instructions, I'm now the acting C.E.O. Of luthorcorp and all its subsidiaries
instruction
1. 교수, 교육(⇒ education [유의어]) 2. 교훈, 가르침 3. [pl.] 훈령, 지령, 명령, 지시;[pl.] (제품 등의) 사용 설명서 4. [pl.] 【법】 소송 위임장 5. 【컴퓨터】 명령(어)
subsidiary
1. 보조의, 보조적인 2. (…에) 종속적인, 보완(補完)하는 《to》 3. 보조금의[에 의한];딴 나라의 용병(傭兵)이 된 4. (과반수의 주(株)를 가진) 모회사(母會社)에 의하여 지탱되는 1. 보조자[물];부속물,
렉스의 지시로, 지금부터 내가 루더사와 모든계열사의 CEO가 됐어요
7.You're nothing but an obscure regional V.P. You actually believe you're qualified?
obscure
1.a <소리·모양 등이> 분명치 않은, 흐릿한(⇒ vague [유의어]) 2. 눈에 띄지 않는, 외진, 구석진;세상에 알려지지 않은, 미천한(humble) 3. (어두)컴컴한(dim), 침침한;흐린, 몽롱한(dim);어둠에 싸인 4. 거무튀튀한, 우중충한
V.P.
vice-president
1 [보통 V- P-] 《미》 부통령 ★ 미국 부통령은 대통령의 조언자이며 상원 의장을 겸함.
2 부총재;부회장;부총장;부은행장, 부사장
qualified
1. 자격 있는, 적격의, 적임의(competent, fit) 《for》;면허를 받은, 검정을 거친 2. 제한[한정]된, 조건부의;수정된 3. 《영·속어》 심한, 몹쓸(bloody, damned) 4. 훌륭한, 완벽한
actually
1. 실지로(in fact), 실제로 2. 현시점에서, 현재 3. (설마 하겠지만) 사실은, 실은;참으로, 정말로(really)
촌구석의 부사장은 아무것도 아니에요. 당신이 적임자라고 믿는건아니겠죠?
8.[Tess Mercer]Lex believes it...and that's all that matters.>
matter
1. a 물질, 물체(opp. spirit);성분, 요소(⇒ substance [유의어]) 2. (종기·상처의) 고름(pus) 3. 【철학】 질료(質料)(opp. form);【논리】 명제(命題)의 본질 4. a 제재(題材), 소재;(논문·책 등의) 내용(substance)
렉스는 믿었죠 그리고 그게 중요하고요
I want a complete inventory of everything you've found. footprints, snowmobile tracks, any sign of an escape.
inventory
1. (상품·재산 등의) 목록, 재고품 목록;표 《of》 2. 재고품(총액); 《미》 재고 조사;재고 조사 자산 3. 천연 자원 조사 일람표;(카운슬링용) 인물 조사 기록
당신이 찾은 모든 목록을 주세요,발자국, 스노우모빌자국,탈출의 흔적 모두
Kwang's 曰
음 previously 포함 3분가량했네.. T.T...
음.. 티비보면서.. 이거하다 와따가따하다보니 무지 오래걸렸네.. 에효 .. 낼은 또 얼마나 걸릴려나..
2008년 9월 18일 목요일
MFC CPPUnit 사용하기(2) - 소스코드 수정하기
파란색으로 수정할 부분을 나타내었다. 원본에 파란 부분을 추가 혹은 주석처리 하면 된다.
<1> CppUnitDemo.cpp 파일
// CppUnitDemo.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "CppUnitDemo.h"
#include "CppUnitDemoDlg.h"
//+++++++++++++++++++++++++ < 가 동작을안함.< CPPUNIT 요부분
// CppUnit: MFC TestRunner
#include cppunit/ui/mfc/TestRunner.h>
// CppUnit: TestFactoryRegistry to retreive the top test
// suite that contains all registered tests.
#include cppunit/extensions/TestFactoryRegistry.h>
// +++++++++++++++++++++++++
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp
BEGIN_MESSAGE_MAP(CCppUnitDemoApp, CWinApp)
//{{AFX_MSG_MAP(CCppUnitDemoApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp construction
CCppUnitDemoApp::CCppUnitDemoApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CCppUnitDemoApp object
CCppUnitDemoApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp initialization
BOOL CCppUnitDemoApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CCppUnitDemoDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
MFC CPPUnit 사용하기(1) - 설정하기
- Cppunit 을 다운로드 받는다.
<2> CPPUnit Libraries 빌드하기(Build CppUnit Libraries)
- $CPPUNIT\src\CppUnitLibraries.dsw 파일을 VC++ 을 통하여 연다.
- Build 메뉴에서 BatchBuild 메뉴를 선택 RebuildAll을 통해 빌드를 한다.
- 빌드가 완료되면 $CPPUNIT$\lib 폴더에 파일들이 나타난것을 볼수 있을것이다.
- 빌드하는 도중 에러가 발생할수 있을것이다. 이는 Unicode libraries 가 인스톨되지 않았을경우에 그렇수 있다.
- VC 설치시 Default 로 설치시 설치되지 않으니 Unicode libraries 를 설치하길 바란다.
<3> MFC exe 프로젝트 생성하기.(Create A New 'MFC AppWizard (exe)' Project)
1.File -> New 선택
2.Projects Tab 선택
3.MFC AppWizard (exe)' project 선택
4.Project name = 'CppUnitDemo' 입력> OK 누름
5. 'Dialog based' 선택> Next 누름
6. 'About box' 와 'ActiveX Controls' 체크 해제>Next 누름
7. 'MFC Standard' 와 Source comments 'Yes,please' 와 As a shared DLL' 선택> Finish 누름
<4> Setting 정보 설정하기.
CPPUnit 을 사용하기위해서 설정해야할 Settung 을 설명한다.
<4-1> RTTI 설정하기(Enable Run-Time Type Information (RTTI))
1. Project > Settings 선택
2. C/C++ tab 선택
3. Category dropbox 의 'C++ Language' 선택
4. 'Enable Run-Time Type Information (RTTI)' 체크
<4-2> Run-Time Library 사용
1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 Code Generation' 선택
4. 'Use run-time library:' dropbox 의 'Debug Multithreaded DLL' 선택
<4-3> Precompiled Headers 사용 해제
1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 'Precompiled Headers' 선택
4. 'Not using precompiled headers' 선택
<4-4> Preprocessor Include Path 설정하기.
1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 'Preprocessor' 선택
4. 'Additional include directories:' box 에 $CPPUNIT\include 를 입력
<4-5> CppUnit/TestRunner Libraries 사용 설정
1. Project > Settings 선택
2. Link tab 선택
3. Category 'dropbox 의 'General' 선택
4. 'Object/library modules:' box 에 $CPPUNIT$\lib\cppunit.lib 와$CPPUNIT\lib\testrunner.lib 입력
<5>. Include Path 수정
1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Include files' 선택
4. 'Directories' list 에 $CPPUNIT$\include 추가
<6> Library Path 수정
1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Library files' 선택
4. 'Directories' list 에 $CPPUNIT$\lib 추가
<7> Source Path 수정
1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Source files' 선택
4. 'Directories' list 에 $CPPUNIT\src\cppunit 추가
<8> Testrunner.dll Path 설정
빌드 하기전에 Testrunner.dll을 복사하기 귀찬차나~ 설정을 해주면 Build 전에 복사되는 부분이다.
1. Project -> Settings 선택
2. Post-build step tab 누름
3.'Post-build description' box 에 'Copying TestRunner DLL To Build Folder' 입력
4.'Post-build command(s)' list 에 "$CppUnit\lib\Testrunner.dll" $(OutDir)' 입력
설정을 마쳤으면 추가한 프로잭트에서 소스의 내용을 수정해야한다.
2008년 9월 12일 금요일
DECLARE_DYNCREATE()와 IMPLEMENT_DYNCREATE()
1.요약 MFC프로그램을 하면서 DECLARE_DYNCREATE()와 IMPLEMENT_DYNCREATE()라는 매크로를 자주보게 될 것입니다. 이 매크로가 무엇때문에 사용되는지 알아보겠습니다.
2.본문 DYNCREATE라는 단어서 볼 수 있듯이 동적생성에 관계있습니다. 이 매크로는 CObject를 선조로 하는 class에서 사용될 수 있으며 이 클래스가 동적으로 생성된다는 것을 알립니다. 위 매크로로 정의된 class를 동적으로 생성하기 위해서는 CRuntimeClass를 사용하는데 이 CRuntimeClass를 가져오기 위해서는 RUNTIME_CLASS(class)를 사용합니다. 보통 어떤 클래스를 동적으로 생성할려면 new연산자를 사용하고 delete연산자로 메모리에서 해제합니다. 그런데 왜 이 매크로를 사용할까 궁금해 질겁니다. 이유는 자기 스스로 파괴되는 객체에 대한 명확한 사용법을 제시하기 위해서 입니다. 자기 스스로 파괴되는 객체의 경우 정적으로 선언하여 사용하면 두번 메모리에서 제거되는 시도를 하기 때문에 메모리 참조가 일어나게됩니다. 그러므로 스스로 파괴되는 객체의 경우 반드시 동적으로 생성되어야하고 프로그래머가 정적으로 선언하는 실수를 방지하기 위해 생성자와 소멸자를 protected 멤버로 선언합니다. 생성자와 소멸자를 protected로 선언하면 다른 class에서 new나 delete로 객체를 생성할 수 없기 때문에 이러한 생성을 도와주는 class가 필요하게되는 것입니다. 이게 바로 CRuntimeClass입니다.
3.예제 위에 말이 좀 어려움감이 있는데 쉽게 예를들어보면 CFrameWnd나 CView같은 class들은 new로 생성할 수 없을 것입니다. 이러한 class를 생성할려면 다음과 같이하면 됩니다. CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CMyFrameWnd);
CMyFrameWnd *pFrame = (CMyFrameWnd*)pRuntimeClass->CreateObject();
pFrame->Create(...);
CreateObject()함수에서 내부적으로 new를 사용해서 객체를 생성하게되는데 이렇게 생성된 객체는 delete시킬 필요가 없을 겁니다. 그건 이 매크로로 작성된 class는 스스로 파괴되도록 설계되어 있을테니까요... 스스로 파괴되도록 설계되어있지 않다면 delete해야 됩니다. 위의 예제에서 보면 CFrameWnd나 CView를 동적으로 생성할 수 있기 때문에 Dialog base 프로그램에 CFrameWnd나 CView를 생성시킬 수 있습니다. 다음번에는 이 매크로를 사용하여 동적으로 생성되는 modeless dialog class를 만들어보겠습니다
JUnit 3.8에서 JUnit 4, TestNG 활용으로
JUnit 3.8을 활용한 방식의 코드를 JUnit 4를 활용하도록 바꾸기.JUnit 4는 JDK 5의 애노테이션(Annotation)을 기반으로 유연한 테스트를 할 수 있게 개선되었다.예제는 Agile Java(TM): Crafting Code with Test-Driven Development (Robert C. Martin Series)의 코드를 기준으로 한다. Agile Java의 한글 번역서의 제목은 '자바 프로그래밍'인데, 서적의 특색을 제목에서 제거해버린 점이 아쉽다.
'자바 프로그래밍' 책 정보 보기
자바 프로그래밍Jeff Langr 지음, 권오근 옮김/교학사(컴퓨터)JUnit 버전을 바꿀 때 가장 먼저 고려할 것은 JUnit 라이브러리 jar 파일을 바꿔야 한다는 점이다. 이클립스에 포함된 jar를 기준으로 하면 JUnit 3.8은 junit.jar, JUnit 4는 junit3.8.1로 작명되어 있다. 이클립스를 사용하지 않는다면 http://junit.org에서 올바른 jar를 다운 받아서 클래스패스에 추가하면 된다. 이클립스를 사용하는 경우라면 다양한 방법으로 라이브러리를 추가할 수 있다. TestNG 사용의 경우라면 http://testng.org에서 jar를 다운 받거나 이클립스 플러그인 설치를 하면 된다.1. 테스트 케이스(Test Case)의 생성
public class StudentTest extends junit.framework.TestCase {}위와 같이 Junit 3.8의 경우는 명시적으로 JUnit이 제공하는 TestCase를 상속해야 한다. JUnit이 사실상 표준화 되어 있는 의존성이 크게 문제되는 경우는 아니라고 할지라도 강한 의존성이 생긴다.
public class StudentTest {}JUnit4에서는 이 시점까지는 별달리 해줄 것은 없다. 엄밀하게 보면 일단 앞서의 코드는 클래스패스에 junit.jar가 없다면 컴파일이 불가능하지만, 후자는 아무런 문제가 생기지 않는다. 하지만, 언어적 개선을 논하려는 상황이 아니라면 실용적으로는 테스트 코드에서 이러한 이점이 대단한 것이라고 보기는 힘들다. TestNG의 경우도 JUnit4와 동일하다.2. 테스트 케이스(Test Case)의 생성
public class StudentTest extends junit.framework.TestCase { public void testCreate() { }}자바 프로그래밍에 따르면 JUnit 3.8을 기준으로 테스트 메소드가 가져야 할 제약은 네 가지가 있다:
public 접근 지정자가 필요하고
반환 값은 void
인자도 없고
메소드 이름은 반드시 소문자 'test'로 시작해야 한다.
확인해보면 모두 AssertionFailedError가 발생하는데, 첫번째 제약을 위반하면 Test method isn't public 메시지를 출력하고, 나머지 경우는 No tests found라는 메시지를 출력한다.
public class StudentTest {@Testpublic void testCreate() {}}
JUnit4의 경우는 마지막 제약이 @Test 애노테이션을 붙여줘야 하는 것으로 바뀐다.@Test를 붙이지 않으면 테스트 메소드로 인식하지 못해서 실행이 불가능 하고, 전자의 세 가지 제약을 위반하면 모두 java.lang.Exception이 발생한다. 출력되는 메시지는 순서대로 Method testCreate should be public, Method testCreate should be void, Method testCreate should have no parameters 이다.test라는 일종의 접두어(prefix)를 붙이지 않아도 되는 것이 장점이 될지는 어떻게 쓰느냐의 문제다. 오히려 Junit 3.8의 작명 제약이 좋은 작명 관습을 유도할 수도 있기 때문이다. 만일 테스트 문서화가 요구되는 조직에서는 아래와 같이 한글을 쓸 수도 있다는 점은 큰 도움이 될 수도 있다.
public class StudentTest {@Testpublic void 객체생성() {}}
한편, 테스트 하려는 행위/기능/메소드 등의 이름을 그대로 사용하는 것도 가독성을 높여줄 수 있다.
public class StudentTest {@Testpublic void creation() {}}
TestNG의 경우도 JUnit4와 동일한 코드로 작성된다. 다만 @Test 애노테이션이 다른 네임스페이스를 갖는다.
import org.junit.Test; // junit4import org.testng.annotations.Test; // testng
그러나, TestNG는 JUnit의 제약에 대해 좀 더 유연하다. 하나씩 살펴보자. public 제약에 대해서는 예외를 발생시키지 않지만, 테스트 메소드로 인식하지 않는다. void 반환은 없다. 인자를 받을 수 있으나, 인자를 제공하지 않고 실행하면 TestNGException 예외가 발생한다. 어떤 면으로는 상당한 유연성 제공이지만, 다른 측면으로 보면 자칫 Separation of concerns를 위반하기 쉽게 할 여지로 볼 수도 있다.
이클립스 단축키
JUnit: Alt+Shift+X, TTestNG: Alt+Shift+X, N (패키지 익스플로러에서는 작동하나, 편집기에서는 먹통)3. assertion 메소드 작성
public void testCreate() {
Student student = new Student("Jane Doe");String studentName = student.getName();
assertEquals("Jane Doe", studentName);
}위와 같은 assertion 메소드를 활용하는 코드는 JUnit 모두 동일하다. 다만, 3.8의 경우는 상속한 TestCase에 정의된 메소드를 사용하는 것이고, JUnit4의 경우에는 assertEquals 메소드를 정적으로 import하여 사용하는 것이다. 따라서, 아래와 같은 import 문이 필요하다.
import static org.junit.Assert.assertEquals; // JUnit 4import static org.testng.Assert.assertEquals; // TestNGTestNG의 경우도 거의 유사하다. 다만, 이클립스 3.2의 JUnit4 지원이 TestNG 플러그인 지원에 비해 우수하다. (Organize import/Quick Fix/Run as/TestCase 생성 마법사 등)JUnit4와 TestNG를 비교하는 글은 여럿 존재한다.
JUnit V TestNG 비교 글...
JUnit V TestNG: Managing external dependencies
TestNG가 JUnit4에 비해 갖는 장점을 다룬 글이다.
여러 모로 봤을 때 기능적으로는 확실히 TestNG가 우위에 있다.
학습 비용도 워낙에 낮다.
그런데 걸리는 점은
1. JUnit은 이클립스에 기본 내장되어 있다.
- TestNG는 별도로 플러그인을 깔아야 한다. 2,3 분 정도 걸리는 간단한 일이지만...
2. Spring의 Test 유틸 클래스는 JUnit 3.x를 기준으로 구동한다.
- Spring 유틸리티를 TestNG 기반으로 변경해야 한다.
사실, 그렇게까지 해가면서 TestNG를 써야 할 이유를 찾기가 쉽지 않다.
다른 관련글:
관련글:
JUnit 4.0
JUnit 4 overview
(추가)
대용량 사이트에선 TestNG가 더 적합하다는 견해의 아티클:
compared TestNG and JUnit 4그러나, 꼭 둘을 대립적으로만 볼 필요는 없다. '블루오션'과 같은 책들을 보면서 태도를 바꾸게 되었는데..
블루오션 정보 보기
블루 오션 전략김위찬 외 지음, 강혜구 옮김/교보문고둘을 섞어서 사용할 수 있는가? 그렇다. 다만, 일관성 유지를 위해서 예전에 IDE 하드 디스크를 사용할 때 Mater/Slave와 같이 주가 되는 것을 정해주는 것이 좋다.
@org.testng.annotations.Testpublic void Create() {
Student student = new Student("Jane Doe");String studentName = student.getName();
org.junit.Assert.assertEquals("Jane Doe", studentName);
}위의 코드는 전혀 문제 없이 수행된다. 마찬가지로 아래 코드도 그렇다.
@org.junit.Testpublic void testCreate() {
Student student = new Student("Jane Doe");String studentName = student.getName();
org.testng.Assert.assertEquals("Jane Doe", studentName);
}물론, 위의 코드는 단순한 실험에 지나지 않고, 실효성이 있는지는 더 살펴볼 일이다.4. TestSuite 작성
public class AllTests { public static junit.framework.TestSuite suite() { junit.framework.TestSuite suite = new junit.framework.TestSuite(); suite.addTestSuite(StudentTest.class); suite.addTestSuite(CourseSessionTest.class); return suite; }}테스트 케이스를 스위트에 추가하는 방법이 자바 코드에서 애노테이션으로 바뀐 것이 가장 큰 특징이다.
@RunWith(Suite.class)@SuiteClasses({StudentTest.class, CourseSessionTest.class})public class AllTests {}
5. setUp 메소드 작성
public void setUp() { session = new CourseSession("ENGL", "101");}JUnit 3.8 에서는 역시 TestCase의 메소드를 상속 받는다.
@Beforepublic void setUp() {session = new CourseSession("ENGL", "101");}tearDown의 경우는 예상할 수 있겠지만 @After 애노테이션을 사용한다.setUp과 teardown의 진정한 개선점은 오버라이딩 대신에 애노테이션을 썼다는 점 보다는복수의 setUp/teardown이 가능해진 것이다.An early look at JUnit 4의 예제 코드를 빌려 오면
@Beforeprotected void findTestDataDirectory() {inputDir = new File("data");inputDir = new File(inputDir, "xslt");inputDir = new File(inputDir, "input");}
@Beforeprotected void redirectStderr() {System.setErr(new PrintStream(new ByteArrayOutputStream()));}자원 소모가 많은 작업을 위한 @BeforeClass/@AfterClass 등도 추가되었다.그 외에 몇 가지 JUnit 3.8 보다 JUnit4에서 개선된 점을 덧붙여본다.6. 예외 테스트의 개선 (예제 코드 출처: An early look at JUnit 4)
// JUnit 3.8 public void testDivisionByZero() { try { int n = 2 / 0; fail("Divided by zero!"); } catch (ArithmeticException success) { assertNotNull(success.getMessage()); }}// JUnit 4@Test(expected=ArithmeticException.class) public void divideByZero() { int n = 2 / 0;}TestNG와 거의 유사한 방식이다. try - catch 문은 사용할 필요가 없어 매우 간결하다.7. 수행 시간 측정 테스트
@Test(timeout = 2000)public void remoteBaseRelativeResolutionWithDirectory() throws IOException, ParsingException {builder.build("http://www.ibiblio.org/xml");}역시, TestNG를 이용하면 예전부터 사용할 수 있었던 방법이다. JUnit 3.8 시절에 이런 류의 테스트를 위해 JUnitPerf가 등장했다.8. 배열을 비교하는 asserttEquals 메소드 추가public static void assertEquals(Object[] expected, Object[] actual)기타@Ignore를 사용하면 특정 테스트를 실행 없이 넘길(skip) 수 있다.
2008년 9월 11일 목요일
Java 어노테이션(Annotation)에 관한 간략한 소개
어노테이션은 @어노테이션의 형태를 사용하고 클래스, 필드, 메소드 등과 같은 프로그램의 선언부에 적용할 수 있다. 어노테이션은 가장 처음으로 그리고 종종(관례상) 그 줄에 나타나며 임의의 인수를 포함할 수 있다:
@Author("MyName")
class myClass() { }
혹은
@SuppressWarnings("unchecked")
void MyMethod() { }
여러분만의 어노테이션을 정의하는 것은 여기에 기술되지 않을 고급기법에 속하지만, 모든 자바 프로그래머들이 알아야 하는 3개의 내장 어노테이션이 있다: @Deprecated, @Override, 그리고 @SuppressWarnings가 그것이다. 다음 예제들은 메소드에 적용된 모든 세 가지 타입의 어노테이션을 보여준다:
import java.util.List;
class Food {}
class Hay extends Food {}
class Animal {
Food getPreferredFood() {
return null;
}
/**
* @deprecated document why the method was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
class Horse extends Animal {
Horse() {
return;
}
@Override
Hay getPreferredFood() {
return new Hay();
}
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
Animal.deprecateMethod(); //deprecation warning - suppressed
}
}
@Deprecated
@Deprecated 어노테이션은 표시된 메소드가 더 이상 사용되지 말아야 함을 가리킨다. 컴파일러는 프로그램이 비추천(deprecated) 메소드나 클래스 혹은 변수를 사용할 때마다 경고를 발생시킨다. 한 요소가 비추천되면 그것은 앞의 예제에 나타나 있는 것처럼 해당되는 @deprecated 태그를 사용하여 문서화 되어야 한다. 태그는 소문자 ‘d’로 시작하며 어노테이션은 대문자 ‘D’로 시작함을 주의하라. 일반적으로 여러분은 비추천 메소드의 사용을 피해야 하며 그것 대신 무엇을 사용해야 하는지를 확인해야 한다.
@Override
@Override 어노테이션은 요소가 상위 클래스에서 선언된 한 요소를 오버라이드 할 것임을 컴파일러에게 알려준다. 앞의 예제에서는 오버라이드 어노테이션이 Horse 클래스의 getPreferredFood 메소드가 Animal 클래스에 있는 동일한 메소드를 오버라이드하고 있음을 가리키는 데 사용되었다. @Override로 표시된 한 메소드가 상위 클래스에 있는 메소드를 오버라이드하는 데 실패할 경우 컴파일러는 에러를 발생시킨다.
메소드를 오버라이드 할 때 이 어노테이션을 사용하도록 요구되는 것은 아니기 때문에 특히 메소드가 오버라이드된 메소드의 리턴 타입의 하위 타입을 리턴할 때 명시적으로 그것을 드러내도록 요구하는 것이 유용할 수 있다. 이러한 관례는 “공변 리턴 타입(covariant return type)”이라 불리는데, 이전의 Food 인스턴스를 리턴하는 Animal.getPreferredFood 예제에서 사용되었다. Horse.getPreferredFood (Horse은 Animal의 하위클래스)는 Hay의 인스턴스를 리턴한다. 좀 더 자세한 정보를 위해서는 Overriding and Hiding Methods를 참조하라.
@SuppressWarnings
@SuppressWarnings 어노테이션은 컴파일러가 다르게 발생될 특정 경고를 억제하도록 해준다. 이전의 예제에서 useDeprecatedMethod는 Animal의 비추천 메소드를 호출한다. 보통 컴파일러는 경고를 발생시킬테지만, 이 경우에는 그것이 억제된다.
모든 컴파일러 경고는 한 종류에 속한다. 자바 언어 명세(Java Language Specification)는 “비추천(deprecation)”과 “비확인(unchecked)”의 두 가지 종류를 나열한다. “비확인” 경고는 제네릭이 나오기 전에 작성된 레거시 코드와 인터페이싱할 경우에 발생할 수 있다. 하나 이상의 경고 종류를 억제하려면 다음의 문법을 사용하라.
@SuppressWarnings({"unchecked", "deprecation"})
지원되는 경고 종류들의 목록을 보려면 컴파일러 문서를 확인하라.
어노테이션을 좀 더 고급스럽게 사용하는 것에는 자바 프로그램을 읽어 그것의 어노테이션을 처리할 수 있는 프로그램을 작성하는 것이 포함되어 있다. 이 작업을 돕기 위해, JDK 5.0 릴리즈에는 apt라 불리는 어노테이션 처리도구(annotation processing tool)가 포함되어 있다. 다음의 JDK 릴리즈(코드네임 머스탱)에는 apt 기능이 자바 컴파일러의 표준 요소가 될 것이다. 좀 더 자세한 정보를 보려면 Getting Started with the Annotation Processing Tool 를 참조하라. 머스탱의 진척사항에 관한 더 자세한 정보를 원한다면 Language Model API 와 JSR 269: Pluggable Annotation Processing API 을 참고하라.
JUnit 관련 링크
일단 선의 튜토리얼 공식 링크http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html예제는 업ㅂ어!
를 외치던 선 & 자바인줄 알았는데 이런 튜토리얼이 존재하다니 감동했다.
한글로 된 'Java 어노테이션(Annotation)에 관한 간략한 소개'http://decoder.tistory.com/21그리
Java APIs 문서 한글화 된곳
http://xrath.com/javase/ko/6/docs/ko/api/index.html은 자바6고
http://www.javastudy.co.kr/api/api1.5/index.html여기는 5다
2008년 9월 9일 화요일
CUTE Test
위키피디아에 C++ 용 Unit Testing 툴이 잘 비교되어 나와 있는데, 이중에서 Eclipse 플러그인을 지원하면서 사용이 비교적 간단한 CUTE (C++ Unit Testing Easier)를 이용해 보도록 한다.
1. Boost 설치
CUTE를 사용하기 위해서는 Boost 라는 C++ 공개 라이브러리를 먼저 설치해줘야 한다.
Download 페이지에서 boost_1_35_0.zip을 받아 폴더에 압축을 푼다.
* 공용 헤더 파일과 라이브러리 파일을 위해 Eclipse의 workspace 아래에 include 및 lib 폴더를 만들어 두자. 앞의 예에서 D:\workspace-cpp를 사용했으므로, D:\workspace-cpp\include, D:\workspace-cpp\lib 폴더를 각각 만들어 사용하도록 하겠다.
boost_1_35_0 폴더 아래에 boost, doc, libs 등의 폴더가 보일 것이다. 이 중 헤더 파일이 들어 있는 boost 폴더를 자신의 workspace의 include 아래로 복사한다. i.e. D:\workspace-cpp\include\boost
2. CUTE 플러그인 설치
Eclipse 메뉴의 Help -> Software Updates -> Find and Install… 을 클릭한다.
CUTE 플러그인을 처음 설치하는 것이므로, Search for new features to install 을 선택하고 Next를 클릭한다.
New Remote Site…를 클릭하고 Name에는 CUTE, URL에는 http://ifs.hsr.ch/cute/updatesite 라고 입력한 후 OK를 클릭한다.
화면에 CUTE 노드가 새로 생겼을 것이다. 체크되어 있는지 확인 후 Finish를 클릭한다.
Cute Launcher 1.3.0을 선택하고 Next를 클릭한다.
License 화면이 나오면 동의한 후 Next 후 Finish. 설치 중 Verification warning이 나오는데 Install All을 선택한다.
설치가 끝나면 Eclipse를 다시 시작하겠냐고 묻는다. Yes를 클릭한다.
3. HelloWorldTest
Eclipse가 다시 시작되면 메뉴의 Window -> Show View -> Other… 를 클릭한다. 제대로 설치되었다면 CUTE Results 라는 View가 보일 것이다. 이 View는 Unit Test 결과를 그래프로 보여준다. 선택한 뒤 OK를 클릭하여 해당 View를 화면에 추가하자.
이제 메뉴의 New -> C++ Project를 클릭해보자. 기존의 옵션 외에 CUTE 용 프로젝트 타입이 세 가지 더 생긴 것이 보일 것이다. Project 명에 HelloWorldTest 라고 입력하고 Cute Project를 선택한 후 Finish를 클릭한다.
새로 생성된 HelloWorldTest 프로젝트를 빌드하기 위해서는 먼저 앞에서 설치한 Boost 헤더파일을 Include path에 포함시켜야 한다. 프로젝트를 선택한 후 메뉴의 Project -> Properties를 클릭하면 설정 화면이 나타난다. C/C++ Build -> Settings 화면에서 GCC C++ Compiler의 Directories를 클릭한다.
여기에 앞에서 설정한 공용 Include 폴더를 추가하자.
아이콘을 클릭한 뒤, File System… 에서 폴더 경로 (i.e. D:\workspace-cpp\include)를 선택하고 OK를 누른다. 다시 OK를 클릭하여 설정을 저장한다.
이제 프로젝트를 빌드해보자. HelloWorldTest 프로젝트를 선택한 뒤 Project -> Build Project 를 클릭한다. 앞의 설정이 제대로 되었다면 에러 없이 컴파일과 빌드가 될 것이다.
빌드가 완료되면 Debug 폴더 아래 HelloWorldTest.exe가 생성된다. 이 파일을 선택한 뒤 오른쪽 마우스 버튼을 클릭하여 나타난 서브 메뉴에서 Run As -> CUTE Test를 선택한다.
테스트 결과가 Console과 Cute Results 창에 나타난다. CUTE Project 로 생성된 소스 코드는 기본적으로 실패하는 테스트를 담고 있기 때문에 실행 결과는 다음과 같이 붉은색으로 나타날 것이다.
이제 이 테스트를 성공하도록 바꿔보자. 자동으로 생성된 Test.cpp에는 다음과 같은 테스트 케이스가 하나 들어 있는데, ASSERTM() 은 두번째 인자의 결과값을 체크하여 성공과 실패 여부를 확인하는 매크로이다. 두번째 인자값이 false이므로 이 테스트는 무조건 실패하도록 되어 있다.
이 코드를 테스트가 성공하도록 다음과 같이 바꿔 보자.
다시 프로젝트를 빌드한 뒤 다시 Cute Test로 실행시키면, 테스트가 성공했음을 알리는 초록색 막대가 나타날 것이다.
이상으로 Eclipse CDT 환경에서 Unit Testing을 위한 준비를 마쳤다.
2008년 9월 8일 월요일
MFC에서 CPPUinit 테스트 케이스 추가하기
0. Project Settings
Project Settings -> C/C++ -> C++ Language -> Enable Run-Time Type Information(RTTI) 체크
Project Settings -> Link -> Object/library modules -> cppunitd.lib testrunnerd.lib 추가( Debug모드일때 파일들 )
testrunnerd.dll 파일을 프로젝트 폴더로 복사한다.
1. XXXApp.cpp 파일에 아래 내용을 추가한다.
#include <msvc6/testrunner/testrunner.h>
#include <cppunit/extensions/testfactoryregistry.h>
...
BOOL CHostAppApp::InitInstance()
{
TestRunner runner;
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
runner.run();
...
return FALSE;
}
2. TestCase h파일을 만들어서 다음과 같은 방식으로 작성한다.( ExampleTestCase.h )
#ifndef TESTBLACKSCHOLES_H_
#define TESTBLACKSCHOLES_H_
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
class TestBlackScholes : public CppUnit::TestCase
{
CPPUNIT_TEST_SUITE(TestBlackScholes);
CPPUNIT_TEST(TestBS);
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
void tearDown();
void TestBS();
};
#endif
3. TestCase cpp파일을 만들어서 다음과 같은 방식으로 작성한다.( ExampleTestCase.cpp )
#include "StdAfx.h"
#include "TestBlackScholes.h"
CPPUNIT_TEST_SUITE_REGISTRATION(TestBlackScholes);
void TestBlackScholes::setUp()
{
}
void TestBlackScholes::tearDown()
{
}
void TestBlackScholes::TestBS()
{
CPPUNIT_ASSERT_EQUAL( 10, 10 );
}
이제 빌드하고 실행하면 아래와 같은 TestRunner가 먼저 실행되고 나서 실제 Application이 실행된다.
[출처]
MFC에서 CppUnit으로 TestCase만들기|작성자
이쓩
원본 위치 <http://blog.naver.com/PostView.nhn?blogId=gmgm21&logNo=80043354631&from=search>
2008년 9월 7일 일요일
Junit 사용법[스크랩]
class 화일을 테스트를 할때.. 반드시 main() 를 만들어 겉으로만 테스트 하는것은
테스트라 보기 어렵다고 한다.
대형 프로젝트의 경우 시나리오가 나오고 로직이 나오면
로직의 문제를 테스트하는것을 테스트라 말 할 수 있다고 한다.
JUnit는 이렇게 보이지 않고 숨겨진 단위 테스트를 좀더 수면 위로 끌어올리고
정형화시켜주는 단위 테스트 프레임워크의 자바 구현물이며
1.4버젼에서 추가된 assertXXX를 사용하여 Test 한다.
-- Eclipse에서 사용법
저도 잘 모르지만... 다른것보단 간단하더라구요..
Eclipse 2.1 버전 이상에서는 Junit을 기본으로 사용하고 있어서...
밑에 읽어보시면 알겠지만. .. classpath를 따로 잡아주지 않아도.
Eclipse 에서는 default 여서 그냥 사용하시면 됩니다.
확인법 : Window->Preferences->Jave->JUnit 모든것을 체크 해주면 됨..
File->NEW->project에서 TestCase, TestSuite가 없으신 분은
Window ->Customize Perspective->File>New에서 찾아서 체크만 해주면 ok
실행은 Run->JUnit
실행하면 왼쪽에 JUnit 창이 뜰것인데.
그쪽에 아무것도 안뜨고 초록 막대가 보이면 Test 성공
에러나면 빨간 막대.. Junit 창에 에러가 쫙~~ 뜹니다.
위 방법을 모르겠거나 잘 되지 않으면,
=====================================================
Sample 프로젝트에 마우스를 대고 오른쪽을 클릭하여 컨텍스트 메뉴 맨 밑에 있는 Properties 를 선택한다.
Java Build Path를 선택한다.
Libraries 탭을 선택한다.
Add Variable 버튼을 클릭한다.
New 버튼을 클릭하고 변수 이름에 JUNIT_LIB을 입력한다.
그 변수를 편집하고 C:\eclipse\plugins\org.junit_3.8.1 (JUnit은 Eclipse plug-in이다)에 지정한다.
Sample 프로젝트에 src 폴더를 선택한다.
구현 경로에 JUnit을 넣었다. 외부 JAR를 이 경로에 직접 추가할 수 있었지만 다른 머신의 작업공간을 설정할 때에는 변수를 사용하는 것이 더 쉽다. 다음은 테스트 클래스를 작성하는 과정이다:
툴바의 Create a Java Class 버튼 오른편에 드롭다운 화살표를 클릭하고 Test Case를 선택한다.
테스트 이름으로 TC_Account를 선택한다.
setUp()과 tearDown() 체크 박스를 선택한다.
Finish를 클릭한다.
====================================================
밑에 다른 사이트에 퍼온건데 정리가 잘 되어 있더라구요.. 도움이 되실꺼예요.
JUnit개요
test case는 일련의 테스트를 실행하기 위한 장치
(fixture, 기능, 원시코드경로, 멤버 함수간의 상호작용)을 정의하는 것이다.
전형적으로 작성한 모든 클래스는 테스트 케이스를 가지고 있어야 한다.
테스트 Fixture는 테스트 수행에 필요한 자원
즉, 프리미티브 변수와 오브젝트를 제공하는 것
동일하거나 유사한 오브젝트에 대한 테스트가 두개 이상 있을 경우
테스트 환경을 셋업하기 위한 코드를 각 테스트에서 꺼내서 하나의 메소드에 넣어둔다.
동일하거나 유사한 환경에서 실행되는 테스트를 위한 설정을 테스트 Fixture라고 한다.
테스트 스위트(test suite) 는 관련된 테스트 케이스를 모아 놓은 것을 말한다.
=====================================================
<<출처 : http://wiki.tdd.or.kr >>
Unit Test
JUnit의 사용법을 말하기 전에 도대체 테스팅이란 무엇인지
그 의미에 대해서 짚고 넘어가자.
테스트는 말 그대로 우리가 만든 프로그램이 원하는 대로 동작하는지
알아보는 것에 불과하다. 그렇다면 우리가 원하는 대로 동작하는지
알 수 있는 방법은 무엇이 있을까?
그것은 단 한가지이다.
기대값과 결과값을 비교한다.
우리가 기대하던 결과를 프로그램이 출력하는지를 살펴 보는것이
테스팅의 기본이고 끝이다.
유닛 테스트는 이러한 기대값과 결과값을 비교한다.
TDD는 이러한 유닛 테스트를 기본으로 한다.
다만 테스트의 범위가 매우 작은것이 그 특징이라 할 수 있다.
비행기를 만들고 비행기가 날아가는 것을 보는것도 테스팅이지만
비행기의 부속하나하나 역시 테스트 하지 않던가?
TDD는 비행기를 테스트 하는것이 아니라 비행기의 부속 하나하나를
꼼꼼하게 테스트한다. 그리고 100% 그 테스트를 통과해야 한다.
JUnit 사용법
http://www.junit.org 에서 junit.jar파일을 구하고
자바 클래스 패쓰에 다운 받은 jar파일을 설정한다.
그리고 에디터로 다음의 코드를 작성해 보자.
package tddbook;
import junit.framework.*;
import junit.textui.*;
public class JUnitTutorialTest extends TestCase {
public JUnitTutorialTest( String arg0 ) {
super( arg0 );
}
public void testNumber() {
int expected = 10;
assertEquals( expected, 2*5 );
}
public static void main( String[] args ) {
TestRunner.run( JUnitTutorialTest.class );
}
}
이것이 바로 JUnit을 이용한 테스트 코드이다.
TestCase를 extends해서 testXXX메써드들을 테스트하고 있다.
위와 같은 모습의 코드가 전형적인 Junit을 이용한 코드의 틀이라고 할 수 있겠다.
위의 testNumber가 실제적인 테스트를 행하는 메써드이며,
이렇게 메써드명이 test로 시작하는 메써드들은 원하는 만큼 많이 만들어서 쓸 수가 있다.
그렇다면 testNumber메써드를 보자. assertEquals라는 TestCase를 통해서
extend받은 메써드를 이용하여 2*5의 결과값이 기대한 값 (expected)와
일치하는지를 비교한다.
위의 코드를 실행하면 다음과 같은 결과를 보게 된다.
.
Time: 0.01
OK (1 test)
자세히 보면 제일 윗줄에 점(.)이 하나 보이는데 이것은 test로 시작하는
메써드들의 갯수 즉, 테스트의 갯수를 의미한다.
다음의 Time은 테스트하는데 소요된 시간을 말하며 OK는 1개의 테스트가
성공했음을 알린다.
이렇듯 text로 그 결과를 보여주는 까닭은 우리가 main메써드에서
junit.textui.TestRunner을 사용했기 때문이며
이 외에도 awt나 swing을 이용한 visual한 결과를 볼 수도 있다.
see also : JunitGui - awt, swing을 이용한 유닛 테스팅
이번에는 테스트가 실패할 경우 어떻게 보여지는지 살펴보도록 하자.
다음과 같이 위의 코드를 수정해 보자.
package tddbook;
import junit.framework.TestCase;
public class JUnitTutorialTest extends TestCase {
public JUnitTutorialTest(String arg0) {
super(arg0);
}
public void testNumber() {
int expected = 10;
assertEquals(expected, 2 * 5);
}
public void testFailMessage() {
int expected = 10;
assertEquals(expected, 3*5);
}
public static void main(String args[]) {
junit.textui.TestRunner.run(JUnitTutorialTest.class);
}
}
testFailMessage라는 메써드를 추가했다.
코드를 보면 expected는 10이지만 3*5의 값은 10일리 없다.
위의 테스트 코드를 실행하면 다음과 같은 결과를 보게 된다.
..F
Time: 0.01
There was 1 failure:
1) testFailMessage(tddbook.JUnitTutorialTest)junit.framework.AssertionFailedError: expected:<10> but was:<15>
at tddbook.JUnitTutorialTest.testFailMessage(JUnitTutorialTest.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at tddbook.JUnitTutorialTest.main(JUnitTutorialTest.java:21)
FAILURES!!!
Tests run: 2, Failures: 1, Errors: 0
점 두개는 역시 테스트의 갯수를 말하며
그 옆의 F는 테스트가 실패(Fail)되었음을 말한다.
There was 1 failure: 밑에는 실패한 이유와 trace가 보인다.
우리의 짐작처럼 기대값은 10인데 결과값이 15라서
AssertionFailedError가 발생했음을 알려준다.
마지막 줄은 총 2개의 테스트 중 1개의 Fail이 있고 Error는 0개임을 말한다.
테스트 코드에서 Fail과 Error는 다르다.
Fail은 우리가 테스트한 기대값과 결과값이 다를때 발생하지만
Error는 코드상의 오류나 NullPointerException같은
예측못한 Exception이 발생할 때 생긴다.
setUp & tearDown
setUp - JUnit 테스트 코드의 setUp 메써드는 특별한 의미이다.
주로 코드내에서 사용할 리소스를 초기화 시킬때 setUp을 이용한다.
즉, 각각의 테스트 코드가 항상 new Person()이라는 statement를 실행한다면
이것은 setUp에 선언해서 테스트 매써드가 실행될 때마다 수행하게 할 수 있는 것이다.
다시 말해 setUp은 각각의 testXXX메써드들이 수행되기 바로 직전에
매번 실행되는 것이다.
tearDown - setUp과 반대의 경우라고 생각하면 된다.
testXXX매써드가 종료될 때마다 수행되는 매써드이다.
사용한 리소스를 클리어할때 주로 사용된다.
Examples.
package tddbook;
import junit.framework.TestCase;
import java.util.*;
public class TestSetupTearDown extends TestCase {
public TestSetupTearDown(String arg0) {
super(arg0);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(TestSetupTearDown.class);
}
Vector employee;
protected void setUp() throws Exception {
employee = new Vector();
}
protected void tearDown() throws Exception {
employee.clear();
}
public void testAdd() {
employee.add("Pey");
assertEquals(1, employee.size());
}
public void testCleared() {
assertEquals(0, employee.size());
}
}
JUnit Useful Methods
JUnit에서 가장 많이 사용되는 메써드는 assertEquals이지만 이 외에도 여러 유용한 메써드들이 있는데 그것에 대해서 알아보기로 하자.
assertTrue(X)
X가 참인지를 테스트한다.
assertFalse(X)
X가 거짓인지를 테스트한다.
assertNull(X)
X가 NULL인지를 테스트한다.
assertNotNull(X)
X가 NULL이 아닌지를 테스트한다.
fail(MSG)
무조건 실패시킨다 (MSG를 출력한다. ) 주로 Exception테스트를 할때 사용된다.
<< 출처 : http://www.yeonsh.com >>
JUnit Cookbook
A cookbook for implementing tests with JUnit.
간단한 Test Case
뭔가를 테스트하고 싶을 때 순서:
1. TestCase 클래스의 인스턴스를 만든다.
2. runTest() 메소드를 override한다.
3. 값을 검사하고 싶으면, assert()를 호출해서 테스트가 성공일 때
참이 되는 boolean을 전달한다.
public void testSimpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
assert(expected.equals(result));
}
이미 작성한 테스트와 유사한 테스트를 다시 작성해야 한다면 대신 Fixture를 만든다.
만일 하나 이상의 테스트를 실행해야 한다면 Suite를 만든다.
Fixture
동일하거나 유사한 오브젝트에 대한 테스트가 두개 이상 있을 경우
테스트 환경을 셋업하기 위한 코드를 각 테스트에서 꺼내서 하나의 메소드에 넣어 둔다.
동일한 환경에서 실행되는 테스트를 위한 설정을 Fixture라고 한다.
처음 테스트를 작성할 때는 테스트 자체를 위한 코드보다는 테스트를 위한 환경 설정에
더 많은 시간이 들 것이다. Fixture를 작성해놓으면 다음에 테스트를 작성할 때
시간이 절약될 것이다.
공통 Fixture가 있을 경우 할 일:
1. TestCase 클래스의 서브 클래스를 만든다.
2. Fixture의 각 파트를 위한 인스턴스 변수를 추가한다.
3. setUp()을 override해서 변수를 초기화한다.
4. tearDown()을 override해서 setUp()에서 할당한 자원들을 해제한다.
public class MoneyTest extends TestCase {
private Money f12CHF;
private Money f14CHF;
private Money f28USD;
protected void setUp() {
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
f28USD= new Money(28, "USD");
}
}
Test Case
Suite
TestSuite는 많은 테스트 케이스들을 함께 실행할 수있다.
하나의 테스트 케이스를 실행하는 방법은 아래와 같다.
TestResult result= (new MoneyTest("testMoneyMoneyBag")).run();
두개의 테스트 케이스를 한번에 실행할 때는 아래와 같이 한다.
TestSuite suite= new TestSuite();
suite.addTest(new MoneyTest("testMoneyEquals"));
suite.addTest(new MoneyTest("testSimpleAdd"));
TestResult result= suite.run();
다른 방법은 JUnit으로 하여금 TestCase에서 suite를 추출하도록 하는 것이다.
그렇게 하기 위해서는 TestSuite의 생성자에 테스트 케이스의 클래스를 전달한다.
TestSuite suite= new TestSuite(MoneyTest.class);
TestResult result= suite.run();
테스트 케이스의 일부만 테스트할 때는 수작업으로 하나씩 지정하는 방법을 사용한다.
그 외의 경우에는 위와 같이 자동 추출되도록 하면 테스트 케이스를 추가할 때마다
지정하지 않아도 되므로 좋다.
TestSuite는 Test Interface를 implement하는 모든 오브젝트를 포함할 수 있다.
TestSuite suite= new TestSuite();
suite.addTest(Kent.suite());
suite.addTest(Erich.suite());
TestResult result= suite.run();
TestRunner
어떻게 테스트를 실행하고 결과를 수집할 것인가?
JUnit은 실행할 suite를 정의하고 결과를 표시하기 위한 도구(TestRunner)를 제공한다.
test suite를 넘겨주는 static method suite()를 사용하면 TestRunner가
suite에 접근할 수 있다.
예를 들어, TestRunner가 MoneyTest suite를 사용할 수 있게 하려면,
아래와 같은 코드를 MoneyTest에 추가한다
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTest(new MoneyTest("testMoneyEquals"));
suite.addTest(new MoneyTest("testSimpleAdd"));
return suite;
}
만일 TestCase가 suite 메소드를 정의하지 않는다면
TestRunner는 'test'로 시작하는 모든 메소드들을 추출해서 suite를 만들 것이다.
JUnit은 TestRunner 툴의 텍스트 버전과 그래픽 버전을 제공한다.
junit.textui.TestRunner는 텍스트 버전이고 junit.ui.TestRunner와
junit.swingui.TestRunner는 그래픽 버전이다.
TestCase 클래스에 main()을 정의해놓으면 직접 TestRunner를 호출할 수도 있다.
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
위의 모든 방법으로 테스트가 정상실행되도록 하기 위해서는
CLASSPATH에 junit.jar 파일이 들어 있어야 한다
단위 테스트 JUnit 사용하기.[스크랩]
목포 bada9님의 질문중 JUnit을 이용한 단위 테스트입니다. 디버그를 할 때 자바는 단위테스트를 많이 사용합니다. 자바 디버깅 툴 jbd 사용법과 System.out.println, JLogger, Log4j를 이용한 로깅방법은 빠른 시일안에 추가하겠습니다.
1. JUnit 환경 확인하기 - 이클립스에 통합되어 있다.
2. 프로젝트 만들기
3. 클래스 만들기
[Student.java]-------------------------
package kr.honny.unit;
public class Student {
private String name;
private int age;
private String addr;
public Student(String name, int age,String addr) {
this.name=name;
this.age=age;
this.addr=addr;
}//Student
public String getAddr() {return addr;}
public int getAge() {return age;}
public String getName() {return name;}
public void setAddr(String string) {addr = string;}
public void setAge(int i) {age = i;}
public void setName(String string) {name = string;}
public String toString(){
return name+" "+age+" "+addr;
}//toString
public boolean equals(Object obj){
boolean isE=false;
Student temp=(Student)obj;
if(temp.getName().equals(name) && temp.getAge()==age
&& temp.getAddr().equals(addr)){
isE=true;
}
return isE;
}//equals
public int hashCode(){
int temp=0;
temp=name.hashCode()+addr.hashCode()+age+37;
return temp;
}//hashCode
}
[StudentMain.java]-------------------------
package kr.honny.unit;
public class StudentMain {
public static void main(String[] args) {
Student s1=new Student("a",34,"b");
Student s2=new Student("a",34,"b");
System.out.println("--------Test----------");
System.out.println(s1.hashCode());//해쉬코드
System.out.println(s2.hashCode());//해쉬코드
System.out.println(s2.equals(s1));
System.out.println(s1.getName().equals("a"));
System.out.println(s1.getAddr().equals("b"));
System.out.println(s1.getAge()==34);
}
}
4. JUnit Test Case 만들기
5. JUnit Test Case 설정
6. JUnit Test Case 코딩
[HelloJunits.java]-------------------------
package kr.honny.unit;
import junit.framework.TestCase;
public class HelloJunits extends TestCase { //1. 반드시 TestCase를 상속한다.
Student s1;
Student s2;
Student s3;
public static void main(String[] args) {
junit.swingui.TestRunner.run(HelloJunits.class); //2. 실행은 ..run(클래스이름.class)
//junit.swingui.TestRunner.run(클래스이름.class) 이형식을 지킬 것.
}
public void setUp() { //초기화
s1=new Student("a",34,"b");
s2=new Student("a",34,"b");
s3=new Student("a",34,"c");
}
public void testHash() { // 3. 테스트할 메서드는 testXXX 형태로 선언한다.
assertTrue(s1.hashCode() == s2.hashCode());
//4. assertTrue는 ==나 equals를 직접 비교한다.
}
public void testSameStudent() {
//System.out.println(s2.equals(s1));
assertEquals(s1,s2); //정상 5. s1.equals(s2)를 비교한다.
assertEquals(s1,s3); //에러 발생
assertEquals("참조타입 비교",s1,s2);
//assertTrue(s2.equals(s1));
}
}
7. JUnit Test Case 코딩
StudentMain.java과 같은 역할을 단위 테스터로 실행한다.
StudentMain.java는 System.out.println을 사용하여 한 줄 한 줄 테스트를한다.
그러나 HelloJunits.java는 JUnit 프레임워크를 이용하여 메서드 단위로 테스트를 한다.
assertEquals, assertTrue를 이용하여 참 거짓을 예상하고 잘 작성된 메서드 인가 아닌가를 판별할 수 있다.
8. JUnit Test Case 실행결과 - 모두 올바른 결과를 낼때
틀린 결과를 내면 붉은 색이 나온다. 맞는 값과 틀린 값을 입력해서 잘 작성된 메서드인가를 확인한다.
유용한 디버깅툴들
1. DeviceTree
kernel 에 등록된 device driver 의 정보를 표현한다.
device name, devObject address, attach device 정보
2. traceview
driver 의 WMI log 를 출력한다.
WMI log 를 driver 가 생성하기 위한 사전작업
1. GUID 를 만든다.
WINDDK\...\tool\other\genguid.exe 에서 registry type 으로 id 를 생성한다.
2. WPP_CONTROL_GUIDS 매크로를 정의한다.
3. makefile 에
RUN_WPP= $(sources) -km 과 C_DEFINES = $(C_DEFINES) -DEVENT_TRACING 을 적당한 위치에 추가 한다.
4. 아래의 코드가 WMI log 를 사용하는 .c 의 제일 위에 위치시킨다.
WMI log 발생을 위한 header 가 필요한데 이것은 DDK tool 에서 작성하여 .tmh file 로 만든다.
이것을 각 source 에서 가져다 쓸 수 있도록 한다.
#include
5. WMI log 초기화 : DriverEntry 에 WPP_INIT_TRACING(DriverObject, RegistryPath); 를 추가하고,
Unload 에 WPP_CLEANUP(DriverObject); 를 추가한다.
6. DoTraceMessage ( ) 을 이용하여 log 를 발생한다.
함수이름을 바꾸기를 원하면 Makefile 에 -func 에 대신사용할 함수이름을 지정한다.
RUN_WPP=$(SOURCES)\
-km \
-func:ToasterDebugPrint(LEVEL,MSG,...)
JUnit 연습하기1
사용한 예제는 이클립스 에서 작성한것이다.(자니메드인가? Version: 3.4.0 Build id: I20080617-2000)
Largest 메소드를 작성.
초기 작성
public class Largest {
/**
* 목록에서 가장큰수를 반환한다.
*
* @param list 정수목록
* @return 주어진 목록에서 가장큰수
*/
public static int largest(int[] list){
int index, max= Integer.MAX_VALUE;
for (index = 0; index
max= list[index];
}
}
return max;
}
}
Largest 메소드 테스트 Junit 3과 4버전의 경우 import 부분만 과 상속받는 부분만 다를분 다른부분은 동일하다.
4를 기준으로 작성하도록하겠다.
Junit 초기 작성
junit 3 일경우
import junit.framework.TestCase;
public class LargestTest_J3 extends TestCase {
public void testLargest() {
assertEquals(9,Largest.largest(new int[] {7,9,8}));
}
}
JUnit 4일경우
import static org.junit.Assert.*;
import org.junit.Test;
public class LargestTest {
@Test
public void testLargest() {
assertEquals(9,Largest.largest(new int[] {7,9,8}));
}
}
실행할경우 에러 발생. 예상결과 9대신 2147483647이 나온다.
이 문제를 해결하기 위해서는 max= Integer.MAX_VALUE 요놈을 수정해야 한다.
이것을 max=0 으로 변경한다.
max를 초기화 해서 입력의 어떤 값이 바로 다음 최대값이 되기를 원한다.
수정1
public class Largest {
/**
* 목록에서 가장큰수를 반환한다.
*
* @param list 정수목록
* @return 주어진 목록에서 가장큰수
*/
public static int largest(int[] list){
int index, max= 0;
for (index = 0; index
max= list[index];
}
}
return max;
}
}
JUnit을 다시 실행한다. 정상적으로 Pass 되는것을 볼수있다.
하지만 아래의 테스트를 수행하면 실패하는 것을 볼수 있을 것이다.
Junit 수정1
import static org.junit.Assert.*;
import org.junit.Test;
public class LargestTest {
@Test
public void testLargest() {
assertEquals(9,Largest.largest(new int[] {7,9,8}));
assertEquals(9,Largest.largest(new int[] {9,7,8}));
assertEquals(9,Largest.largest(new int[] {7,8,9}));
}
}
왜 가장큰수가 8로 나왔을까? 결과를 보면 테스트가 배열의 마지막 원소를 무시해서 나타난것이다.
예상결과는 9인데 실제결과는 8이 나와서 나타나는 결과이다.
for (index = 0; index
이부분이 문제이다.
이것을 아래와 같이 바꾼다.
수정2
public class Largest {
/**
* 목록에서 가장큰수를 반환한다.
*
* @param list 정수목록
* @return 주어진 목록에서 가장큰수
*/
public static int largest(int[] list){
int index, max= 0;
for (index = 0; index
max= list[index];
}
}
return max;
}
}
다시 Junit을 실행하면 Fail없이 정상적으로 동작하는 것이 보여진다.
그러면 동일한 숫자가 있을경우는 어떻게 되는지 보자.
그냥 동일한 테스트 메소드에 넣어도되지만 테스트 메소드를 하나더 추가해서 만들겠다.
Junit 추가1
public void testDups(){
assertEquals(9,Largest.largest(new int[] {7,9,8,9}));
}
역시 통과한다.
한개의 수가 있을경우는?
Junit 추가2
public void testOne() {
assertEquals(1, Largest.largest(new int[] { 1 }));
}
역시 통과
- 일경우는?
Junit 추가3
public void testNegative(){
assertEquals(-7,Largest.largest(new int[] {-7,-9,-8}));
}
실패한다. 예상결과에는 -7이였지만 결과는 0으로 나온다. 왜그럴까?
그건 Max=0을 줘서 그렇다. Max의 값을 음수 보다도 적게 하려면 Integer.MIN_VALUE를 사용하면 된다.
최종
public class Largest {
/**
* 목록에서 가장큰수를 반환한다.
*
* @param list 정수목록
* @return 주어진 목록에서 가장큰수
*/
public static int largest(int[] list){
int index, max= Integer.MIN_VALUE;
for (index = 0; index
max= list[index];
}
}
return max;
}
}
공백에 대한 테스트를 하여야 하지만 이부분은 예외처리를 하도록하겠다.
Junit 추가4
public void testEmpty() {
try {
Largest.largest(new int[] {});
fail("Should have thrown an exception");
} catch (RuntimeException e) {
assertTrue(true);
}
}
Junit 전체
import static org.junit.Assert.*;
import org.junit.Test;
public class LargestTest {
@Test
/*
* 순서 일반비교
*/
public void testLargest() {
assertEquals(9, Largest.largest(new int[] { 7, 9, 8 }));
assertEquals(9, Largest.largest(new int[] { 9, 7, 8 }));
assertEquals(9, Largest.largest(new int[] { 7, 8, 9 }));
}
@Test
/*
* 동일한 숫자가 있을경우
*/
public void testDups() {
assertEquals(9, Largest.largest(new int[] { 7, 9, 8, 9 }));
}
@Test
/*
* 숫자 하나만 있는 경우
*/
public void testOne() {
assertEquals(1, Largest.largest(new int[] { 1 }));
}
@Test
/*
* 음수가 들어간경우
*/
public void testNegative() {
assertEquals(-7, Largest.largest(new int[] { -7, -9, -8 }));
}
@Test
/*
* 공백일경우
*/
public void testEmpty() {
try {
Largest.largest(new int[] {});
fail("Should have thrown an exception");
} catch (RuntimeException e) {
assertTrue(true);
}
}
}
테스트의 여섯가지 영역
Right-BICEP
1. Right - 결과가 옳은가?
2. B - 모든경계(Boundary) 조건이 CORRECT한가?
3. I - 역(Inverse)관계를 확인 할수 있는가?
4. C - 다른 수단을 사용해서 결과를 교차 확인(Cross - check)할수 있는가?
5. E - 에러조건(Error Condition) 을 강제로 만들어 낼 수 있는가?
6. P - 성능(Performance) 특성이 한도 내에 있는가?