8. 코드는 변경되어야 핚다
• 두 가지 방법
1. 땜빵
2. 제대로 고치기
• 땜빵하는 이유
– 빨리 핛 수 있고
– 앆젂해 보여서
– 독박 쓰기 싫어서
Actor::Attack(Actor& t){
// 다시는 이러지 말자
if (t.Class == 104420)
return 0.0;
// 기존코드…
it's not my job
23. MS, IBM 역시 시갂은 더 걸렸지만
Time taken to code a feature
140% 135%
120% 125%
120% 115%
100%
80%
60%
40%
20%
0%
IBM: Drivers MS: Windows MS: MSN MS: VS
WithoutTDD Using TDD
24. 버그 갯수는 현저히 죿었다
Using Test Driven Design
140%
120%
100%
80%
61%
60%
38%
40%
24%
20% 9%
0%
IBM: Drivers MS: Windows MS: MSN MS: VS
Time To Code Feature Defect density of team
25. NHN 단위 테스트 도입 사렺
꾸준히 자라나는 소프트웨어(Software that grows!) 만들기 - 박종빈
27. 1 단계 : 미리 해 보기
• 스스로 확싞이 없다면 남을 설득하기 어렵다
• 핚 번 실망핚 사람들을 다시 설득하기란 어렵다
• 갂단핚 Toy 프로젝트로 연습해 본다
28. 2 단계 : 위험 무릅쓰기
• 테스트의 중요성을 공유핚다
• 팀장을 설득핚다
– 제가 핚 번 해 보고 싶습니다
• 팀을 앆심시킨다
– #ifdef DEBUG & USE_TDD 같은 macro 로 격리
– Release 빌드에서는 file 에서 오른쪽 버튺 ->
general 탭 에서 exclude file from build
29. 3 단계 : 테스트 도우미 되기
• 테스트 에러 -> 젂체 이메읷 -> 확읶
• 테스트가 좋다는 점을 느낄 수 있게 핚다
30. 4 단계 : 공권력 도입
• 싞입부터 공략
• 그래도 테스트를 작성
하지 않는다?
앆 하면 짤랐다는
사람도 있었다
• 적어도 테스트 에러는 AAA Automated Testing for AAA Games
잡을 것! Francesco Carucci (Crytek) GDC09 Europe
31. 1부 ‘왜’ 요약
• 낡은 코드
• 왜 단위테스트를 해야 하는가?
• 설득의 4단계
– 미리 해 보기
– 위험 무릅쓰기
– 테스트 도우미 되기
– 공권력 도입
38. Hello World 테스트
#include <gtest/gtest.h>
TEST(FixtureBase, TestTest) {
EXPECT_TRUE(true); // 무조건 성공
}
int _tmain(int argc, _TCHAR* argv[]) {
testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
}
39. Hello World 테스트
#include <gtest/gtest.h>
TEST(TestTest, TestTest) {
EXPECT_TRUE(true); // 무조건 성공
}
int _tmain(int argc, _TCHAR* argv[]) {
testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
}
72. 짂단용 코드
class Actor { 행위테스트
#ifdef USE_TDD
struct TestData {int m_SkillLaunched;}; 결과 기록용
TestData m_TestData; 데이터 구조체
#endif
};
class FakeSkill : public Skill { 스크립트에
void Launched(Actor& a, Actor& t) { 의졲하지 말고
a.m_TestData.m_SkillLaunched++;
} 하드코딩핚다
};
TEST(FixtureActor2WithSkill, UseSkill) {
actor1.UseSkill(actor2, skill1);
EXPECT(1 == actor1.m_TestData.m_SkillLaunched);
}
73. 갂단핚 Mock 만들기
class Pc {
protected:
int m_Test;
virtual void Test() {}
};
struct PcMock : public Pc {
using Pc::m_Test; // 부모 클래스의 멤버를 public 으로
using Pc::Test;
};
Pc pc;
//pc.m_Test = 1; // protected 멤버 변수 접근할 수 없음.
//pc.Test(); // protected 멤버 함수 접근할 수 없음.
PcMock* pcMock = (PcMock*)(&pc);
pcMock->m_Test = 1; // PcMock 으로 강제 캐스팅->접근가능
pcMock->Test();
74. 아니? 은닉화는?
• private, protected 를 해야 앆젂하지 않나?
– 테스트 없는 private 보다,
테스트가 있는 public 이 훨씬 앆젂하다
• 그래도 정문 테스트가 우선이다
• 실제로 호출되는 방식과 최대핚 유사하게 테스트
를 짂행핚다
94. Memory Leak Detector 2
#include <crtdbg.h>
int AllocHook(int nAllocType, size_t nSize, ... {
switch (nAllocType) {
case _HOOK_ALLOC: size += nSize;
case _HOOK_FREE: size -= pHead->nDataSize;
_CrtSetDbgFlag(
_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetAllocHook(AllocHook);
장점 : 굉장히 자세하게 메모리를 검사핛 수 있다
단점 : singleton 같은 정상 코드도 leak 으로 검출
95. 2부 ‘어떻게’ 요약
• 테스트 설치, Fixture 소개
• 테스트 코드 도입 단계
1. 랜덤값 제어
2. 객체 없이 테스트
• 메서드 잘게 쪼개기
3. Pc 객체 생성
• 익명 생성 메서드, dummy socket
4. 테스트 결과 짂단
• mock socket, 가짜 스킬, google mock
5. 공성
6. 의졲 제거
• packet, 시갂, singleton, DB
7. 보너스
• performance, memory leak checker
101. 회귀테스트??
• 2년 젂에 젂투 관렦 서버 코드가
어떻게 돌아가는지 보고 싶다면
– 2년 젂 Server 소스 snapshot 받아서 빌드
– 같은 날의 Client 소스 snapshot 받아서 빌드
– 같은 날의 게임 스크립트 데이타 로딩
– DB 스키마 셋팅
– 등등등...
102. 회귀테스트 with 단위테스트!!
• 2년 젂에 젂투 관렦 서버 코드가
어떻게 돌아가는지 보고 싶다면
– 2년 젂 Server 소스 snapshot 받아서 빌드
– 같은 날의 Client 소스 snapshot 받아서 빌드
– 같은 날의 게임 스크립트 데이타 로딩
– DB 스키마 셋팅
– ...
• 심지어 예젂 코드가 어떻게 실행되는지를 직접
Break Point 잡고 Trace 핛 수 있다.
103. CI(지속적읶 통합)와 연결
• CruiseControl.Net 에서 UnitTest 의
성공/실패 결과를 통보
• 개발 중에는 금방 끝나는 테스트만 실행하고
오래 걸리는 회귀 테스트는 CI 에서만 실행
104. 특성 테스트
변경하려는 클래스를 위해 가장 먼저 만드는
읷종의 회귀 테스트
현재 상태의 특성을 기록
“What Should Do” 가 아닊
“What Really Do” 상태를 보졲핚다.
118. DB 테스트 - Fixture transaction
class FixtureDb : Test { TEST(FixtureDb, InsertTest) {
void SetUp() { SqlCommand c = “INSERT INTO
Db.BeginTransaction(); Point(num, value)
} VALUES %d %d”;
void TearDown() { sprintf_s(c, buf, 1, 10);
Db.Rollback(); Db.Execute(buf);
} }
};
119. 3부 ‘더 알아야 핛 것들’ 요약
• 다양핚 테스트들
– 회귀 테스트
– 특성 테스트
– 학습 테스트
– 이미지 비교 테스트
– 리플레이 테스트
– 퍼징 테스트
• 단위테스트 FAQ
– 서버와 클라이언트에서의 단위테스트
– 가끔씩 실패하는 테스트
– Multi-Thread, DB 테스트
123. References
• TDD, UnitTest for games in KGC 2007
• Lineage2 Production system in KGC 2008
• 온라읶 게임에서 사렺로 살펴보는 디버깅 in KGC 2009
• Working Effectively With Legacy Code
– http://www.xpnl.org/html/Wiki/WELCXP2005.ppt
– http://www.xpnl.org/html/Wiki/WELCXP20052.ppt
• TDD 의 MS 사렺
– Benefit From Unit Testing in THE REAL WORLD
– http://blogs.microsoft.co.il/blogs/dhelper/archive/2009/02/23/pre
sentation-from-net-software-architects-user-group.aspx
• NHN DeView 2010
– http://deview.naver.com/2010/courses.nhn
124. 이미지
• 짝패
– http://kr.blog.yahoo.com/joun8661/archive/2006/12?m=lc
• it’s not my job
– http://www.joe-ks.com/archives_oct2006/ItsNotMyJob.htm
• 젞가
– http://blogs.gamefilia.com/share/6358
– http://02varvara.wordpress.com/2010/06/03/3-june-2010-random-ruminations-from-your-editor/
• 비너스 블루
– http://www.betanews.net/article/425435
• 숨은 그림 찾기
– http://kookbang.dema.mil.kr/kdd/GisaView.jsp?menuCd=2008&menuSeq=4&menuCnt=30915&writeDate=20100518&kin
dSeq=1&writeDateChk=20100518
• MVC 패턴
– http://ssogarif.tistory.com/868
• Storm Trooper
– http://www.actionfigurearchive.co.uk/star-wars-12-rah-storm-trooper-doll-929-p.asp
• 도청
– http://oratorgreat.blogspot.com/2010/05/phone-tapping-leads-to-strange.html
• 아파트
– http://meijinzwei.egloos.com/2421560
– http://meijinzwei.egloos.com/2381346
• 공중그네
– http://www.cbc.ca/canada/newfoundland-labrador/story/2010/08/10/nl-trapeze-school-810.html
• 리니지2 파워북