이 문서에서는 Unity를 사용하여 보다 안정적인 프로젝트를 출시하는 데 도움이 되는 다양한 테스트 사례에 대해 소개합니다.
테스트 또는 품질 보증(QA)은 게임 개발 주기 전반에 걸쳐 실행되어야 하는 중요한 프로세스입니다. 숙련된 개발자라면 누구나 알고 있듯이 작성하는 모든 코드는 테스트가 필요합니다.
독립 개발자이든 대규모 팀의 일원이든(기존 스튜디오에는 전담 QA 엔지니어가 있는 경우가 많습니다) 사용할 수 있는 다양한 테스트 및 QA 방법이 있습니다.
스포츠를 플레이하거나 시청하는 것을 좋아한다면 많은 경기에서 우승의 승패는 수비라는 것을 알고 있을 것입니다. QA 프로세스는 최고의 성능과 안정성을 갖춘 게임을 출시하기 위한 방어 전략이라고 생각하면 됩니다.
테스트는 코드의 버그, 아트워크의 시각적 아티팩트, 게임 디자인 및 게임플레이의 사용자 경험 문제와 같은 문제를 발견하는 데 매우 중요합니다. 기술적으로 아무리 뛰어난 게임을 개발해도 10번 중 9번 이상 충돌이 발생한다면 사용자들은 금방 게임을 포기하게 될 것입니다.
게임 개발 프로세스가 끝날 때까지 테스트를 미루지 마세요. 테스트를 시퀀스의 한 단계로 생각하기보다는 게임 개발의 다른 단계를 뒷받침하는 지속적인 프로세스로 보는 것이 도움이 될 수 있습니다. 제작 과정과 출시 전에 아이디어와 프로토타입을 테스트하세요. 게임을 업데이트할 때마다 이 과정을 반복합니다.
프로젝트의 여러 단계에 더 적합한 다양한 테스트 기법이 있습니다.
전담 QA 팀이 없는 소규모 스튜디오의 일원이신가요? 테스트를 도와줄 친구로 구성된 작업 그룹을 구성하거나 타사 QA 제공업체를 선택하여 도움을 받을 수 있습니다. 사내 QA 팀이 있는 스튜디오도 로컬라이제이션 테스트(LQA)와 같은 추가 테스트 서비스를 위해 외부 업체를 이용하는 경우가 많습니다.
플레이어 테스트는 QA의 하위 집합으로 볼 수 있으며, 게임이 타겟 고객과 시장의 공감을 얻을 수 있도록 도와줍니다. 개발 단계에서 게임을 개선하기 위해 플레이어로부터 귀중한 피드백을 얻을 수 있는 프로세스입니다.
플레이어 테스트에 참여해야 하는 사람은 테스트의 구체적인 목표에 따라 달라집니다. 하지만 일반적으로 게임의 타겟 고객을 대표하는 다양한 플레이어 그룹을 참여시키는 것이 중요합니다. 게임 개발자는 플레이어 테스트에 다양한 유형의 플레이어를 참여시킴으로써 다양한 관점에서 피드백을 수집하고 게임이 광범위한 사용자에게 어필할 수 있도록 할 수 있습니다.
다음 섹션에서는 일반적인 테스트 기법에 대해 알아볼 수 있습니다. 이러한 방법을 결합하여 코드베이스가 최대한 원활하게 작동하도록 할 수 있습니다.
타겟 플랫폼 내 다양한 기기에서 게임을 테스트하는 것도 중요합니다. 이는 특히 모바일 게임에 적용되며, 다양한 운영 체제, 화면 크기, 최저 사양의 모바일 기기에서 테스트해야 합니다. 이렇게 하면 최소 장치 요구 사항을 벤치마킹하는 데 도움이 되며, 애플리케이션에 기능을 추가할 때 각 카테고리를 지속적으로 재검토해야 합니다.
다양한 플랫폼에서의 테스트는 게임을 망칠 수 있는 잠재적인 문제를 파악하는 것뿐만 아니라 모바일 게임의 배터리 소모나 열 과열과 같은 장기적이거나 간접적인 영향을 파악하는 데에도 중요합니다.
유닛 테스트는 게임의 개별 유닛이나 구성 요소를 개별적으로 테스트하는 기법으로, 개발 프로세스 초기에 버그를 발견하고 코드 변경으로 인해 기존 기능이 손상되지 않도록 하는 데 도움이 됩니다.
단위 테스트는 코드의 특정 동작을 실행하는 작은 테스트 케이스를 작성하여 수행합니다. 테스트는 개별 스크립트, 게임 오브젝트 또는 게임의 특정 기능에 대해 실행할 수 있습니다.
게임 개발에는 수동 및 자동화된 단위 테스트 방법을 모두 사용해야 합니다.
수동 단위 테스트
수동 테스트는 사람들이 직접 게임을 플레이하여 게임의 기능을 테스트하는 것입니다. UI 버그나 불균형하거나 제대로 실행되지 않는 게임플레이 또는 디자인 등 자동화된 테스트에서 발견하지 못하는 문제가 있을 수 있으므로 수동 테스트를 실행하는 것이 중요합니다.
Unity에서 수동 단위 테스트의 예로는 함수에 대한 테스트 조건을 추가하고 Debug.Log를 사용하여 통과 또는 실패 기준(테스트 시나리오의 출력)을 Unity의 플레이 모드를 사용하여 출력하는 것이 있습니다.
자동화된 단위 테스트
자동화된 단위 테스트는 개별 단위 또는 코드 조각을 개별적으로 자동 테스트하는 코드를 작성해야 합니다. Unity에서는 테스트 스위트의 일부로 실행할 수 있는 스크립트, 컴포넌트 및 기타 게임 코드 단위에 대한 테스트를 작성할 수 있습니다.
UTF( Unity 테스트 프레임워크 ) 패키지는 개발자가 Unity 에디터의 편집 및 플레이 모드에서 자체 자동화된 테스트를 작성할 수 있는 프레임워크를 제공합니다. UTF는 NUnit을 참조하는 모든 어셈블리 내에서 테스트를 찾습니다. 이러한 어셈블리를 테스트 어셈블리라고 합니다. 플레이 모드와 편집 모드 테스트는 별도의 어셈블리에 있어야 합니다.
UTF는 에디터에서 테스트 사례를 실행하고 관리하는 데 도움이 되는 테스트 러너 창을 제공합니다.
UTF는 테스트 어셈블리 정의를 사용하므로 프로젝트를 런타임 어셈블리 정의로 세분화해야 합니다. 이는 개발 프로세스 초기에 계획하면 더 쉽게 수행할 수 있으며, 모듈식 코드를 더 많이 작성하도록 장려합니다.
Unity 패키지인 퍼포먼스 테스트 익스텐션은 UTF와 함께 사용할 수 있는 확장 기능입니다. 테스트 사례에서 측정하고 사용자 지정 메트릭을 제공하기 위한 추가 API를 제공합니다.
비디오 게임 개발을 위한 Unity 테스트 프레임워크 튜토리얼을 읽고 Unity 테스트 프레임워크를 시작하는 방법을 알아보세요.
테스트 중심 개발(TDD)은 특정 기능을 구현하기 위해 실제 코드를 작성하기 전에 해당 기능에 대한 테스트를 작성하는 기법입니다. 이 프로세스에는 일반적으로 실패한 테스트를 작성하고, 테스트를 통과하는 데 필요한 최소한의 코드를 작성한 다음, 다음 테스트 케이스를 설계하기 전에 유지 관리가 용이하도록 코드를 리팩토링하는 과정이 포함됩니다.
TTD는 게임 개발에서는 매우 드문 경우입니다(주류 소프트웨어 개발에서는 더 일반적입니다). 이는 아마도 재미있고 매력적인 게임플레이를 프로토타이핑하고 제작하는 데 있어 직관적이지 않은 과정이기 때문일 것입니다.
그러나 게임을 깨는 변경 사항은 즉시 실패한 테스트 케이스를 생성하기 때문에 게임의 깨진 부분을 식별하는 프로세스의 속도를 높일 수 있습니다.
Unity의 TDD에 대한 자세한 내용은 블로그 게시물 "Unity 테스트 러너로 테스트 중심 개발 테스트"를 참조하세요.
코드 커버리지
TDD 또는 단위 테스트를 구현하려면 Unity 코드 커버리지 패키지를 사용하는 것이 좋습니다. UTF와 함께 사용하면 코드 커버리지 패키지를 통해 프로젝트의 어떤 코드 줄이 테스트되고 있는지 표시하여 프로젝트에서 취약하거나 테스트되지 않은 부분을 식별할 수 있습니다.
코드 커버리지는 플레이 모드에서 게임을 테스트하는 동안 보고서를 생성할 수도 있습니다. 이렇게 하면 단위 테스트에서 다루지 않더라도 정기적으로 테스트를 실행하는 코드의 일부가 표시됩니다. 그러나 코드 커버리지 보고서는 테스트에서 어떤 코드 줄을 다루었는지는 보여주지만, 코드에서 로직이 어떤 경로를 통해 이동했는지는 보여주지 않습니다.
블로그 게시물 "코드 적용 범위를 참조하세요: 테스트에서 부족한 부분을 찾아보세요" 자세한 내용을 확인하세요.
통합 테스트는 시스템의 여러 구성 요소를 함께 테스트하여 올바르게 작동하는지 확인하는 기술입니다. 여기에는 게임 내에서 서로 다른 게임 오브젝트, 스크립트 또는 시스템이 어떻게 상호 작용하는지 테스트하는 것이 포함될 수 있습니다. 통합 테스트는 범위가 넓기 때문에 데이터 흐름이나 컴포넌트 간의 통신 문제 등 단위 테스트에서는 나타나지 않을 수 있는 버그를 발견하는 데 도움이 될 수 있습니다.
예를 들어, 개별 단위 테스트를 사용하는 대신 플레이어가 무기를 발사하여 총알을 인스턴스화하고, 총알이 적을 명중시켜 죽이고, 플레이어가 적을 죽이면 점수를 얻고, 특정 점수에 도달하면 업적이 잠금 해제되는 이 전체 시퀀스에 대한 통합 테스트를 작성할 수 있습니다.
UTF를 사용하여 Unity에서 통합 테스트를 빌드할 수 있습니다. 설정 및 해체 메서드를 사용하여 여러 시스템을 한 번에 테스트할 수 있는 환경을 만들 수 있습니다. 플레이어 로직과 입력을 시뮬레이션할 수 있으며, 특히 커맨드 패턴을 사용하여 구현한 경우(새 입력 시스템을 사용하는 경우라면 이미 구현했을 가능성이 높습니다) 플레이어 입력이 게임 로직으로 전달되는 전체 흐름을 테스트할 수 있습니다.
회귀 테스트는 소프트웨어나 기능이 수정 또는 업데이트된 후 올바르게 작동하는지 검증하는 방법입니다. 회귀 테스트의 목표는 코드베이스의 변경으로 인해 소프트웨어에 새로운 버그나 회귀가 발생하지 않도록 하는 것입니다. 이 기술은 예상치 못한 방식으로 상호 작용할 수 있는 다양한 구성 요소가 있을 수 있는 라이브 게임과 같이 업데이트가 잦은 크고 복잡한 애플리케이션에 가장 적합합니다.
게임 세계와 메커니즘이 확장됨에 따라 회귀 테스트의 필요성도 증가하므로 비용이 많이 들 수 있습니다. 따라서 가능한 한 자동화하는 것이 중요합니다. 회귀 테스트는 특히 여러 플랫폼을 대상으로 하는 경우 새로운 기능 개발과 병행하여 수행해야 합니다.
회귀 테스트는 대규모 라이브 게임에 가장 적합하지만 소프트웨어의 복잡성, 변경 또는 업데이트 빈도, 영향을 받는 기능(미션 또는 안전에 중요한 시스템)의 중요도 등 다른 요인에 따라 그 필요성이 결정되기도 합니다.
기능 테스트는 시스템 또는 소프트웨어 애플리케이션의 기능을 기능 요구 사항에 따라 테스트하여 그 기능을 평가합니다. 여기에는 시스템의 기능, 사용자 인터페이스, 데이터베이스 상호 작용 및 시스템의 동작과 기능에 영향을 미치는 기타 측면을 테스트하는 작업이 포함됩니다. 기능 테스트의 목적은 시스템 또는 애플리케이션이 고객 또는 최종 사용자가 제공한 요구 사항과 사양을 충족하는지 확인하는 것입니다.
대부분의 단위 테스트는 코드의 특정 경로에 초점을 맞춰 특정 입력에 따라 올바른 출력을 반환하는지 테스트합니다. 게임이 의도한 대로 작동하는지 테스트할 수 없습니다.
기능 테스트는 이를 위한 접근 방식입니다. 각 기능이나 특징을 원래 설계와 비교하여 결과물이 기대에 부합하는지 확인합니다. 여기에는 게임의 컨트롤, 게임플레이 메커니즘 및 전반적인 사용자 경험 테스트가 포함될 수 있습니다.
게임을 개발할 때 기능 테스트를 염두에 두고 "이렇게 하면 저렇게 한다"는 접근 방식으로 작업을 만드는 것이 유용할 수 있습니다. 예를 들어 플레이어가 스페이스바를 누르면 캐릭터가 점프해야 합니다: 이는 개발자에게는 기능을 구현하는 방법에 대한 지침이자 테스터가 테스트할 수 있는 허용 기준입니다. 때로는 기능에 사용할 수 있는 경우와 사용할 수 없는 경우 등 몇 가지 관련 허용 기준이 포함될 수 있습니다. 하지만 일반적으로 한 가지 기능에 집중해야 합니다.
기능 테스트는 요구 사항이 명확하게 정의되고 범위가 정해져 있을 때 가장 강력합니다. 따라서 프리랜서나 스튜디오와 계약하여 게임플레이 또는 게임 월드 에셋의 구성 요소를 제공하는 데 유용할 수 있습니다.
자동 및 수동 기능 테스트를 모두 실행할 수 있습니다. '블랙박스' 테스트(시스템 내부 작동에 대한 지식 없이 테스트)와 '화이트박스' 테스트(시스템 내부 작동에 대한 지식이 있는 상태에서 테스트)를 모두 실행해야 합니다.
성능 테스트에는 게임이 다양한 하드웨어 및 소프트웨어 구성에서 원활하고 효율적으로 실행되는지 확인하는 테스트가 포함됩니다. 이는 프로파일링 및 일반적인 성능 최적화 워크플로와 밀접한 관련이 있으며, 게임 성능에 영향을 줄 수 있는 성능 병목 현상이나 문제를 파악하는 데 도움이 될 수 있습니다.
핵심 목표는 다양한 워크로드 조건에서 시스템 또는 애플리케이션의 성능을 평가하는 것입니다. 게임 개발에서 성능 테스트는 게임이 허용 가능한 수준의 성능, 프레임 속도, 응답성 및 안정성으로 실행되는지, 메모리를 가장 효율적으로 사용하는지 여부를 측정합니다.
다양한 유형의 성능 테스트가 있습니다:
- 로드 테스트: 과부하가 걸렸을 때 게임 성능을 결정합니다.
- 스트레스 테스트: 플레이어 활동의 갑작스러운 증가와 같은 예기치 않은 상황을 게임이 어떻게 처리하는지 평가합니다.
- 지구력 테스트: 장기간에 걸쳐 게임의 성능을 평가합니다.
Unity 프로파일러
Unity의 프로파일러 툴은 게임 개발 시 게임 성능을 분석하는 데 도움이 됩니다. 에디터에서 개발하는 동안 개요를 제공하거나 케이블 또는 로컬 네트워크를 통해 컴퓨터에 연결된 모든 기기에서 작동하여 게임이 대상 기기에서 어떻게 실행되는지 정확하게 분석할 수 있습니다.
프로파일러를 확장하여 캡처하려는 데이터의 종류와 프로파일러 창에서 시각적으로 표시되는 방식을 모두 사용자 지정할 수 있습니다.
프로파일러 커스터마이징에 대한 자세한 내용은 Unite 2022 세션 "Unity 프로파일러에서 성능 지표를 커스터마이징하는 방법"에서 알아보세요.
또한 자체 도구를 작성하여 자동화된 성능 테스트를 만들 수도 있습니다. 이에 접근하는 방법에 대한 흥미로운 토론을 보려면 유나이트 2022에서 모뉴먼트 밸리 개발사인 유스투 게임즈의 강연을 살펴보세요: "알바 만들기: 퍼포먼스 높은 오픈월드 게임을 제작하는 방법."
테스트는 버그 발견과 성능 모니터링에만 국한되지 않습니다. 때로는 두 가지 버전의 게임 기능을 비교하여 어떤 기능이 플레이어의 참여를 더 많이 유도하고 더 나은 성과를 내는지 확인하고 싶을 수 있습니다. 이를 A/B 테스트라고 합니다.
A/B 테스트는 게임 밸런스에 영향을 줄 수 있지만 게임 메커니즘은 변경되지 않는 캐릭터나 무기의 능력치를 수정할 때 유용합니다. 다른 예로는 다양한 튜토리얼, 게임 메커니즘 또는 사용자 인터페이스의 효과를 비교하기 위해 실시하는 테스트가 있습니다. 두 그룹에서 수집한 데이터를 분석하여 어떤 버전의 게임이나 기능이 더 효과적인지 파악하고 최종 제품에 어떤 변경 사항을 반영할지 데이터에 기반한 의사 결정을 내릴 수 있습니다.
A/B 테스트는 플레이어를 두 그룹에 무작위로 배정하는 방식으로 진행됩니다: 한 그룹은 게임 또는 기능의 원래 버전을 플레이하고(대조군), 다른 그룹은 게임 또는 기능의 수정된 버전을 플레이합니다(실험군).
핵심은 소수의 플레이어 집단이 다양한 변경 사항에 어떤 영향을 받았는지에 대한 데이터를 수집하여 광범위한 업데이트로 출시할 접근 방식을 결정하는 데 도움이 되도록 설계하는 것입니다.
A/B 테스트는 사용자 경험을 개선하고 플레이어 참여도와 리텐션을 높이는 데 도움이 될 수 있습니다. 사용자 참여도나 리텐션이 조금만 개선되어도 큰 영향을 미칠 수 있는 대규모 사용자 기반을 보유한 게임에 특히 유용합니다.
A/B 테스트는 일반적으로 백엔드 서비스로 제공되며, 플레이어는 다른 변형을 사용하고 있다는 사실조차 인지하지 못합니다. 유니티 게임 서비스(UGS)에는 게임에서 A/B 테스트를 실행하는 데 도움이 되는 툴이 있으며, 자세한 내용은 여기에서 확인할 수 있습니다. 유니티 백엔드 서비스 샘플 모음인 UGS 사용 사례를 확인하여 게임에서 A/B 테스트를 설정하는 방법에 대한 샘플을 살펴볼 수도 있습니다.
클라우드 진단 고급은 백트레이스가 제공하는 크래시 보고 및 분석 툴로, 유니티와 통합되어 개발자에게 게임 내 크래시 및 예외에 대한 자세한 정보를 제공합니다. 크래시가 발생하면 클라우드 진단 고급은 환경, 호출 스택, 힙 및 레지스터에 대한 정보를 포함하여 크래시 발생 당시 게임 상태의 스냅샷을 캡처합니다. 이 스냅샷은 백트레이스 서버로 전송되며, 백트레이스 서버에서는 이를 분석하여 충돌의 근본 원인을 파악합니다.
또한 Cloud 진단 고급은 상세한 분석 및 보고 도구를 제공하여 시간 경과에 따른 게임 성능 및 안정성의 추세와 패턴을 파악하는 데 도움이 됩니다. 중복 제거 알고리즘은 코드의 근본 원인별로 일반적인 충돌을 클러스터링하여 가장 많은 플레이어의 안정성을 향상시키기 위해 먼저 수정해야 할 오류의 우선 순위를 정하는 데 사용할 수 있습니다.
어떤 테스트 기술을 사용하든 게임을 테스트할 방법에 대한 계획을 세우고, 테스트가 개발 프로세스의 필수적인 부분인지 확인하는 것이 중요합니다. 이러한 기술을 조합하여 사용하면 Unity 게임을 최고 품질로 제작하고 바로 제작할 수 있습니다.
이제 프로그래머를 위한 새로운 전자책 시리즈가 유니티에서 무료로 제공됩니다. 각 가이드는 숙련된 프로그래머가 작성했으며 개발팀에 중요한 특정 주제에 대한 모범 사례를 제공합니다.
C# 스타일 가이드를 만듭니다: 확장 가능한 깔끔한 코드 작성 스타일 가이드를 개발하는 팀을 안내하여 보다 일관된 코드베이스를 만들기 위한 접근 방식을 통합하는 데 도움을 줍니다.
게임 프로그래밍 패턴으로 코드 수준 높이기 에서는 SOLID 원칙과 일반적인 프로그래밍 패턴을 사용하여 Unity 프로젝트에서 확장 가능한 게임 코드 아키텍처를 만드는 모범 사례를 소개합니다.
스크립터블 오브젝트로 Unity에서 모듈식 게임 아키텍처 만들기 에서는 게임 제작 시 스크립터블 오브젝트를 배포하는 모범 사례를 제공합니다.
경험이 많은 크리에이터에게 실행 가능한 팁과 영감을 제공하기 위해 이 시리즈를 만들었습니다. 하지만 규칙서가 아닙니다! Unity 프로젝트를 구성하는 방법은 다양하므로 배포하기 전에 동료들과 함께 각 권장 사항, 팁, 패턴의 장단점을 평가해 보세요.
Unity 베스트 프랙티스 허브에서 더 많은 고급 가이드와 문서를 확인하세요.