Unity์—์„œ์˜ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋ฐ Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”

2025. 3. 9. 15:54ยท๐Ÿ“‚ Quality Assurance Study/๐Ÿ“„ QA ๊ณต๋ถ€

 

๐Ÿ“Œ Unity Script vs Test Script

ํ•ญ๋ชฉ ์ผ๋ฐ˜์ ์ธ Unity Script (MonoBehaviour) Test Script (NUnit)
๋™์ž‘ ๋ฐฉ์‹ GameObject์˜ Component๋กœ ์ถ”๊ฐ€๋˜์–ด์•ผ ์‹คํ–‰๋จ Test Runner๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰
์‹คํ–‰ ์‹œ์  Unity์˜ Start(), Update() ๋“ฑ์—์„œ ํ˜ธ์ถœ๋จ Test Runner๊ฐ€ SetUp(), Test() ๋“ฑ์„ ํ˜ธ์ถœ
Unity Scene ํ•„์š” ์—ฌ๋ถ€ ํ•„์š” O (Scene์—์„œ ์‹คํ–‰๋จ) ํ•„์š” X (GameObject ์—†์ด๋„ ๋™์ž‘ ๊ฐ€๋Šฅ)

 

+ ์ถ”๊ฐ€ ์ง€์‹

Test Runner

 ~> Unity์—์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” Test Runner ๋„๊ตฌ ์‚ฌ์šฉ

 ~> [ Window ] > [ General ] > [ Test Runner ] ์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ

 

๐Ÿ“Œ Unity Test Framework๋ž€?

Unity Test Framework๋ž€ Unity์—์„œ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” NUnit ๊ธฐ๋ฐ˜์˜ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ผ๋ฐ˜์ ์ธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ถ€ํ„ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ฆ‰, ๋‹จ์ˆœํ•œ ๊ฐœ๋ณ„ ํ•จ์ˆ˜ ๊ฒ€์ฆ๋ถ€ํ„ฐ, ๊ฒŒ์ž„์˜ UI, ๋ฌผ๋ฆฌ ์—”์ง„, ๋„คํŠธ์›Œํฌ, ์„ฑ๋Šฅ ์ตœ์ ํ™” ํ…Œ์ŠคํŠธ๊นŒ์ง€ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด๋‹ค.

 

[ Uniity Test Framwork์˜ ํŠน์ง• ]

โœ… NUnit ๊ธฐ๋ฐ˜

 ~> Assert ๋ฌธ๋ฒ• ์ง€์› (AreEqual(), IsTrue(), IsNull() ๋“ฑ)

 ~> SetUp(), TearDown()์„ ํ™œ์šฉํ•œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ค์ •

โœ… UnityTest() ๋ฅผ ํ™œ์šฉํ•œ MonoBehaviour ํ…Œ์ŠคํŠธ

 ~> ์ผ๋ฐ˜์ ์ธ Test()๋Š” MonoBehaviour ํ…Œ์ŠคํŠธ ๋ถˆ๊ฐ€๋Šฅ

 ~> UnityTest()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋ฃจํ‹ด ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•˜์—ฌ, ํ”„๋ ˆ์ž„ ๋‹จ์œ„ ๋™์ž‘ ๊ฒ€์ฆ ๊ฐ€๋Šฅ

โœ… Edit Mode vs Play Mode

 ~> Edit Mode๋Š” MonoBehaviour ์—†์ด ๋น ๋ฅธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์‹คํ–‰

 ~> Play Mode๋Š” MonoBehaviour๋ฅผ ํฌํ•จํ•œ Physics, UI, Animation, Rigidbody ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ

โœ… CI/CD ์—ฐ๋™ ๊ฐ€๋Šฅ

 ~> Unity CLI(Command Line Interface)๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ž๋™ ์‹คํ–‰ ๊ฐ€๋Šฅ

 ~> GitHub Actions, GitLab CI/CD, Jenkins์™€ ์—ฐ๋™ํ•˜์—ฌ ๋นŒ๋“œ ์•ˆ์ •์„ฑ ํ™•๋ณด ๊ฐ€๋Šฅ

 

[ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ]

โญ ๊ณต์‹ ๋ฌธ์„œ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ก  Test Framework ํŒจํ‚ค์ง€๋Š” Unity 2019.2 ์ดํ›„ ๋ฒ„์ „๋ถ€ํ„ฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, using NUnit.Framework;๋ฅผ ํ†ตํ•ด ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 1๏ธโƒฃ Assembly Definition ํŒŒ์ผ ์ƒ์„ฑ

   ~> ํ…Œ์ŠคํŠธ ํŒŒ์ผ๋“ค์ด ํฌํ•จ๋œ ํด๋” ๋‚ด์—์„œ [ ์˜ค๋ฅธ์ชฝ ๋งˆ์šฐ์Šค ] > [ Create ] > [ Scripting ] > [ Assembly Definition ]

 2๏ธโƒฃ .asmdef ์—์„œ ์ฐธ์กฐ ์ถ”๊ฐ€

   ~> ์ƒ์„ฑ๋œ .asmdef ํŒŒ์ผ์„ ์„ ํƒ

   ~> Inspector ์ฐฝ์—์„œ [ Assembly Definition References ] ์„น์…˜์— UnityEngine.TestRunner์™€ UnityEditor.TestRunner ์ถ”๊ฐ€

 

