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

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringWSO2
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxFIDO Alliance
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe中 央社
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceIES VE
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....rightmanforbloodline
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governanceWSO2
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaWSO2
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityVictorSzoltysek
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...caitlingebhard1
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingScyllaDB
 

Último (20)

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using Ballerina
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream Processing
 

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

  • 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