SlideShare una empresa de Scribd logo
1 de 53
Descargar para leer sin conexión
(birdkr@gmail.com)
 birdkr@gmail.com)
?
CruiseControl.NET
CruiseControl.NET
CruiseControl.NET
•
• Asset
•
•
•
•
•       (doxygen)
•
?
1.           .

2.   .

3.       ,
         .
테스트 결과 로그
<?xml version="1.0"?>

<maiettest-results tests=“2" failedtests=“1" failures="1" time="0.137">
       <report text="time : 680 sec" />
       <report text=“총 클라이언트 개수 : 4650" />
       <test name=“로그인 반복" time="0.062" >
               <success message="success" />
       </test>
       <test name=“캐릭터 생성 반복" time="0.062" >
               <failure message="Crash!" />
       </test>
</maiettest-results>
테스트 결과 로그
• 테스트 결과를 XML로 만들고, XSL을 이용
  하여 CruseControl.NET에 출력한다.
Feedback
Unit Test
•
•
    .
Unit Test
TEST(TestMathFunctionTruncateToInt)
{
  CHECK_EQUAL(0, GMath::TruncateToInt(0.0));
  CHECK_EQUAL(5, GMath::TruncateToInt(5.6));
  CHECK_EQUAL(13, GMath::TruncateToInt(13.2));
  CHECK_EQUAL(13, GMath::TruncateToInt(13.2));
  CHECK_EQUAL(-6, GMath::TruncateToInt(-5.6));
  CHECK_EQUAL(-3, GMath::TruncateToInt(-2.1));
}
Unit Test
TEST(ShieldCanBeDamaged)
{
  World world;
  world.Create();
  Player player;
  player.Create(world, vec3(1000,1000,0));
  player.SetHealth(1000);
  Shield shield;
  shield.SetHealth(100);
  player.Equip(shield);
  player.Damage(200);

    CHECK(shield.GetHealth() == 0);
    CHECK(player.GetHealth() == 900);
}
Unit Test
Unit Test
TEST_FIXTURE(FLogin, TestLogin_MC_COMM_REQUEST_LOGIN_SERVER_Success)
{
                                 MakeParam_TD_LOGIN_INFO();
     TD_LOGIN_INFO tdLoginInfo = MakeParam_TD_LOGIN_INFO();
     OnRecv_MMC_COMM_REQUEST_LOGIN_SERVER(m_nRequestID, m_nConnectionKey, &tdLoginInfo
                                                                           tdLoginInfo);
     OnRecv_MMC_COMM_REQUEST_LOGIN_SERVER(m_nRequestID, m_nConnectionKey, &tdLoginInfo);

     // 로그인 하기 전의 값 체크
     CHECK_EQUAL(0, gmgr.pPlayerObjectManager->GetPlayersCount());

     // 클라이언트로부터 존 입장 패킷 받음
     OnRecv_MC_COMM_REQUEST_LOGIN_SERVER(m_nConnectionKey);
     OnRecv_MC_COMM_REQUEST_LOGIN_SERVER(m_nConnectionKey);

    // 마스터 서버로 인증키 확인 패킷 보냈는지 체크
    CHECK_EQUAL(MC_COMM_RESPONSE_LOGIN_SERVER, m_pLink- GetCommandID(0));
    CHECK_EQUAL(MC_COMM_RESPONSE_LOGIN_SERVER, m_pLink->GetCommandID(0));
    CHECK_EQUAL(RESULT_SUCCESS, m_pLink- GetParam<int>(0,
    CHECK_EQUAL(RESULT_SUCCESS, m_pLink->GetParam<int>(0, 0));
    CHECK_EQUAL(m_pLink->GetUID(), m_pLink->GetParam<MUID>(0, 1));
    CHECK_EQUAL(m_pLink- GetUID(), m_pLink- GetParam<MUID>(0,

     // 로그인 후 값 체크
     CHECK_EQUAL(1, gmgr.pPlayerObjectManager->GetPlayersCount());

     GPlayerObject* pPlayerObject = gmgr.pPlayerObjectManager->GetPlayer(m_pLink->GetUID());
     CHECK(pPlayerObject != NULL);
     CHECK_EQUAL(m_nGUID, pPlayerObject->GetAccountInfo().nGUID);
     CHECK_EQUAL(string(“birdkr”), string(pPlayerObject->GetAccountInfo().strID));
}
Mock Object
class MockPlayer : public GPlayer
{
public:
         MockPlayer() {};
        virtual ~ MockPlayer() {};
        …
        virtual void SendToThisSector (MPacket* pPacket) override { }
        virtual void SendToMe(MPacket * pPacket) override { }
        virtual void SendToGuild(MPacket* pPacket) override { }
        …
};
,
class XSystem
{
public:
        virtual unsigned int GetNowTime()
        {
                return timeGetTime()
                       timeGetTime()();
        }
        virtual int RandomNumber(int nMin, int nMax)
        {
                return (rand() % (nMax - nMin + 1)) + nMin;
                        rand()
                        rand
        }
};
,
class MockSystem : public XSystem
{
protected:
        unsigned int m_nExpectedNowTime;
public:
        virtual unsigned int GetNowTime()
        {
                 if (m_nExpectedNowTime != 0)
                         return m_nExpectedNowTime;

              return XSystem::GetNowTime();
       }

       void ExpectNowTime(unsigned int nNowTime)
       {
               m_nExpectedNowTime = nNowTime;
       }
};
,
TEST_FIXTURE(FPlayerInOut2, TestObjectCacheDelete)
{
  vec3 vNewPos = vec3(100.0f, 100.0f, 0.0f);
  CHECK_EQUAL(2, gg.omgr->GetCount());

    m_pNet->OnRecv( MC_ENTITY_WARP, 3, NEW_ID(m_pMyPlayer->GetID

    Update(0.1f);

    CHECK_CLOSE(100.0f, m_pMyPlayer->GetPosition().x, 0.001f);
    CHECK_CLOSE(100.0f, m_pMyPlayer->GetPosition().y, 0.001f);

    XExpectNowTime(XGetNowTime() + 10000 );
    Update(10.0f);

    // 멀리 있는 다른 플레이어가 지워졌다.
    CHECK_EQUAL(1, gg.omgr->GetCount());
}
,
template <class Type>
class GTestMgrWrapper : public MInstanceChanger<Type>
{
public:
        GTestMgrWrapper() : MInstanceChanger()
        {
                m_pOriginal = gmgr.Change(m_pTester);
        }
        ~GTestMgrWrapper()
        {
                gmgr.Change(m_pOriginal);
        }
};
,
TEST_FIXTURE(FChangeMode, TestNPC_SightRange)
{
  GTestMgrWrapper<GNPCInfoMgr> m_NPCInfoMgrWrapper;

    m_NPCInfo.nSightRange = 1000;

    GNPC* pNPC = m_pMap->SpawnTestNPC(&m_NPCInfo);
    CHECK_EQUAL(1000, pNPC->GetSightRange());

    pNPC->ChangeMode(NPC_MODE_1);
    CHECK_EQUAL(500, pNPC->GetSightRange());
}
Refactoring Test Code
• Mock Object
 • override
 • Google C++ Mocking Framework!
Refactoring Test Code
• UnitTestHelper
 –                            Helper
                  .
 –   ) GUTHelper_NPC::SpawnNPC()
Refactoring Test Code
•                         Fixture
                      .
    class FBasePlayer;
    class FBaseItem;
    class FBaseNPC;
    class FBaseMap;
    class FBaseNetClient;
Refactoring Test Code
•                           Fixture
                        .
class FForCombatTest : public FBaseMockLink,
                      public FBaseNetClient,
                      public FBasePlayer,
                      public FBaseMap,
                      public FBaseMapMgr,
                      public FBasePlayer
{
…
};
Refactoring Test Code
Class Fduel  // Fixture
{
…
  void CHECK_DuelCancel()
  {
     CHECK_EQUAL(m_pLinkRequester->GetCommand(0).GetID(), MC_DUEL_CANCEL);
     CHECK_EQUAL(m_pLinkTarget->GetCommand(0).GetID(), MC_DUEL_CANCEL);
  }

    void CHECK_DuelFinished(CPlayer* pWinner, CPlayer* pLoser)
    {
       MockLink* pWinnerLink = (pWinner==m_pPlayerRequester) ? M_pLinkRequester : m_pLinkT
       const Mcommand& Command = pWinnerLink->GetCommand();
       CHECK_EQUAL(Command.GetID(), MC_DUEL_FINISHED);

        int nWinnerID, nLoserID;
        Command.GetParam(&nWinnerID, 0, MPT_INT);
        Command.GetParam(&nLoserID, 0, MPT_INT);

        CHECK_EQUAL(nWinnerID, pWinner->GetID());
        CHECK_EQUAL(nLoserID, pLoser->GetID());
    }
}
Refactoring Test Code
TEST_FIXTURE(FDuel, DuelQuestionRefuse)
{
  CHECK_EQUAL(gmgr.pDuelMgr->GetCount(), 0);
  DuelRequest();

    CHECK_EQUAL(gmgr.pDuelMgr->GetCount(), 1);
    BeginCommandRecord();

    DuelResponse(false);

    CHECK_DuelCancel();
}
Database Unit Test
• 저장 프로시저, 트리거 등에 대한 유닛 테스
  트
• xDBUnit 프레임워크가 있지만 자체적으로
  작성했다.
 – UnitTest++ 사용
Database Unit Test
• 테스트 단계
 1. SandBox에 데이터베이스, Table, SP 등 생성
 2. 테스트에 필요한 데이터 집합(Seed Dataset)
    을 생성
 3. 테스트 케이스 실행
 4. 데이터 변경 검증
Seed DataSet
Unit Test Code
DBTEST(FGuildDB, CreateGuild)
{
  UTestDB.Seed(“GuildTestSeedData.xml”);

    uint32 nMasterCID = DBTestHelper::GetCID(“Acc5Char1”);
    uint32 nMem1 = DBTestHelper::GetCID(“Acc5Char2”);
    uint32 nMem2 = DBTestHelper::GetCID(“Acc5Char3”);

    CHECK((0 != nMasterCID) && (0 != nMem1) && (0 != nMem2));

    // 길드 생성
    TDBRecordSet rs1;
    UTestDB.Execute(rs1, “{CALL spGuildCreate (‘%S’, %d)}”, “TGuild4”, nMasterCID);


    int nGID = rs1.Field(“GID”).AsInt();
    CHECK(0 != nGID);

    // 길드가 추가되었는지 레코드 개수 확인
    TDBRecordSet rs2;
    UTestDB.Execute(rs2, “SELECT COUNT(*) AS cnt FROM dbo.Guild;”);
    CHECK_EQUAL(1, rs2.GetFetchedCount());
    CHECK_EQUAL(1, rs2.Field(“cnt”).AsInt());
}
• 특정 씬을 렌더링하여 원본 이미지와 같은
  이미지인지 픽셀별로 비교하여 같은 픽셀
  값인지 테스트
• 렌더링에 대한 UnitTest를 만들지 못하여
  나온 대안
• 랜덤 요소 제거 등의 추가 작업이 필요함
•
•
•
•
•
Recv
 Replay                              Send
 Packet
 Queue         Command Queue        Packet

 Local
                                    Local
 Event
                               복사
                                    Replay
                                    Queue




커맨드 구조    ID         Data
Resource Validator
• 기획자나 아티스트가 작업한 게임 데이터
  (Assets)에 논리적으로 잘못된 값이 입력되
  었는지 검증
• 예시
 –   상점 인터랙션이 설정된 NPC는 비전투형인가?
 –   아이템 판매 가격이 구매 가격보다 높은가?
 –   몬스터에 설정된 스킬 애니메이션 파일이 존재하는가?
 –   맵의 포탈에 연결된 맵이 실재로 존재하는가?
Resource Validator
• XML             Schema
•

•
Resource Validator
Runtime Validator
•

•
    – DB
    –
    – AI
    – Assertion
Runtime Validator
•                       XML
                .
    –
        •   ,       ,     ,
    –
•
• Crash
AI
•

•
    – Crash
    –
Crash Dump Reporter
Crash Dump Analyzer
•

•
•
Crash Dump Analyzer
•
•
• WinDbg   Command-Line

•
Crash Dump Analyzer
Crash Dump Analyzer
?
1.

2.

3.
Q/A
             birdkr@gmail.com
      http://mypage.sarang.net

Más contenido relacionado

La actualidad más candente

The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 51 of 88
The Ring programming language version 1.3 book - Part 51 of 88The Ring programming language version 1.3 book - Part 51 of 88
The Ring programming language version 1.3 book - Part 51 of 88Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 87 of 202
The Ring programming language version 1.8 book - Part 87 of 202The Ring programming language version 1.8 book - Part 87 of 202
The Ring programming language version 1.8 book - Part 87 of 202Mahmoud Samir Fayed
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++Dimitrios Platis
 
Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Alexey Lesovsky
 
The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 38 of 212
The Ring programming language version 1.10 book - Part 38 of 212The Ring programming language version 1.10 book - Part 38 of 212
The Ring programming language version 1.10 book - Part 38 of 212Mahmoud Samir Fayed
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Philip Zhong
 
Mysql handle socket
Mysql handle socketMysql handle socket
Mysql handle socketPhilip Zhong
 
Numerical Methods with Computer Programming
Numerical Methods with Computer ProgrammingNumerical Methods with Computer Programming
Numerical Methods with Computer ProgrammingUtsav Patel
 
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅재춘 노
 
Mysql5.1 character set testing
Mysql5.1 character set testingMysql5.1 character set testing
Mysql5.1 character set testingPhilip Zhong
 
The Ring programming language version 1.5.3 book - Part 88 of 184
The Ring programming language version 1.5.3 book - Part 88 of 184The Ring programming language version 1.5.3 book - Part 88 of 184
The Ring programming language version 1.5.3 book - Part 88 of 184Mahmoud Samir Fayed
 
Maximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestMaximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestPythian
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven DevelopmentAgileOnTheBeach
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196Mahmoud Samir Fayed
 

La actualidad más candente (20)

The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185
 
The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181
 
The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189
 
The Ring programming language version 1.3 book - Part 51 of 88
The Ring programming language version 1.3 book - Part 51 of 88The Ring programming language version 1.3 book - Part 51 of 88
The Ring programming language version 1.3 book - Part 51 of 88
 
The Ring programming language version 1.8 book - Part 87 of 202
The Ring programming language version 1.8 book - Part 87 of 202The Ring programming language version 1.8 book - Part 87 of 202
The Ring programming language version 1.8 book - Part 87 of 202
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
 
Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.
 
The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181
 
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212
 
The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184
 
The Ring programming language version 1.10 book - Part 38 of 212
The Ring programming language version 1.10 book - Part 38 of 212The Ring programming language version 1.10 book - Part 38 of 212
The Ring programming language version 1.10 book - Part 38 of 212
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8
 
Mysql handle socket
Mysql handle socketMysql handle socket
Mysql handle socket
 
Numerical Methods with Computer Programming
Numerical Methods with Computer ProgrammingNumerical Methods with Computer Programming
Numerical Methods with Computer Programming
 
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
 
Mysql5.1 character set testing
Mysql5.1 character set testingMysql5.1 character set testing
Mysql5.1 character set testing
 
The Ring programming language version 1.5.3 book - Part 88 of 184
The Ring programming language version 1.5.3 book - Part 88 of 184The Ring programming language version 1.5.3 book - Part 88 of 184
The Ring programming language version 1.5.3 book - Part 88 of 184
 
Maximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestMaximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digest
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven Development
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196
 

Similar a 생산적인 개발을 위한 지속적인 테스트

Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneDroidConTLV
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
Testing in those hard to reach places
Testing in those hard to reach placesTesting in those hard to reach places
Testing in those hard to reach placesdn
 
Unit test candidate solutions
Unit test candidate solutionsUnit test candidate solutions
Unit test candidate solutionsbenewu
 
Chainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたChainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたAkira Maruoka
 
Transaction Management Tool
Transaction Management ToolTransaction Management Tool
Transaction Management ToolPeeyush Ranjan
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeLaurence Svekis ✔
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и DjangoMoscowDjango
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)Thomas Fan
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 

Similar a 생산적인 개발을 위한 지속적인 테스트 (20)

Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
Batch processing Demo
Batch processing DemoBatch processing Demo
Batch processing Demo
 
Qtp test
Qtp testQtp test
Qtp test
 
Testing in those hard to reach places
Testing in those hard to reach placesTesting in those hard to reach places
Testing in those hard to reach places
 
Unit test candidate solutions
Unit test candidate solutionsUnit test candidate solutions
Unit test candidate solutions
 
Chainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたChainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみた
 
Transaction Management Tool
Transaction Management ToolTransaction Management Tool
Transaction Management Tool
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
 
Ac2
Ac2Ac2
Ac2
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)
Pydata DC 2018 (Skorch - A Union of Scikit-learn and PyTorch)
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 

Más de 기룡 남

GAN을 이용한 캐릭터 리소스 제작 맛보기
GAN을 이용한 캐릭터 리소스 제작 맛보기GAN을 이용한 캐릭터 리소스 제작 맛보기
GAN을 이용한 캐릭터 리소스 제작 맛보기기룡 남
 
NDC 2015 게임 스타트업 시작하기
NDC 2015 게임 스타트업 시작하기NDC 2015 게임 스타트업 시작하기
NDC 2015 게임 스타트업 시작하기기룡 남
 
게임 스타트업 시작하기 두달 후
게임 스타트업 시작하기 두달 후게임 스타트업 시작하기 두달 후
게임 스타트업 시작하기 두달 후기룡 남
 
게임 스타트업 시작하기
게임 스타트업 시작하기게임 스타트업 시작하기
게임 스타트업 시작하기기룡 남
 
마쉬멜로우 첼린지
마쉬멜로우 첼린지마쉬멜로우 첼린지
마쉬멜로우 첼린지기룡 남
 
레이더즈 기술 사례
레이더즈 기술 사례레이더즈 기술 사례
레이더즈 기술 사례기룡 남
 
Ignite Maiet 14 마이에트야구단
Ignite Maiet 14 마이에트야구단Ignite Maiet 14 마이에트야구단
Ignite Maiet 14 마이에트야구단기룡 남
 
Ignite Maiet 12 누구나 쉽게 만드는 음악
Ignite Maiet 12 누구나 쉽게 만드는 음악Ignite Maiet 12 누구나 쉽게 만드는 음악
Ignite Maiet 12 누구나 쉽게 만드는 음악기룡 남
 
Ignite Maiet 10 두근두근사파리 제작후기2
Ignite Maiet 10 두근두근사파리 제작후기2Ignite Maiet 10 두근두근사파리 제작후기2
Ignite Maiet 10 두근두근사파리 제작후기2기룡 남
 
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기기룡 남
 
Ignite Maiet 03 순정만화를 게임으로 재현하기
Ignite Maiet 03 순정만화를 게임으로 재현하기Ignite Maiet 03 순정만화를 게임으로 재현하기
Ignite Maiet 03 순정만화를 게임으로 재현하기기룡 남
 
Rapid Development
Rapid DevelopmentRapid Development
Rapid Development기룡 남
 
refactoring database
refactoring databaserefactoring database
refactoring database기룡 남
 
Continuous Test
Continuous TestContinuous Test
Continuous Test기룡 남
 
KGC2007 Scrum And Xp
KGC2007 Scrum And XpKGC2007 Scrum And Xp
KGC2007 Scrum And Xp기룡 남
 
Game AI Overview
Game AI OverviewGame AI Overview
Game AI Overview기룡 남
 
Gunz Postmortem
Gunz PostmortemGunz Postmortem
Gunz Postmortem기룡 남
 
Responding to change
Responding to changeResponding to change
Responding to change기룡 남
 

Más de 기룡 남 (19)

GAN을 이용한 캐릭터 리소스 제작 맛보기
GAN을 이용한 캐릭터 리소스 제작 맛보기GAN을 이용한 캐릭터 리소스 제작 맛보기
GAN을 이용한 캐릭터 리소스 제작 맛보기
 
NDC 2015 게임 스타트업 시작하기
NDC 2015 게임 스타트업 시작하기NDC 2015 게임 스타트업 시작하기
NDC 2015 게임 스타트업 시작하기
 
게임 스타트업 시작하기 두달 후
게임 스타트업 시작하기 두달 후게임 스타트업 시작하기 두달 후
게임 스타트업 시작하기 두달 후
 
게임 스타트업 시작하기
게임 스타트업 시작하기게임 스타트업 시작하기
게임 스타트업 시작하기
 
마쉬멜로우 첼린지
마쉬멜로우 첼린지마쉬멜로우 첼린지
마쉬멜로우 첼린지
 
레이더즈 기술 사례
레이더즈 기술 사례레이더즈 기술 사례
레이더즈 기술 사례
 
Pm
PmPm
Pm
 
Ignite Maiet 14 마이에트야구단
Ignite Maiet 14 마이에트야구단Ignite Maiet 14 마이에트야구단
Ignite Maiet 14 마이에트야구단
 
Ignite Maiet 12 누구나 쉽게 만드는 음악
Ignite Maiet 12 누구나 쉽게 만드는 음악Ignite Maiet 12 누구나 쉽게 만드는 음악
Ignite Maiet 12 누구나 쉽게 만드는 음악
 
Ignite Maiet 10 두근두근사파리 제작후기2
Ignite Maiet 10 두근두근사파리 제작후기2Ignite Maiet 10 두근두근사파리 제작후기2
Ignite Maiet 10 두근두근사파리 제작후기2
 
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기
Ignite Maiet 07 칵테일과 함께 훈남훈녀 되기
 
Ignite Maiet 03 순정만화를 게임으로 재현하기
Ignite Maiet 03 순정만화를 게임으로 재현하기Ignite Maiet 03 순정만화를 게임으로 재현하기
Ignite Maiet 03 순정만화를 게임으로 재현하기
 
Rapid Development
Rapid DevelopmentRapid Development
Rapid Development
 
refactoring database
refactoring databaserefactoring database
refactoring database
 
Continuous Test
Continuous TestContinuous Test
Continuous Test
 
KGC2007 Scrum And Xp
KGC2007 Scrum And XpKGC2007 Scrum And Xp
KGC2007 Scrum And Xp
 
Game AI Overview
Game AI OverviewGame AI Overview
Game AI Overview
 
Gunz Postmortem
Gunz PostmortemGunz Postmortem
Gunz Postmortem
 
Responding to change
Responding to changeResponding to change
Responding to change
 

Último

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 

Último (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 

생산적인 개발을 위한 지속적인 테스트

  • 2. ?
  • 3.
  • 4.
  • 8. ?
  • 9. 1. . 2. . 3. , .
  • 10. 테스트 결과 로그 <?xml version="1.0"?> <maiettest-results tests=“2" failedtests=“1" failures="1" time="0.137"> <report text="time : 680 sec" /> <report text=“총 클라이언트 개수 : 4650" /> <test name=“로그인 반복" time="0.062" > <success message="success" /> </test> <test name=“캐릭터 생성 반복" time="0.062" > <failure message="Crash!" /> </test> </maiettest-results>
  • 11. 테스트 결과 로그 • 테스트 결과를 XML로 만들고, XSL을 이용 하여 CruseControl.NET에 출력한다.
  • 13.
  • 15. Unit Test TEST(TestMathFunctionTruncateToInt) { CHECK_EQUAL(0, GMath::TruncateToInt(0.0)); CHECK_EQUAL(5, GMath::TruncateToInt(5.6)); CHECK_EQUAL(13, GMath::TruncateToInt(13.2)); CHECK_EQUAL(13, GMath::TruncateToInt(13.2)); CHECK_EQUAL(-6, GMath::TruncateToInt(-5.6)); CHECK_EQUAL(-3, GMath::TruncateToInt(-2.1)); }
  • 16. Unit Test TEST(ShieldCanBeDamaged) { World world; world.Create(); Player player; player.Create(world, vec3(1000,1000,0)); player.SetHealth(1000); Shield shield; shield.SetHealth(100); player.Equip(shield); player.Damage(200); CHECK(shield.GetHealth() == 0); CHECK(player.GetHealth() == 900); }
  • 18. Unit Test TEST_FIXTURE(FLogin, TestLogin_MC_COMM_REQUEST_LOGIN_SERVER_Success) { MakeParam_TD_LOGIN_INFO(); TD_LOGIN_INFO tdLoginInfo = MakeParam_TD_LOGIN_INFO(); OnRecv_MMC_COMM_REQUEST_LOGIN_SERVER(m_nRequestID, m_nConnectionKey, &tdLoginInfo tdLoginInfo); OnRecv_MMC_COMM_REQUEST_LOGIN_SERVER(m_nRequestID, m_nConnectionKey, &tdLoginInfo); // 로그인 하기 전의 값 체크 CHECK_EQUAL(0, gmgr.pPlayerObjectManager->GetPlayersCount()); // 클라이언트로부터 존 입장 패킷 받음 OnRecv_MC_COMM_REQUEST_LOGIN_SERVER(m_nConnectionKey); OnRecv_MC_COMM_REQUEST_LOGIN_SERVER(m_nConnectionKey); // 마스터 서버로 인증키 확인 패킷 보냈는지 체크 CHECK_EQUAL(MC_COMM_RESPONSE_LOGIN_SERVER, m_pLink- GetCommandID(0)); CHECK_EQUAL(MC_COMM_RESPONSE_LOGIN_SERVER, m_pLink->GetCommandID(0)); CHECK_EQUAL(RESULT_SUCCESS, m_pLink- GetParam<int>(0, CHECK_EQUAL(RESULT_SUCCESS, m_pLink->GetParam<int>(0, 0)); CHECK_EQUAL(m_pLink->GetUID(), m_pLink->GetParam<MUID>(0, 1)); CHECK_EQUAL(m_pLink- GetUID(), m_pLink- GetParam<MUID>(0, // 로그인 후 값 체크 CHECK_EQUAL(1, gmgr.pPlayerObjectManager->GetPlayersCount()); GPlayerObject* pPlayerObject = gmgr.pPlayerObjectManager->GetPlayer(m_pLink->GetUID()); CHECK(pPlayerObject != NULL); CHECK_EQUAL(m_nGUID, pPlayerObject->GetAccountInfo().nGUID); CHECK_EQUAL(string(“birdkr”), string(pPlayerObject->GetAccountInfo().strID)); }
  • 19. Mock Object class MockPlayer : public GPlayer { public: MockPlayer() {}; virtual ~ MockPlayer() {}; … virtual void SendToThisSector (MPacket* pPacket) override { } virtual void SendToMe(MPacket * pPacket) override { } virtual void SendToGuild(MPacket* pPacket) override { } … };
  • 20. , class XSystem { public: virtual unsigned int GetNowTime() { return timeGetTime() timeGetTime()(); } virtual int RandomNumber(int nMin, int nMax) { return (rand() % (nMax - nMin + 1)) + nMin; rand() rand } };
  • 21. , class MockSystem : public XSystem { protected: unsigned int m_nExpectedNowTime; public: virtual unsigned int GetNowTime() { if (m_nExpectedNowTime != 0) return m_nExpectedNowTime; return XSystem::GetNowTime(); } void ExpectNowTime(unsigned int nNowTime) { m_nExpectedNowTime = nNowTime; } };
  • 22. , TEST_FIXTURE(FPlayerInOut2, TestObjectCacheDelete) { vec3 vNewPos = vec3(100.0f, 100.0f, 0.0f); CHECK_EQUAL(2, gg.omgr->GetCount()); m_pNet->OnRecv( MC_ENTITY_WARP, 3, NEW_ID(m_pMyPlayer->GetID Update(0.1f); CHECK_CLOSE(100.0f, m_pMyPlayer->GetPosition().x, 0.001f); CHECK_CLOSE(100.0f, m_pMyPlayer->GetPosition().y, 0.001f); XExpectNowTime(XGetNowTime() + 10000 ); Update(10.0f); // 멀리 있는 다른 플레이어가 지워졌다. CHECK_EQUAL(1, gg.omgr->GetCount()); }
  • 23. , template <class Type> class GTestMgrWrapper : public MInstanceChanger<Type> { public: GTestMgrWrapper() : MInstanceChanger() { m_pOriginal = gmgr.Change(m_pTester); } ~GTestMgrWrapper() { gmgr.Change(m_pOriginal); } };
  • 24. , TEST_FIXTURE(FChangeMode, TestNPC_SightRange) { GTestMgrWrapper<GNPCInfoMgr> m_NPCInfoMgrWrapper; m_NPCInfo.nSightRange = 1000; GNPC* pNPC = m_pMap->SpawnTestNPC(&m_NPCInfo); CHECK_EQUAL(1000, pNPC->GetSightRange()); pNPC->ChangeMode(NPC_MODE_1); CHECK_EQUAL(500, pNPC->GetSightRange()); }
  • 25. Refactoring Test Code • Mock Object • override • Google C++ Mocking Framework!
  • 26. Refactoring Test Code • UnitTestHelper – Helper . – ) GUTHelper_NPC::SpawnNPC()
  • 27. Refactoring Test Code • Fixture . class FBasePlayer; class FBaseItem; class FBaseNPC; class FBaseMap; class FBaseNetClient;
  • 28. Refactoring Test Code • Fixture . class FForCombatTest : public FBaseMockLink, public FBaseNetClient, public FBasePlayer, public FBaseMap, public FBaseMapMgr, public FBasePlayer { … };
  • 29. Refactoring Test Code Class Fduel // Fixture { … void CHECK_DuelCancel() { CHECK_EQUAL(m_pLinkRequester->GetCommand(0).GetID(), MC_DUEL_CANCEL); CHECK_EQUAL(m_pLinkTarget->GetCommand(0).GetID(), MC_DUEL_CANCEL); } void CHECK_DuelFinished(CPlayer* pWinner, CPlayer* pLoser) { MockLink* pWinnerLink = (pWinner==m_pPlayerRequester) ? M_pLinkRequester : m_pLinkT const Mcommand& Command = pWinnerLink->GetCommand(); CHECK_EQUAL(Command.GetID(), MC_DUEL_FINISHED); int nWinnerID, nLoserID; Command.GetParam(&nWinnerID, 0, MPT_INT); Command.GetParam(&nLoserID, 0, MPT_INT); CHECK_EQUAL(nWinnerID, pWinner->GetID()); CHECK_EQUAL(nLoserID, pLoser->GetID()); } }
  • 30. Refactoring Test Code TEST_FIXTURE(FDuel, DuelQuestionRefuse) { CHECK_EQUAL(gmgr.pDuelMgr->GetCount(), 0); DuelRequest(); CHECK_EQUAL(gmgr.pDuelMgr->GetCount(), 1); BeginCommandRecord(); DuelResponse(false); CHECK_DuelCancel(); }
  • 31. Database Unit Test • 저장 프로시저, 트리거 등에 대한 유닛 테스 트 • xDBUnit 프레임워크가 있지만 자체적으로 작성했다. – UnitTest++ 사용
  • 32. Database Unit Test • 테스트 단계 1. SandBox에 데이터베이스, Table, SP 등 생성 2. 테스트에 필요한 데이터 집합(Seed Dataset) 을 생성 3. 테스트 케이스 실행 4. 데이터 변경 검증
  • 34. Unit Test Code DBTEST(FGuildDB, CreateGuild) { UTestDB.Seed(“GuildTestSeedData.xml”); uint32 nMasterCID = DBTestHelper::GetCID(“Acc5Char1”); uint32 nMem1 = DBTestHelper::GetCID(“Acc5Char2”); uint32 nMem2 = DBTestHelper::GetCID(“Acc5Char3”); CHECK((0 != nMasterCID) && (0 != nMem1) && (0 != nMem2)); // 길드 생성 TDBRecordSet rs1; UTestDB.Execute(rs1, “{CALL spGuildCreate (‘%S’, %d)}”, “TGuild4”, nMasterCID); int nGID = rs1.Field(“GID”).AsInt(); CHECK(0 != nGID); // 길드가 추가되었는지 레코드 개수 확인 TDBRecordSet rs2; UTestDB.Execute(rs2, “SELECT COUNT(*) AS cnt FROM dbo.Guild;”); CHECK_EQUAL(1, rs2.GetFetchedCount()); CHECK_EQUAL(1, rs2.Field(“cnt”).AsInt()); }
  • 35. • 특정 씬을 렌더링하여 원본 이미지와 같은 이미지인지 픽셀별로 비교하여 같은 픽셀 값인지 테스트 • 렌더링에 대한 UnitTest를 만들지 못하여 나온 대안 • 랜덤 요소 제거 등의 추가 작업이 필요함
  • 37. Recv Replay Send Packet Queue Command Queue Packet Local Local Event 복사 Replay Queue 커맨드 구조 ID Data
  • 38. Resource Validator • 기획자나 아티스트가 작업한 게임 데이터 (Assets)에 논리적으로 잘못된 값이 입력되 었는지 검증 • 예시 – 상점 인터랙션이 설정된 NPC는 비전투형인가? – 아이템 판매 가격이 구매 가격보다 높은가? – 몬스터에 설정된 스킬 애니메이션 파일이 존재하는가? – 맵의 포탈에 연결된 맵이 실재로 존재하는가?
  • 39. Resource Validator • XML Schema • •
  • 41. Runtime Validator • • – DB – – AI – Assertion
  • 43. XML . – • , , , – • • Crash
  • 44. AI • • – Crash –
  • 47. Crash Dump Analyzer • • • WinDbg Command-Line •
  • 50. ?
  • 52.
  • 53. Q/A birdkr@gmail.com http://mypage.sarang.net