๐Ÿ“Œ Unity Performance Testing Extension์ด๋ž€?

Unity Performance Testing Extension์ด๋ž€ Unity์—์„œ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ์„ฑ๋Šฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” ํ™•์žฅ ๊ธฐ๋Šฅ์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ”„๋ ˆ์ž„ ์†๋„(FPS), CPU/GPU ์‚ฌ์šฉ๋Ÿ‰, ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๋Ÿ‰, ์ฝ”๋“œ ์‹คํ–‰ ์†๋„ ๋“ฑ์„ ์ธก์ •ํ•˜์—ฌ ๊ฒŒ์ž„์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ํŠน์ • ๊ธฐ๋Šฅ์˜ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋ถ„์„ํ•˜๊ณ , ์ฝ”๋“œ ๋ณ€๊ฒฝ ์ „ํ›„ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•˜์—ฌ ์ตœ์ ํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๋„๊ตฌ์ด๋‹ค.

 

[ Unity Performance Testing Extension์˜ ํŠน์ง• ]

โœ… ์ฝ”๋“œ ์‹คํ–‰ ์‹œ๊ฐ„ ์ธก์ •

 ~> Measure.Method()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์ฝ”๋“œ ๋ธ”๋ก์˜ ์‹คํ–‰ ์†๋„ ๋ถ„์„ ๊ฐ€๋Šฅ

 ~> WarmupCount(), MeasurementCount()๋ฅผ ํ™œ์šฉํ•ด ํ‰๊ท ๊ฐ’ ๋„์ถœ ๊ฐ€๋Šฅ

โœ… FPS ๋ฐ CPU/GPU ์„ฑ๋Šฅ ์ธก์ •

 ~> Measure.Frames()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ FPS ๋ฐ CPU/GPU ์‚ฌ์šฉ๋Ÿ‰์„ ์ž๋™์œผ๋กœ ๋ถ„์„ ๊ฐ€๋Šฅ

 ~> ํŠน์ • ๊ตฌ๊ฐ„์—์„œ ํ”„๋ ˆ์ž„ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜์—ฌ ์ตœ์ ํ™” ์—ฌ๋ถ€ ํŒ๋‹จ ๊ฐ€๋Šฅ

โœ… ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ธก์ •

 ~> Measure.Profiler()๋ฅผ ํ™œ์šฉํ•˜์—ฌ Garbage Collection(GC) ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ถ„์„ ๊ฐ€๋Šฅ

 ~> ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๊ฐ์ง€ํ•˜์—ฌ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ฐ€๋Šฅ

โœ… ์„ฑ๋Šฅ ๊ธฐ์ค€ ์„ค์ • ๋ฐ ๋น„๊ต ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ

 ~> ShouldBeUnder()๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํŠน์ • ์ฝ”๋“œ์˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด ๋ชฉํ‘œ ๊ธฐ์ค€๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ ์‹คํŒจ ์ฒ˜๋ฆฌ

 ~> ์ฝ”๋“œ ๋ณ€๊ฒฝ ์ „ํ›„์˜ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•˜์—ฌ ์ตœ์ ํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒ€์ฆ ๊ฐ€๋Šฅ

โœ… CI/CD ์—ฐ๋™ ๊ฐ€๋Šฅ

 ~> Unity CLI(Command Line Interface)๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ์ž๋™ ์‹คํ–‰ ๊ฐ€๋Šฅ

 ~> GitHub Actions, GitLab CI/CD, Jenkins์™€ ์—ฐ๋™ํ•˜์—ฌ ์„ฑ๋Šฅ ์ €ํ•˜ ๊ฐ์ง€ ๊ฐ€๋Šฅ

 

[ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ]

โญ ๊ณต์‹ ๋ฌธ์„œ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ก  Performance testing API ํŒจํ‚ค์ง€๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ณ„๋„์˜ ์„ค์น˜ ํ›„ using Unity.PerformanceTesting; ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  1๏ธโƒฃ ํŒจํ‚ค์ง€ ์„ค์น˜

   ~> [ Window ] > [ Package Manager ] ์—ด๊ธฐ

   ~> Unity Registry ํƒญ์—์„œ Performance testing API ๊ฒ€์ƒ‰ ํ›„ [ Install ]

  2๏ธโƒฃ Assembly Definition ํŒŒ์ผ ์ƒ์„ฑ

   ~> ํ…Œ์ŠคํŠธ ํŒŒ์ผ๋“ค์ด ํฌํ•จ๋œ ํด๋” ๋‚ด์—์„œ [ ์˜ค๋ฅธ์ชฝ ๋งˆ์šฐ์Šค ] > [ Create ] > [ Scripting ] > [ Assembly Definition ]

  3๏ธโƒฃ .asmdef ์—์„œ ์ฐธ์กฐ ์ถ”๊ฐ€

   ~> ์ƒ์„ฑ๋œ .asmdef ํŒŒ์ผ์„ ์„ ํƒ

   ~> Inspector ์ฐฝ์—์„œ [ Assembly Definition References ] ์„น์…˜์— Unity.PerformanceTesting ์ถ”๊ฐ€

 

