Agile Test Driven Development For Games What, Why, And How
1. 게임을 위한 테스트 주도 개발 : 무엇을 , 왜 그리고 어떻게 ? Noel Llopis Senior Architect High Moon Studios 번역 : 박일 http:// ParkPD.egloos.com 도움 : 김기웅 http://betterways.tistory.com/
2.
3.
4. define G(n) int n(int t, int q, int d) #define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023)) #define U(m) *((signed char *)(m)) #define F if(!--q){ #define I(s) (int)main-(int)s #define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k G (B) { Z; F D = E (Y (V), C = E (Y (V), Y (t + 4) + 3, 4, 0), 2, 0); Y (t + 12) = Y (t + 20) = i; Y (t + 24) = 1; Y (t + 28) = t; Y (t + 16) = 442890; Y (t + 28) = d = E (Y (V), s = D * 8 + 1664, 1, 0); for (p = 0; j < s; j++, p++) U (d + j) = i == D | j < p ? p--, 0 : (n = U (C + 512 + i++)) < ' ' ? p |= n * 56 - 497, 0 : n; } n = Y (Y (t + 4)) & 1; F U (Y (t + 28) + 1536) |= 62 & -n; M U (d + D) = X (D, Y (t + 12) + 26628, 412162) ? X (D, Y (t + 12) + 27653, 410112) ? 31 : 0 : U (d + D); for (; j < 12800; j += 8) P (d + 27653 + Y (t + 12) + ' ' * (j & ~511) + j % 512, U (Y (t + 28) + j / 8 + 64 * Y (t + 20)), 0); } F if (n) { D = Y (t + 28); if (d - 10) U (++Y (t + 24) + D + 1535) = d; else { for (i = D; i < D + 1600; i++) U (i) = U (i + 64); Y (t + 24) = 1; E (Y (V), i - 127, 3, 0); } } else Y (t + 20) += ((d >> 4) ^ (d >> 5)) - 3; } }
15. 캐릭터 + 방패 Character Damage(x) Shield Damage(x) class Character { IShield* m_shield; public: Character(); void Damage(float amount); float GetHealth() const; };
16.
17. 반환되는 값 검사 TEST (ShieldCanBeDamagedIfFull) { } 방패 방패 검사하기 bool Damage() 데미지 ? Shield shield; CHECK (shield.Damage()); “ ShieldLevelStartsFull 에서 오류 발생 : 100 을 예상했지만 , 0 이 나옴 . ”
18. 상태 검사 TEST (LevelCannotBeDamagedBelowZero) { } 방패 방패 검사하기 Damage(200) GetLevel() Shield shield; shield.Damage(200); CHECK_EQUAL (0, shield.GetLevel()); 0?
22. 상호작용 검사 ( 초기에 문제가 될 수 있다 . ) 캐릭터 검사하기 캐릭터 Damage() *m_shield TEST(CharacterUsesShieldToAbsorbDamage) { Character character(400); character.Damage(100); CHECK_EQUAL(390, character.GetHealth()); } 390? 방패 GetHealth() 화려한 방패
23. class IShield { public: virtual float Damage(float amount) = 0; } class FancyShield : public IShield { public: float Damage(float amount) { … }; } class MockShield : public IShield { public: float damagePassedIn; float damageToReturn; float Damage(float amount) { damagePassedIn = amount; return damageToReturn; } } 가짜 객체가 , 검사 대상인 해당 단위 (unit) 의 외부에 위치한 객체를 대신한다 .
24. Mock 을 사용해서 검사하기 캐릭터 검사하기 TEST(CharacterUsesShieldToAbsorbDamage) { } 가짜 방패 MockShield mockShield = new MockShield; mockShield->damageToReturn = 10; Character character(400, mockShield); character.Damage(200); CHECK_EQUAL(200, mockShield->damagePassedIn); CHECK_EQUAL(390, character.GetHealth()); 캐릭터 Damage() *m_shield 매개 변수들은 정확한가 ? GetHealth() 반환된 데미지가 정확하게 사용되는가 ?
25. 최상의 관행 : 근처의 코드만 검사하기 검사 검사중인 코드 검사 검사중인 코드 하위 시스템 A 하위 시스템 B 하위 시스템 C 고양이가 끄집어낸 어떤 것 부엌의 싱크대 누가 알겠어
28. 최상의 관행 : 신속한 검사 Debug 상태에서 TestDebugServer 의 단위 검사 실행중 .. 검사 116 번 실행 실패한 검사 없음 . 소요 시간 : 0.016 초 . Debug 상태에서 TestStreams 의 단위 검사 실행중 ... 검사 138 번 실행 실패한 검사 없음 . 소요 시간 : 0.015 초 . Debug 상태에서 TestMath 의 단위 검사 실행중 ... 검사 245 번 실행 실패한 검사 없음 . 소요 시간 : 0.001 초 . 단위 검사 실행중 ... 검사 184 번 실행 실패한 검사 없음 . 소요 시간 : 0.359 초 .