๐Ÿ“Œ Assembly Definition ํŒŒ์ผ์ด๋ž€?

.asmdef (Assembly Definition) ํŒŒ์ผ์€ Unity์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํŠน์ • ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•˜๋Š” ์„ค์ • ํŒŒ์ผ์ด๋‹ค. ๋งŒ์•ฝ .asmdef ํŒŒ์ผ์ด ์—†์œผ๋ฉด, Unity๋Š” ๋ชจ๋“  C# ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ์ปดํŒŒ์ผํ•˜๋ฉฐ, ์ด๋กœ ์ธํ•ด ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊นŒ์ง€ ํฌํ•จ๋˜์–ด ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด .asmdef ํŒŒ์ผ์„ ํ™œ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์†๋„๋ฅผ ์ตœ์ ํ™”ํ•˜๊ณ , ์‹คํ–‰ ์ฝ”๋“œ์™€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[ Assets ๊ตฌ์„ฑ ]

  ๐Ÿ“ Scripts

   ใ„ด ๐Ÿ“„ PlayerController.cs

   ใ„ด ๐Ÿ“„ CameraController.cs

   ใ„ด ๐Ÿ“„ Runtime.asmdef

   ใ„ด ๐Ÿ“ Tests

    ใ„ด ๐Ÿ“„ PlayerControllerTest.cs

    ใ„ด ๐Ÿ“„ CameraControllerTest.cs

    ใ„ด ๐Ÿ“„ Tests.asmdef

 

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„ Assets ๊ตฌ์„ฑ์—์„œ Unity๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ์ปดํŒŒ์ผํ•œ๋‹ค. ์ด๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(Tests/)์™€ ์‹คํ–‰ ์ฝ”๋“œ(Scripts/)๊ฐ€ ๋ถ„๋ฆฌ๋˜์ง€ ์•Š๊ณ  ํ•จ๊ป˜ ๋นŒ๋“œ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ๊ฐ์˜ ํด๋”์— .asmdef ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ์‹คํ–‰ ์ฝ”๋“œ์™€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ–ˆ๋‹ค. ์ฆ‰, Runtime.asmdef๋Š” ์‹ค์ œ ๊ฒŒ์ž„ ์‹คํ–‰์„ ์œ„ํ•œ ์ฝ”๋“œ๋งŒ ํฌํ•จ๋˜๋ฉฐ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์™€ ๋ถ„๋ฆฌ๋˜๋ฏ€๋กœ, ๋นŒ๋“œ ์‹œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์•„ ์‹คํ–‰ ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•˜๊ฒŒ ์œ ์ง€๋œ๋‹ค.

 

์œ„์™€ ๊ฐ™์ด .asmdef ํŒŒ์ผ์„ ์„ค์ •ํ•˜๋ฉด, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(Tests/ ํด๋” ์•ˆ์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ)๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹คํ–‰ ์ฝ”๋“œ(PlayerController.cs ๋“ฑ)์— ๋ฐ”๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด Tests.asmdef์—์„œ Runtime.asmdef๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, Tests.asmdef ํŒŒ์ผ์˜ [ Assembly Definition References ] ํ•ญ๋ชฉ์— Runtime.asmdef๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์‹คํ–‰ ์ฝ”๋“œ(PlayerController.cs, CameraController.cs)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ

๋ณธ์ธ์€ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”๋ฅผ ์œ„ํ•ด, ๊ธฐ๋ณธ์ ์ธ ์บ๋ฆญํ„ฐ ์ด๋™ ๋ฐ ์• ๋‹ˆ๋งค์ด์…˜, ์นด๋ฉ”๋ผ ๊ณ ์ • ๊ธฐ๋Šฅ๋งŒ ๊ตฌํ˜„๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

 

[ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ]

 • Unity ๋ฒ„์ „: Unity 6 (6000.0.38f1)

 • ํ…Œ์ŠคํŠธ ๋Œ€์ƒ Script

  ~> PlayerController.cs (์บ๋ฆญํ„ฐ ์ด๋™ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜)

  ~> CameraController.cs (์นด๋ฉ”๋ผ ๊ณ ์ • ๊ธฐ๋Šฅ)

[ ํ…Œ์ŠคํŠธ ํŒจํ‚ค์ง€ ์„ค์น˜ ]

 • Test Framework (๊ธฐ๋ณธ ํฌํ•จ ์—ฌ๋ถ€ ํ™•์ธ ํ›„ ํ•„์š” ์‹œ ์„ค์น˜)

 • Performance Testing API (Package Manager์—์„œ ์„ค์น˜)

[ Assets ๊ตฌ์„ฑ ]

  ๐Ÿ“ Scripts

   ใ„ด ๐Ÿ“„ PlayerController.cs

   ใ„ด ๐Ÿ“„ CameraController.cs

   ใ„ด ๐Ÿ“„ Runtime.asmdef

   ใ„ด ๐Ÿ“ Tests

    ใ„ด ๐Ÿ“„ PlayerControllerTest.cs

    ใ„ด ๐Ÿ“„ CameraControllerTest.cs

    ใ„ด ๐Ÿ“„ Tests.asmdef

[ .asmdef ํŒŒ์ผ ์„ค์ • ]

 • Tests.asmdef ํŒŒ์ผ์˜ [ Assembly Definition References ]

  ~> UnityEngine.TestRunner.asmdef

  ~> UnityEditor.TestRunner.asmdef

  ~> Unity.PerformanceTesting.asmdef

  ~> Runtime.asmdef

 

UnityEngine.TestRunner๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์œ„ํ•ด, UnityEditor.TestRunner๋Š” Unity Editor์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด, Unity.PerformanceTesting์€ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด, Runtime.asmdef๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์‹คํ–‰ ์ฝ”๋“œ(PlayerController.cs, CameraController.cs)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ•ด์ค€ ๊ฒƒ์ด๋‹ค.

 

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”

[ PlayerController.cs ]

๋”๋ณด๊ธฐ
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody rigid;
    Animator anim;

    public float speed = 3f;
    public Vector3 inputKey = Vector3.zero;

    void Awake()
    {
        rigid = GetComponent<Rigidbody>();
        anim = GetComponent<Animator>();
    }

    void FixedUpdate()
    {
        Vector3 moveDir = inputKey != Vector3.zero ? inputKey : GetInputDirection();

        if (moveDir != Vector3.zero)
            MoveCharacter(moveDir.normalized);
        else
            anim.Play("Idle");
    }

    Vector3 GetInputDirection()
    {
        Vector3 direction = Vector3.zero;

        if (Input.GetKey(KeyCode.W)) // ์•ž์œผ๋กœ ์ด๋™
            direction += Vector3.forward;
        if (Input.GetKey(KeyCode.S)) // ๋’ค๋กœ ์ด๋™
            direction += Vector3.back;
        if (Input.GetKey(KeyCode.D)) // ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™
            direction += Vector3.right;
        if (Input.GetKey(KeyCode.A)) // ์™ผ์ชฝ์œผ๋กœ ์ด๋™
            direction += Vector3.left;

        return direction;
    }

    void MoveCharacter(Vector3 dir)
    {
        // ์บ๋ฆญํ„ฐ ํšŒ์ „
        Quaternion targetRotation = Quaternion.LookRotation(dir);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 10f);

        // ๋ฌผ๋ฆฌ ์ด๋™
        Vector3 newPosition = rigid.position + dir * speed * Time.deltaTime;
        rigid.MovePosition(newPosition);

        anim.Play("RunForward");
    }
}

 

[ PlayerControllerTest.cs ]

๋”๋ณด๊ธฐ
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.SceneManagement;
using NUnit.Framework;
using System.Collections;
using Unity.PerformanceTesting;

public class PlayerControllerTest
{
    PlayerController playerController;
    Animator animator;

    string sceneName = "GameScene";

    Vector3 startPos;
    Vector3 endPos;
 
    bool isIdle;
    bool isRunning;

    [UnitySetUp]
    public IEnumerator Setup(){
        if (SceneManager.GetActiveScene().name != sceneName) {
            Debug.LogWarning("โš ๏ธ [TEST WARNING] ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „ ์”ฌ์„ ๊ฐ•์ œ๋กœ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค!");
            SceneManager.LoadScene(sceneName); 
        }

        while (SceneManager.GetActiveScene().name != sceneName)
            yield return new WaitForSeconds(0.1f);

        playerController = GameObject.Find("Player").GetComponent<PlayerController>();
        if (playerController == null)
            Assert.Fail("โŒ [TEST ERROR] PlayerController๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!");

        animator = GameObject.Find("Player").GetComponent<Animator>();
        if (animator == null)
            Assert.Fail("โŒ [TEST ERROR] Animator๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!");

        startPos = playerController.transform.position;
    }

    [UnityTest]
    public IEnumerator MoveCharacterTest() {
        playerController.inputKey = Vector3.forward;
        yield return new WaitForSeconds(2f);

        endPos = playerController.transform.position;
        Assert.Greater(endPos.z, startPos.z, "โŒ [TEST Fail] ํ”Œ๋ ˆ์ด์–ด ์ด๋™ ์‹คํŒจ!");

        playerController.inputKey = Vector3.zero;
    }

    [UnityTest]
    public IEnumerator AnimationIdleTest() {
        playerController.inputKey = Vector3.zero;
        yield return new WaitForSeconds(2f);

        isIdle = animator.GetCurrentAnimatorStateInfo(0).IsName("Idle");
        Assert.IsTrue(isIdle, "โŒ [TEST Fail] ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๋ฉˆ์ถฐ์žˆ์ง€๋งŒ, 'Idle' ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹คํ–‰๋˜์ง€ ์•Š์Œ!");
    }

    [UnityTest]
    public IEnumerator AnimationRunTest() {
        playerController.inputKey = Vector3.left;
        yield return new WaitForSeconds(2f);

        isRunning = animator.GetCurrentAnimatorStateInfo(0).IsName("RunForward");
        Assert.IsTrue(isRunning, "โŒ [TEST Fail] ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ด๋™ ์ค‘์ด์ง€๋งŒ, 'RunForward' ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹คํ–‰๋˜์ง€ ์•Š์Œ!");

        playerController.inputKey = Vector3.zero;
    }

    [Test, Performance]
    public void MoveCharacterPerformanceTest() {
        Measure.Method(() => {
            playerController.inputKey = Vector3.forward;
            playerController.FixedUpdate();
        })
        .WarmupCount(5)
        .MeasurementCount(50)
        .IterationsPerMeasurement(10)
        .Run();
    }

    [TearDown]
    public void TearDown() {
        playerController = null;
        animator = null;

        isIdle = false;
        isRunning = false;

        startPos = Vector3.zero;
        endPos = Vector3.zero;
    }
}

 

[ CameraController.cs ]

๋”๋ณด๊ธฐ
using UnityEngine;

public class CameraController : MonoBehaviour
{
    [SerializeField]
    GameObject target;

    public float offsetX = 0f;
    public float offsetY = 2f;
    public float offsetZ = -3f;
    float speed = 3f;

    Vector3 targetPos;

    void FixedUpdate() {
        // ์นด๋ฉ”๋ผ ์ด๋™
        targetPos = target.transform.position + new Vector3(offsetX, offsetY, offsetZ);
        transform.position = Vector3.Lerp(transform.position, targetPos, Time.deltaTime * speed);
    }   
}

 

[ CameraControllerTest.cs ]

๋”๋ณด๊ธฐ
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.SceneManagement;
using NUnit.Framework;
using System.Collections;

public class CameraControllerTest
{
    PlayerController playerController;
    CameraController cameraController;

    string sceneName = "GameScene";

    Vector3 initialCamPos;
    Vector3 expectedCamPos;
    Vector3 actualCamPos;

    [UnitySetUp]
    public IEnumerator SetUp() {
        if (SceneManager.GetActiveScene().name != sceneName) {
            Debug.LogWarning("โš ๏ธ [TEST WARNING] ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „ ์”ฌ์„ ๊ฐ•์ œ๋กœ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค!");
            SceneManager.LoadScene(sceneName); 
        }

        while (SceneManager.GetActiveScene().name != sceneName)
                yield return new WaitForSeconds(0.1f);

        playerController = GameObject.Find("Player").GetComponent<PlayerController>();
        if (playerController == null)
            Assert.Fail("โŒ [TEST ERROR] PlayerController๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!");

        cameraController = GameObject.Find("Camera").GetComponent<CameraController>();
        if (cameraController == null)
            Assert.Fail("โŒ [TEST ERROR] CameraController๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!");
    }

    [UnityTest]
    public IEnumerator CameraFollowTest() {
        initialCamPos = cameraController.transform.position;

        playerController.inputKey = Vector3.forward;
        yield return new WaitForSeconds(1f);
        playerController.inputKey = Vector3.zero;
        yield return new WaitForSeconds(1f);

        expectedCamPos = playerController.transform.position + new Vector3(cameraController.offsetX, cameraController.offsetY, cameraController.offsetZ);
        actualCamPos = cameraController.transform.position;

        Assert.AreNotEqual(initialCamPos, actualCamPos, "โŒ [TEST Fail] ์นด๋ฉ”๋ผ๊ฐ€ ์ด๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค!");
        Assert.AreEqual(expectedCamPos.x, actualCamPos.x, 0.1f, "โŒ [TEST Fail] ์นด๋ฉ”๋ผ X ์œ„์น˜๊ฐ€ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฆ„!");
        Assert.AreEqual(expectedCamPos.y, actualCamPos.y, 0.1f, "โŒ [TEST Fail] ์นด๋ฉ”๋ผ Y ์œ„์น˜๊ฐ€ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฆ„!");
        Assert.AreEqual(expectedCamPos.z, actualCamPos.z, 0.1f, "โŒ [TEST Fail] ์นด๋ฉ”๋ผ Z ์œ„์น˜๊ฐ€ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฆ„!");
    }

    [TearDown]
    public void TearDown() {
        playerController = null;
        cameraController = null;
        
        initialCamPos = Vector3.zero;
        expectedCamPos = Vector3.zero;
        actualCamPos = Vector3.zero;
    }
}

 

[ โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ ]

ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— ํ˜„์žฌ Scene์„ Unity ๋นŒ๋“œ ์„ค์ •์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ฉด SceneManager.LoadScene()์ด ์‹คํ–‰๋˜์ง€ ์•Š์•„์„œ ์”ฌ์„ ๋กœ๋“œํ•  ์ˆ˜ ์—†๋‹ค.

 1๏ธโƒฃ [ File ] > [ Build Profiles ]

 2๏ธโƒฃ [ Scene List ] > [ Add Open Scenes ] ๋ฅผ ํ†ตํ•ด ํ˜„์žฌ Scene์„ Unity ๋นŒ๋“œ ์„ค์ •์— ์ถ”๊ฐ€

 

[ โ“ Why in Play Mode? ]

์œ„ PlayerControllerTest.cs์™€ CameraControllerTest.cs๋Š” ๋‘˜ ๋‹ค Play Mode์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

1๏ธโƒฃ Unity์˜ ์ž…๋ ฅ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ

 ~> PlayerController.cs๋Š” Input.GetKey()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‚ค ์ž…๋ ฅ์„ ๊ฐ์ง€

 ~> ํ•˜์ง€๋งŒ Edit Mode ํ…Œ์ŠคํŠธ์—์„œ๋Š” Unity์˜ ์ž…๋ ฅ ์‹œ์Šคํ…œ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Œ

2๏ธโƒฃ MonoBehaviour์˜ ๋™์ž‘์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ

 ~> FixedUpdate(), Animator ๋“ฑ Unity ์—”์ง„์˜ ์‹ค์ œ ๋™์ž‘์„ ํฌํ•จํ•˜๋Š” ํ…Œ์ŠคํŠธ๋Š” Play Mode์—์„œ๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅ

 ~> Edit Mode์—์„œ๋Š” MonoBehaviour๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ

3๏ธโƒฃ Scene์— ์กด์žฌํ•˜๋Š” PlayerController, CameraController๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ

 ~> Edit Mode ํ…Œ์ŠคํŠธ์—์„œ๋Š” Scene์„ ๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ

 ~> Find()๋ฅผ ์‚ฌ์šฉํ•ด์„œ Scene์— ์กด์žฌํ•˜๋Š” Object๋ฅผ ์ฐพ์•„์•ผ ํ•จ

 

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ์‹คํ–‰ (in Editor)

 

๊ธฐ๋Šฅ ์„ค๋ช…
์‹คํ–‰ ๊ฒฝ๋กœ [ Window ] > [ General ] > [ Test Runner ]
ํ…Œ์ŠคํŠธ ๋ชจ๋“œ Edit Mode vs Play Mode
๊ฒฐ๊ณผ ์ €์žฅ ์œ„์น˜ Console ์ฐฝ ๋กœ๊ทธ ํ™•์ธ
Export Results ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ
Clear Results ๊ธฐ์กด ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์ดˆ๊ธฐํ™”
Return Failed ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ๋งŒ ๋‹ค์‹œ ์‹คํ–‰
Run Selected ์„ ํƒํ•œ ํŠน์ • ํ…Œ์ŠคํŠธ๋งŒ ์‹คํ–‰
Run All ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰

 

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๊ฒฐ๊ณผ (in Editor)

 

โœ… ์ €์žฅ ๊ฒฝ๋กœ

 ๐Ÿ“ C:\Users\User\AppData\LocalLow\DefaultCompany\MyFirst3D

โœ… ํŒŒ์ผ๋ณ„ ํฌํ•จ ์ •๋ณด

ํŒŒ์ผ๋ช… ํฌํ•จ๋œ ์ •๋ณด ์„ค๋ช…
TestResults.xml
(by Unity Test Framework)
- ์ „์ฒด ํ…Œ์ŠคํŠธ ๊ฐœ์ˆ˜
- ์„ฑ๊ณต/์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ ๊ฐœ์ˆ˜
- ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹œ๊ฐ„
- ์‹คํ–‰ ํ™˜๊ฒฝ (PlayMode/EditMode)
- ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ํฌํ•จ (์ตœ์†Œ/์ตœ๋Œ€ ์‹คํ–‰ ์‹œ๊ฐ„ ๋“ฑ)
                                 ...
๋ชจ๋“  ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋กํ•˜๋ฉฐ, ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋„ ํฌํ•จ๋จ
PerformanceTestResults.json
(by Unity Performance Testing Extension)
- ํ•˜๋“œ์›จ์–ด ์ •๋ณด (CPU, GPU, RAM ๋“ฑ)
- ์‹คํ–‰ ํ™˜๊ฒฝ (ํ•ด์ƒ๋„, ์ฃผ์‚ฌ์œจ, ๋ Œ๋”๋ง ๋ชจ๋“œ ๋“ฑ)
- ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋งŒ ๋ณ„๋„๋กœ ์ €์žฅ
                                ...
์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ์ž์„ธํžˆ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉ

 

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ์‹คํ–‰ ๋ฐ ๊ฒฐ๊ณผ (in cmd)

Unity Test Runner๋Š” Unity Editor์—์„œ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, cmd์—์„œ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, GUI ์—†์ด cmd์—์„œ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ CI/CD ํ™˜๊ฒฝ์—์„œ๋„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[ ๋ช…๋ น์–ด ์˜ˆ์‹œ ]

"C:\Program Files\Unity\Hub\Editor\6000.0.38f1\Editor\Unity.exe" -batchmode -runTests -projectPath "C:/Users/User/UnityProject/MyFirst3D" -testPlatform PlayMode -logFile"C:/Users/User/UnityProject/MyFirst3D/results.log"

 

โœ… "C:\Program Files\Unity\Hub\Editor\6000.0.38f1\Editor\Unity.exe"

 ใ„ด Unity ์‹คํ–‰ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜์—ฌ ์‹คํ–‰

โœ… -batchmode

 ใ„ด Unity๋ฅผ GUI ์—†์ด ํ„ฐ๋ฏธ๋„/์ปค๋งจ๋“œ ๋ผ์ธ์—์„œ ์‹คํ–‰ (์ž๋™ํ™” ์‹คํ–‰์„ ์œ„ํ•ด ํ•„์ˆ˜)

โœ… -runTests

 ใ„ด Unity์˜ TestRunner๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ์˜ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰

โœ… -projectPath "C:/Users/User/UnityProject/MyFirst3D"

 ใ„ด ํ•ด๋‹น ๊ฒฝ๋กœ์˜ Unity ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด์„œ ์‹คํ–‰

โœ… -testPlatform PlayMode

 ใ„ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ํ™˜๊ฒฝ์„ ์ง€์ • (PlayMode: ์‹ค์ œ ๊ฒŒ์ž„ ํ™˜๊ฒฝ์—์„œ ํ…Œ์ŠคํŠธ ์‹คํ–‰)

โœ… -logFile "C:/Users/User/UnityProject/MyFirst3D/results.log"

 ใ„ด ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ results.log ํŒŒ์ผ์— ์ €์žฅ

 ใ„ด ํŒŒ์ผ ๊ฒฝ๋กœ๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ (๊ฒฝ๋กœ ๋ฌธ์ œ ๋ฐฉ์ง€)

 

 

๐Ÿ“Œ Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”

Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด, CameraControllerTest.cs ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์—ฌ CameraFollowTest()๊ฐ€ ์‹คํŒจํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

๋”๋ณด๊ธฐ

[ ์ˆ˜์ • ์ „ ]

[UnityTest]
    public IEnumerator CameraFollowTest() {
        # ...

        actualCamPos = cameraController.transform.position;

        # ...
    }

 

[ ์ˆ˜์ • ํ›„ ]

[UnityTest]
    public IEnumerator CameraFollowTest() {
        # ...

        actualCamPos = cameraController.transform.position + new Vector3(1.0f, 1.0f, 1.0f);

        # ...
    }

 

[ ๊ตฌํ˜„ ์ฝ”๋“œ ]

๋”๋ณด๊ธฐ
import os
import json
import requests
import xml.etree.ElementTree as ET

JIRA_PROJECT_KEY = "ํ”„๋กœ์ ํŠธ ํ‚ค"
JIRA_URL = "jira ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ"
JIRA_API_TOKEN = "๋ฐœ๊ธ‰๋ฐ›์€ Jira API ํ† ํฐ"
JIRA_EMAIL = "๋ณธ์ธ์˜ ์ด๋ฉ”์ผ"

AUTH = (JIRA_EMAIL, JIRA_API_TOKEN)
HEADERS = {"Content-Type": "application/json"}

# Unity Test ๊ฒฐ๊ณผ XML ํŒŒ์ผ ๊ฒฝ๋กœ
XML_FILE_PATH = "C:\\Users\\User\\AppData\\LocalLow\\DefaultCompany\\MyFirst3D\\TestResults.xml" 

def getFailedTests(xmlPath): # ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ ๋ชฉ๋ก์„ ์ถ”์ถœํ•˜๋Š” ํ•จ์ˆ˜
    tree = ET.parse(xmlPath)
    root = tree.getroot()

    failedTests  = []

    for testCase in root.findall(".//test-case[@result='Failed']"):
        testName = testCase.get("name")
        messageNode = testCase.find("failure/message")
        errorMessage = messageNode.text if messageNode is not None else "No error message provided"
        
        failedTests.append({"name": testName , "message": errorMessage})

    return failedTests 

def createJiraIssue(summary, description): # Jira์— ๋ฒ„๊ทธ ์ด์Šˆ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
    url = f"{JIRA_URL}/rest/api/2/issue/"
    data = {
        "fields": {
            "project": {"key": JIRA_PROJECT_KEY},
            "summary": summary,
            "description": description,
            "issuetype": {"name": "๋ฒ„๊ทธ"}
        }
    }

    response = requests.post(url, auth=AUTH, headers=HEADERS, data=json.dumps(data))

    if response.status_code == 201:
        print(f"โœ… Jira ์ด์Šˆ ์ƒ์„ฑ ์™„๋ฃŒ: {summary}")
    else:
        print(f"โŒ Jira ์ด์Šˆ ์ƒ์„ฑ ์‹คํŒจ: {response.text}")

def processTestResults(): # ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  Jira์— ์ด์Šˆ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
    failed_tests = getFailedTests(XML_FILE_PATH)

    if not failed_tests:
        print("๐ŸŽ‰ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. Jira ์ด์Šˆ๋ฅผ ๋“ฑ๋กํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")
        return

    print(f"๐Ÿšจ {len(failed_tests)}๊ฐœ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. Jira ์ด์Šˆ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค...")

    for test in failed_tests:
        summary = f"[Unity Test] {test['name']} ์‹คํŒจ"
        description = f"ํ…Œ์ŠคํŠธ '{test['name']}' ์‹คํŒจ: {test['message']}"
        createJiraIssue(summary, description)

# ์‹คํ–‰
os.system('cls')
processTestResults()

 

[ ์‹คํ–‰ ๊ฒฐ๊ณผ ]

 

Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ, ์œ„์™€ ๊ฐ™์ด Jira์— ์ด์Šˆ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

'๐Ÿ“‚ Quality Assurance Study > ๐Ÿ“„ QA ๊ณต๋ถ€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Jest + POM] ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ† ๋ง  (0) 2025.04.20
Jira REST API ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ์ด์Šˆ ์กฐํšŒ  (0) 2025.03.02
XPath์— ๋Œ€ํ•˜์—ฌ  (0) 2025.02.27
Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ•  (2) 2025.02.20
BTS (Bug Tracking System)์— ๋Œ€ํ•˜์—ฌ  (3) 2025.01.13
'๐Ÿ“‚ Quality Assurance Study/๐Ÿ“„ QA ๊ณต๋ถ€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Jest + POM] ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ† ๋ง
  • Jira REST API ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ์ด์Šˆ ์กฐํšŒ
  • XPath์— ๋Œ€ํ•˜์—ฌ
  • Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
YeonSu02
YeonSu02
Email : rkddustn2519@naver.com
  • YeonSu02
    IsLiife2
    YeonSu02
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • ๐Ÿ“‚ Computer Science
      • ๐Ÿ“‚ Unity Engine Study
        • ๐Ÿ“„ Unity ์ธํ”„๋Ÿฐ ๊ฐ•์˜
        • ๐Ÿ“„ Unity ์œ ํŠœ๋ธŒ ๊ฐ•์˜
        • ๐Ÿ“„ Unity ์ฐธ๊ณ 
      • ๐Ÿ“‚ Game Designer Study
        • ๐Ÿ“„ ๊ธฐํš ์ธํ”„๋Ÿฐ ๊ฐ•์˜
      • ๐Ÿ“‚ Quality Assurance Study N
        • ๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™ N
        • ๐Ÿ“„ QA ๊ณต๋ถ€
        • ๐Ÿ“š QA ์ฑ… ๋ฆฌ๋ทฐ
      • ๐Ÿ“‚ Program Language Study
        • ๐Ÿ“„ C# ๊ณต๋ถ€
        • ๐Ÿ“„ ํŒŒ์ด์ฌ ๊ณต๋ถ€
        • ๐Ÿ“„ Java ๊ณต๋ถ€
        • ๐Ÿ“„ JavaScript ๊ณต๋ถ€
      • ๐Ÿ“‚ Additional Study
        • ๐Ÿ“„ Git
        • ๐Ÿ“„ Firebase
        • ๐Ÿ“„ License
      • ๐Ÿ’ป Game Development
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
  • ๋งํฌ

    • GitHub
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    qa์ž๊ฒฉ์ฆ
    ISTQB
    ํ…Œ์ŠคํŒ…์ž๊ฒฉ์ฆ
    ์ž๊ฒฉ์ฆ
    ์ปดํ“จํ„ฐํ™œ์šฉ๋Šฅ๋ ฅ1๊ธ‰
    ์ •์ฒ˜๊ธฐ
    ์ •์ฒ˜๊ธฐ ๋…ํ•™
    ์ •์ฒ˜๊ธฐ ํ•„๊ธฐ
    QA
    qa ์ฑ…
    BTS
    ์ •์ฒ˜๊ธฐ ์‹ค๊ธฐ
    ์ปดํ™œ
    ๊ตญ์ œ์ž๊ฒฉ์ฆ
    istqb-ctfl
    ์—‘์…€
    ์ปดํ“จํ„ฐํ™œ์šฉ๋Šฅ๋ ฅ
    ์ปดํ“จํ„ฐํ™œ์šฉ๋Šฅ๋ ฅ2๊ธ‰
    ์ปดํ™œ2๊ธ‰
    qa ์ฑ… ๋ฆฌ๋ทฐ
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
YeonSu02
Unity์—์„œ์˜ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋ฐ Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”