Nunit: ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ณ„ ์ธ์Šคํ„ด์Šค ๊ธฐ๋Šฅ

์— ๋งŒ๋“  2017๋…„ 11์›” 24์ผ  ยท  112์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: nunit/nunit

๋ชจ๋‘์˜ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์€ Fixture ๋‚ด์—์„œ ๋ณ‘๋ ฌํ™”ํ•  ๋•Œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ณ„๋กœ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(https://github.com/nunit/nunit/issues/2105, https://github.com/nunit/nunit/issues). /2252, https://github.com/nunit/nunit/issues/2573) ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋Š” ์—†์—ˆ์ง€๋งŒ. ์ €๋Š” ํ•ญ์ƒ ์ •์  ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์–ด๋–ค ๋ฉด์—์„œ ๋” ํ’๋ถ€ํ•œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ์ผํšŒ์šฉ ์ค‘์ฒฉ ์กฐ๋ช…๊ธฐ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์ง€๋งŒ( ์˜ˆ์‹œ ), ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์•ฝ๊ฐ„์˜ ๋‹จ์ ์€ ์šฉ์–ด์ƒ ์ •์  ํด๋ž˜์Šค๊ฐ€ NUnit์ด ๊ณ ์ • ์žฅ์น˜๋กœ ๊ฐ„์ฃผํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์‹ค์ œ ๊ณ ์ • ์žฅ์น˜๋Š” ์ค‘์ฒฉ ํด๋ž˜์Šค๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์˜ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š” ๋น„๋ณ‘๋ ฌ ๊ณ ์ • ์žฅ์น˜๊ฐ€ ์ค‘๋‹จ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค. [Order] ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์•„๋งˆ๋„ ์ด๊ฒƒ์ด ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์‚ฌ๋žŒ๋“ค์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ˆœ์„œ ์ข…์† ํ…Œ์ŠคํŠธ๋ฅผ ์™„์ „ํžˆ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” Charlie์˜ ์ œ์•ˆ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

  • ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜๊ฐ€ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค ๋˜๋Š” ํ”ฝ์Šค์ฒ˜๋‹น ์ธ์Šคํ„ด์Šค๋กœ ์ƒ์„ฑ๋˜๋Š” ๋ฐฉ์‹์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ๋ ˆ๋ฒจ ์†์„ฑ์ž…๋‹ˆ๋‹ค.
  • ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋Š” ์ง€๊ธˆ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ํ”ฝ์Šค์ฒ˜๋‹น ์ธ์Šคํ„ด์Šค๋Š” ๊ฐ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ์ƒˆ ํ”ฝ์Šค์ฒ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ์ผํšŒ์„ฑ ์„ค์ • ๋ฐ ๋ถ„ํ•ด ํ™œ๋™์„ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜(์ฆ‰, ๋” ์ด์ƒ "์ผํšŒ์„ฑ"์ด ์•„๋‹˜) OneTimeSetUp ๋ฐ OneTimeTearDown์— ์˜ค๋ฅ˜ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ง€์ •๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ํ™•์žฅ:

  • ์ด ํด๋ž˜์Šค ๋ ˆ๋ฒจ๋„ ๋งŒ๋“ค์–ด ๊ฐœ๋ณ„ ์„ค๋น„๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ ๊ณ ์ • ์žฅ์น˜์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ์„ธ ๋ฒˆ์งธ ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค. (ํ•ญ์ƒ ๋ฏธ๋ฆฌ ์•Œ๊ธฐ๋Š” ๊นŒ๋‹ค๋กœ์›€)

๊ทธ๋Ÿฌ๋‚˜ ๋จผ์ € ๊ธฐ๋ณธ์„ ์ˆ˜ํ–‰ํ•˜๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ ๋‹น์žฅ์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ์ธ์Šคํ„ด์Šค ์ƒํƒœ๊ฐ€ ์žˆ๊ณ  ํ”ฝ์Šค์ฒ˜๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ๋ฒ„๊ทธ๊ฐ€ ๋ณด์žฅ๋˜๋ฏ€๋กœ, ํ”ฝ์Šค์ฒ˜์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค๋กœ ์ „ํ™˜ํ•˜๋Š” Auto ์˜ต์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ”ผํ•˜์‹ญ์‹œ์˜ค . Auto๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์ผ์ƒ์ ์ธ ๋ฌธ์ œ๋กœ [assembly: InstancePerTestCase] ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฐ€์žฅ ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ๊ฐ’์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ€๋“œ๋ ˆ์ผ์— ์ฐฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ”ฝ์Šค์ฒ˜๊ฐ€ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ OneTimeSetUp ๋ฐ OneTimeTearDown์— ์˜ค๋ฅ˜ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ง€์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ •์ ์ด ์•„๋‹Œ ํ•œ?

done feature normal docs releasenotes

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์„ ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ •๋ง ๊ฐ€๊นŒ์›Œ์ง„ ๋Š๋‚Œ

๋ชจ๋“  112 ๋Œ“๊ธ€

ํ˜„์žฌ, (1) ์ƒ์„ฑ์ž ๋˜๋Š” ์ผํšŒ์„ฑ ์„ค์ •์—์„œ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜๊ณ  (2) ์–ด๋–ค ํ…Œ์ŠคํŠธ์—์„œ๋„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ๋ณ‘๋ ฌ ํ…Œ์ŠคํŠธ ๊ฐ„์— ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒํƒœ๊ฐ€ ํ…Œ์ŠคํŠธ ๋˜๋Š” ์„ค์ •์—์„œ ์ƒ์ˆ˜๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํ†ต๊ณผํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ผ๋ถ€ NUnit ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ํ›„์ž๋Š” icky์ž…๋‹ˆ๋‹ค.

์ œ ์ƒ๊ฐ์—๋Š” ๊ธฐ๋ณธ๊ฐ’์„ ์กฐ๋งŒ๊ฐ„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด์„œ ํ˜„์žฌ ๋ฒ„๊ทธ๊ฐ€ ๋ณด์žฅ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฒ„๊ทธ์ผ ๋ฟ์ด๋ฉฐ ์ฝ”๋“œ ๋ถ„์„์„ ํ•˜์ง€ ์•Š๋Š” ํ•œ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋˜๋Š” ์„ค์ • ๋˜๋Š” ๋ถ„ํ•ด ๋‚ด์—์„œ ์ธ์Šคํ„ด์Šค ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด ์†์ƒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ํ•œ ์ด๋ฏธ ๊ณ ์žฅ๋‚œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‹น์‹ ์ด ๋ถ€์„œ์ง€์ง€ ์•Š์„ ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์‚ฌ์šฉ์ž์˜ ๋ณต์žก์„ฑ์ด "ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ๊ฐ’" ๊ฒฐ๊ณผ์˜ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒฝ์šฐ ์ž๋™ ์˜ต์…˜์— ๋Œ€ํ•œ ์ •๋‹นํ™”์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ์š”์ ์ด ์žˆ์ง€๋งŒ ๋‚˜๋Š” ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๊ฒฐ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์ž ์žฌ์ ์ธ ์—ฐ์žฅ์ด๋ผ๊ณ  ๊ณ„์† ์˜นํ˜ธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋ชจ๋“  ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๋ ค๊ณ  ํ•˜์ง€ ๋ง๊ณ  ์ด ์ž‘์—…์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ €๋Š” @CharliePoole ๊ณผ ํ•จ๊ป˜

๋ชจ๋“  ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด ๊ณต์œ ๋˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์Šค๋ ˆ๋“œ๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ๊ณ ์ • ์ˆ˜์ค€ ์†์„ฑ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@BlythMeister ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”! ๊ธฐ์กด ์ฝ”๋“œ๊ฐ€ ์†์ƒ๋˜๊ธฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฑด ์žฌ๋ฏธ ์žˆ๋„ค. ๋‚˜๋Š” instance-per-test-case๊ฐ€ instance-per-thread๋ณด๋‹ค ๋งˆ์Œ์„ ๊ฐ์‹ธ๋Š” ๊ฒƒ์ด ๋” ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ์Šค๋ ˆ๋“œ์— ํ• ๋‹น๋˜๋Š” ๋ฐฉ์‹์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ธ์Šคํ„ด์Šค๋‹น ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋น„ํ•ด ์–ด๋–ค ์ด์ ์ด ์žˆ๋Š”์ง€ ์ƒ๊ฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋„ค, ๋ณ‘๋ ฌ ์‹คํ–‰์„ ์˜๋ฏธํ•˜๊ธฐ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‚ฌ์‹ค ์ •ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

XP์˜ ๊ด€์ ์—์„œ(๊ทธ๋ฆฌ๊ณ  ๋ชจ๋‘๊ฐ€ ๊ทธ๊ฒƒ์ด ํ•ญ์ƒ ๋‚ด ๊ด€์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค) ์„œ๋กœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ์ด์•ผ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค...

  1. ์‚ฌ์šฉ์ž๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ๋ชจ๋“  ๊ณ ์ • ์žฅ์น˜์— ๋Œ€ํ•ด ์ „์—ญ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ์‚ฌ์šฉ์ž๋Š” ํ”ฝ์Šค์ฒ˜์—์„œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  3. ์‚ฌ์šฉ์ž๋Š” ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ณ ์ • ์žฅ์น˜์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์—์„œ (1)์ด ์™„์ „ํžˆ ๊ตฌํ˜„๋˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‹น๋ถ„๊ฐ„์€ (2)๋ฅผ ๋จธ๋ฆฌ์—์„œ ๋นผ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ์ ์–ด๋„ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ถ€๋ถ„์—์„œ๋Š” ์ œ์™ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (3)์€ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๋ฌธ์ œ์—์„œ ์ด๋ฏธ ์ ‘ํ•œ ๋ช‡ ๊ฐ€์ง€ ํ•จ์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค. (ํ”ฝ์Šค์ณ๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค!) (1)๊ณผ (2)๊ฐ€ ์™„๋ฃŒ๋˜๊ณ  ๋ณ‘ํ•ฉ๋œ ํ›„์˜ JustInTime์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. FWIW, ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ์›€์ง์ž„์„ ๋ฏธ๋ฆฌ ์ƒ๊ฐํ•˜๋ ค๊ณ  ์‹œ๋„ํ•จ์œผ๋กœ์จ ๋งค๋“ญ์— ๋ฌถ์ด๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” (2)์™€ (3)์„ ์–ธ๊ธ‰ํ•˜์—ฌ ์–ด๋–ค ์‹์œผ๋กœ๋“  ์ฐจ๋‹จํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ถฉ๋ถ„ํžˆ ํ”ผํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋•Œ๋Š” ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ๋™์˜ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์ „์— ๋ช‡ ๊ฐ€์ง€ NUnit ์šฐ์„  ์ˆœ์œ„๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋…ผํ‰ํ•˜๊ณ  ์„ ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚จ๊ฒจ ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์ค„ ์„ค์ •์ด ์•„๋‹Œ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์žฅ์ ์€ ๋ชจ๋“  ๋Ÿฌ๋„ˆ์—์„œ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์†์„ฑ์ด์–ด์•ผํ•œ๋‹ค๋Š” @CharliePoole์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋Š” ํ…Œ์ŠคํŠธ๋‹น ์ธ์Šคํ„ด์Šค ๋˜๋Š” ๊ณ ์ •์žฅ์น˜๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ์„ค๊ณ„ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์˜ต์…˜ 1 ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์Šคํƒ€์ผ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์›ํ•˜๋ฉด ์ „์ฒด ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์— ๋Œ€ํ•ด ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚ฎ์€ ์ˆ˜์ค€์—์„œ ์˜ตํŠธ์ธ์„ ํ—ˆ์šฉํ•˜๋ฉด ROI๊ฐ€ ์ข‹์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๋ณต์žก์„ฑ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ž„๋ฐ•ํ•œ ๊ณ„ํš์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹ญ๋‹ˆ๊นŒ?

@rprouse ์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋””์ž์ธ์ด ํ•„์š”ํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋˜์ง€๋งŒ ๋…ผ์˜๊ฐ€ ์ด๋ฏธ ๋ชจ๋“  ๊ฒƒ์„ ๋‹ค๋ฃฌ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

@CharliePoole ์€ ์ด๊ฒƒ์ด ๋””์ž์ธ์—์„œ @pfluegs ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ๋””์ž์ธํ•˜๋Š” ๊ฒƒ ์ด์ƒ์œผ๋กœ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์•„์ง ๊ณ„ํš์ด ์—†์Šต๋‹ˆ๋‹ค.

์•„๋ฌด๋„ ๊ทธ๊ฒƒ์— ๋งŽ์€ ๊ด€์‹ฌ์„ ๊ธฐ์šธ์ด๋Š”์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์ง€๋งŒ ํ† ๋ก ์ด๋‚˜ ๋””์ž์ธ ๋ ˆ์ด๋ธ”์ด ์—†๋‹ค๋Š” ๊ฒƒ์€ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž์›ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜„

๋‚˜๋Š” ๋ฐ”๋กœ ์ด ๋ฌธ์ œ์— ์‹ฌํ•˜๊ฒŒ ๋ฌผ๋ ธ์Šต๋‹ˆ๋‹ค - ์ˆ˜์ •์„ ์œ„ํ•ด +1.

๋” ๋งŽ์€ ์˜ต์…˜์„ ์›ํ•  ๊ฒฝ์šฐ:

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: FixtureCreation(FixtureCreationOptions.PerTestCase)]

And:
```diff
namespace NUnit.Framework
{
+   public enum FixtureCreationOptions
+   {
+       Singleton, // = default
+       PerTestCase
+   }
}

์ด์— ๋Œ€ํ•œ ๋‚ด ์ƒ๊ฐ์€ ์ ์–ด๋„ ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋งฅ๋ฝ์—์„œ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๊ฐ ๋™์ž‘์— ๋Œ€ํ•ด ํ•˜๋‚˜์”ฉ ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค ์ˆ˜์ค€ ์†์„ฑ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. TestFixture๊ฐ€ ํ…Œ์ŠคํŠธ๋‹น ์ธ์Šคํ„ด์Šค์™€ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๊ณ  Shared Fixture๊ฐ€ ํ˜„์žฌ NUnit์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ์ด๊ฒƒ์€ NUnit์˜ ๋งฅ๋ฝ์—์„œ ํš๊ธฐ์ ์ธ ๋ณ€๊ฒฝ์ด์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์€ ๊ณ ๋ คํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@CharliePoole [TestFixture(FixtureOptions.PerTestCase)] ์ข‹์€ ๊ตฌ๋ฌธ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์†์„ฑ๋„ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์›ํ•˜๋ฏ€๋กœ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ํ”„๋กœ์ ํŠธ์— ์˜ตํŠธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์†์„ฑ์ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์œผ๋ฉด ํ•ฉ๋‹ˆ๊นŒ?

๋งž์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €๋Š” ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•ด ์˜ˆ์•ฝ WRT๋ฅผ ํ‘œํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ NUnit์˜ ๊ฒฝ์šฐ TestFixture ์˜ ์˜๋ฏธ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ์‚ฌ๋ก€๋ณ„ ๋™์ž‘์— ๋Œ€ํ•ด ์ •๋ง ์ข‹์€ ์ด๋ฆ„์ด ์ƒ๊ฐ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ์ด๋ฆ„์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ์กฐ๋ช…๊ธฐ์—์„œ ์›ํ•˜๋Š” ๋™์ž‘์„ ์–ป๊ธฐ ์œ„ํ•ด ํ•ด์•ผ ํ•  ์ผ์€ ์†Œ์Šค ํŒŒ์ผ์˜ ์ „์—ญ ํŽธ์ง‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์˜ ์ „์—ญ ์„ค์ •์€ AssemblyInfo ํŒŒ์ผ์— ์„ค์ •๋œ ๋‚ด์šฉ์„ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์ผ๋ถ€ ๊ฐœ๋ฐœ์ž๋ฅผ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” ๋ช‡ ๊ฐœ๋งŒ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•ด๋„ ํฐ ๋ฌธ์ œ๋Š” ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ๋ชจ๋“  ๊ณ ์ • ์žฅ์น˜์— ๋Œ€ํ•œ ์˜ต์…˜(๊ธฐ๋ณธ๊ฐ’?)์„ ์„ค์ •ํ•˜๊ณ  ์žˆ์Œ์„ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์†์„ฑ์˜ ์ด๋ฆ„์— ๋Œ€ํ•ด ์•„๋ฌด ์ƒ๊ฐ์ด ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ์–ธ๊ธ‰ํ•œ ๋ฐ”๋กœ ๊ทธ ์ด์œ ๋กœ ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์˜ ๊ธฐ๋ณธ๊ฐ’๋„ ์–ด๋Š ์ •๋„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์†์„ฑ์ด ์—†๋Š” ๊ฐ ๊ณ ์ • ํด๋ž˜์Šค์— ์ƒˆ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„๊ตํ•˜์—ฌ ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์†์„ฑ์ด ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.

@nunit/framework-team ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”? ๊ธฐ๋Šฅ์˜ ์ดˆ๊ธฐ ๋„์ž…:

  • ์˜ˆ/์•„๋‹ˆ์˜ค ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์„ค์ •?
  • ์กฐ๋ช…๊ธฐ ์ˆ˜์ค€ ์„ค์ •์— ์˜ˆ/์•„๋‹ˆ์š”?
  • ๋ฐฉ๋ฒ• ์ˆ˜์ค€ ์„ค์ •์— ์˜ˆ/์•„๋‹ˆ์š”?
  • ์˜ˆ/์•„๋‹ˆ์˜ค ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ˆ˜์ค€ ์„ค์ •?

์†์„ฑ ์—†๋Š” ์กฐ๋ช…๊ธฐ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ข‹์€ ์ ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์˜ˆ, ์˜ˆ, ์•„๋‹ˆ์˜ค, ์•„๋‹ˆ์˜ค๋ผ๊ณ  ๋งํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค

๋‚˜๋Š” Charlie์˜ ๋ง์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. 'fixture-level'์ด 'class-level'์„ ์˜๋ฏธํ•œ๋‹ค๋Š” ์„ค๋ช…์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ๋ฅผ ๋“ค์–ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์†Œ์Šค ๋ฐฉ๋ฒ•๊ณผ ๋ฐ˜๋Œ€์ž…๋‹ˆ๋‹ค. ๐Ÿ˜Š)

๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค! ๋”ฐ๋ผ์„œ [TestFixture(FixtureCreationOptions.PerTestCase)] ์˜ ๋ฌธ์ œ๋Š” ๋™์ผํ•œ ํด๋ž˜์Šค์—์„œ ์—ฌ๋Ÿฌ TestFixture ์†์„ฑ์ด ํ—ˆ์šฉ๋˜๊ณ  ์„œ๋กœ ๋ชจ์ˆœ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ์™€ ํด๋ž˜์Šค์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋ช…๋ช…๋œ ํŠน์„ฑ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ๋” ์ข‹๊ณ  ๊ฐ„๋‹จํ•ฉ๋‹ˆ๊นŒ?

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: ShareFixtureInstances(๊ฑฐ์ง“)]

[ShareFixtureInstances(๊ฑฐ์ง“)]
๊ณต๊ฐœ ํด๋ž˜์Šค SomeFixture
{
// ...
}

Framework API:

```diff
namespace NUnit.Framework
{
+   [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class)]
+   public sealed class ShareFixtureInstancesAttribute : PropertyAttribute
+   {
+       public bool ShareFixtureInstances { get; }

+       public ShareFixtureInstancesAttribute(bool shareFixtureInstances);
+   }
}

์ž˜ ๋“ค๋ฆฐ๋‹ค. ์ด๊ฒƒ์˜ ์ƒ์† ๋™์ž‘์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ž์ฒด ํ…Œ์ŠคํŠธ์™€ ํ•จ๊ป˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ํŠน์„ฑ์ด ์žˆ๊ณ  ํ•ด๋‹น ํด๋ž˜์Šค์—์„œ ์ƒ์†ํ•˜๋Š” ๊ฒฝ์šฐ? ๐Ÿ˜Š

์•„๋งˆ๋„ 'ํด๋ž˜์Šค' ์†์„ฑ์ด๋ฏ€๋กœ ๋ฌธ์ œ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹ค์ œ ํด๋ž˜์Šค์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋˜ํ•œ, ๋‚˜๋Š” ๊ทธ ์ด๋ฆ„์— ์™„์ „ํžˆ ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ณ ์ • ์žฅ์น˜๊ฐ€ ํ•ญ์ƒ ๋‹จ์œ„ ์šฉ์–ด๋กœ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— (์˜ˆ: testcasesource์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ - 'suite'์™€ 'fixture'๊ฐ€ ๋” ๊ฐ•๋ ฅํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ํ•œ) ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Nunit ์šฉ์–ด๋กœ ์ƒ๊ฐ๋ณด๋‹ค ์˜๋ฏธ!)

InstancePerTest์˜ ๋ผ์ธ์„ ๋”ฐ๋ผ ...ํ•˜์ง€๋งŒ ๋” ๋‚˜์€ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์–ด์…ˆ๋ธ”๋ฆฌ ๋ฐ ํด๋ž˜์Šค ์ˆ˜์ค€์— ๋Œ€ํ•ด ๋™์˜ํ–ˆ์ง€๋งŒ ๋” ์ด์ƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ @ChrisMaddock ์˜ ์ œ์•ˆ ClassInstancePerTest(bool) ๋ผ์ธ์„ ๋”ฐ๋ผ ๋ฌด์–ธ๊ฐ€๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํด๋ž˜์Šค ์ˆ˜์ค€์˜ ํŠน์„ฑ์ด ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์„ ์žฌ์ •์˜ํ•˜๊ณ  ์ƒ์†๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์†์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์™€ ๊ฒฐํ•ฉ๋œ ํด๋ž˜์Šค์˜ ๊ตฌ์„ฑ์›์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŒŒ์ƒ ํด๋ž˜์Šค์— ์ž๋™์œผ๋กœ ์ ์šฉ๋˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜ ์œ ํ˜•์ด ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ NUnit์ด ํ…Œ์ŠคํŠธ๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์— ์ •๋ง ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์ €๋Š” ํ•ญ์ƒ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์Šค์บํด๋”ฉ์„ ์„ค์ •ํ•˜๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์Šค์บํด๋”ฉ์ด ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๊ฐ„์— ์˜๋„ํ•˜์ง€ ์•Š์€ ์ƒํƒœ ์ „์†ก์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. @jnm2 ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์˜ˆ๋ฅผ ๋“ค์–ด ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œํ•  ๋•Œ ์ผ€์ด์Šค ๋Ÿฌ๋„ˆ๋Š” ์ •๋ง ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค. IDisposable์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋” ์ด์ƒ ๋งˆ๋ฒ• ๊ฐ™์€ [TearDown] ๋Š” ์—†์Šต๋‹ˆ๋‹ค. :( ์Šค์บํด๋”ฉ ์˜ค๋ฅ˜์—์„œ ํ…Œ์ŠคํŠธ ์˜ค๋ฅ˜๋ฅผ โ€‹โ€‹๊ตฌ๋ณ„ํ•˜๋Š” ์ผ๊ด€๋œ ๋ฐฉ๋ฒ•๋„ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ •๋ง ๊ณ ํ†ต์Šค๋Ÿฌ์šด ์‚ฌ์šฉ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

๋””์ž์ธ์— ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด @CharliePoole ๊ณผ ํ•จ๊ป˜ yes, yes, no, no์ž…๋‹ˆ๋‹ค.

PerTestInstance , InstancePerTest ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ์ด๋ฆ„์ด ShareFixtureInstances ๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” F# ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์œ ํ˜• ์ธ์Šคํ„ด์Šค๊ฐ€ ํด๋ž˜์Šค ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์†์„ฑ ์ด๋ฆ„์— Class ๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์•ฝ๊ฐ„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ๊ทธ๊ฑธ๋กœ ์‚ด ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค! :)

์˜ค, ์ด ๊ธฐ๋Šฅ์ด ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค!

@kkm000 "class" ์‚ฌ์šฉ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. NUnit์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌํ˜„๊ณผ ๊ตฌ๋ณ„๋˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋•Œ๋„ ์‚ฌ๋žŒ๋“ค์€ ์ถ”์ธก์„ ํ•˜์ง€๋งŒ ๊ทธ๋Ÿฐ ์ผ์€ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ผ๊ด€์„ฑ์ด ์žˆ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๋‚ด๊ฐ€ ๋งํ•˜๋Š” ๊ฒƒ์˜ ์˜ˆ: Test, TestFixture, SetUpFixture, Worker(์Šค๋ ˆ๋“œ ์•„๋‹˜) ๋“ฑ. ์›์น™์ ์œผ๋กœ __could__ ํด๋ž˜์Šค๋Š” ๊ณ ์ • ์žฅ์น˜๊ฐ€ ์•„๋‹Œ ๋‹จ์ผ ํ…Œ์ŠคํŠธ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค... ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ฑฐ๋‚˜ ์‹ฌ์ง€์–ด๋Š” ํ•ด์•ผ ํ•˜์ง€๋งŒ __ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค__.

@kkm000

๋Œ“๊ธ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‹น์‹ ์€ ์ „ํ˜€ ๋ผ์–ด๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ์–ธ์–ด์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ๋””์ž์ธ ๋ชฉํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
C#์— ์ดˆ์ ์„ ๋งž์ถ”๋Š” ๊ฒƒ ์™ธ์— class ๋ผ๋Š” ๋‹จ์–ด์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์ ์€: ์–ธ์  ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์„ค๋น„๋ฅผ ์ง€์›ํ•œ๋‹ค๋ฉด?

[InstancePerTestCase] ๋Š” ๋ฌธ์ œ๋ฅผ ํšŒํ”ผํ•˜์ง€๋งŒ ์ง๊ด€์ ์ธ ๋ช…ํ™•์„ฑ์„ ์žƒ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋‚  ๋น„ํ’ˆ๊ณผ ํด๋ž˜์Šค๋Š” ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์ง€๋งŒ ๋งŒ์•ฝ ๊ทธ๋“ค์ด ๊ฐˆ๋ผ์ง„๋‹ค๋ฉด ์ด ์†์„ฑ์€ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๊ณ ์ •๋ฌผ๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

์Šค์œ„ํŠธ๋Š” ์ผ๋ฐ˜์ ์ธ ์กฐ์ง ๊ฐœ๋…์ธ ๋ฐ˜๋ฉด ๊ณ ์ • ์žฅ์น˜๋Š” ์„ค์ •/ํ•ด์ œ ๋…ผ๋ฆฌ ๋ฐ ํ…Œ์ŠคํŠธ ์ƒํƒœ๋ฅผ ๋ณด์œ ํ•˜๊ณ  ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์— ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(ํ˜„์žฌ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ์˜ this ์ธ์ˆ˜๋กœ). ์„ค๋น„๊ฐ€ ์กฐ์ง ๊ณ„์ธต์˜ ์ผ๋ถ€์ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ๊ฐœ๋…์—์„œ ๋ฒ—์–ด๋‚˜๊ณ  ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์˜ ๊ฐœ๋…์—์„œ ๋ฒ—์–ด๋‚˜๋Š” ํ”ฝ์Šค์ฒ˜๋ฅผ ์ƒ์ƒํ•ด ๋ด…์‹œ๋‹ค.

```c#
public static class SomeTestSuite // ๊ณ ์ • ์žฅ์น˜๊ฐ€ ์•„๋‹˜: ์„ค์ •/ํ•ด์ œ ๋…ผ๋ฆฌ ๋ฐ ํ…Œ์ŠคํŠธ ์ƒํƒœ ์—†์Œ
{
[Test] // ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ์Šค์œ„ํŠธ๊ฐ€ ์•„๋‹Œ ๋‹จ์ผ ํ…Œ์ŠคํŠธ;
// ๊ณ ์ •๋ฌผ์€ ์•”์‹œ์  this ๋งค๊ฐœ๋ณ€์ˆ˜ ๋Œ€์‹  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค.
๊ณต๊ฐœ ์ •์  ๋ฌดํšจ SomeTest(SomeFixture ๊ณ ์ • ์žฅ์น˜)
{
๊ณ ์ •.SomeService.SomeProperty = true;
๊ณ ์ •.SomeAction();
๊ณ ์ •.AssertSomething();
}
}

[ํ…Œ์ŠคํŠธํ”ฝ์Šค์ฒ˜]
๊ณต๊ฐœ ๊ตฌ์กฐ์ฒด SomeFixture : IDisposable
{
๊ณต๊ฐœ SomeService SomeService { ๊ฐ€์ ธ์˜ค๊ธฐ; } // ์ƒํƒœ

public SomeFixture() // This was almost legal syntax in C# 6, but I'm making a point ๐Ÿ˜
{
    // Setup
}

public void Dispose()
{
    // Teardown
}

public void SomeAction()
{
    // Helper method
}

public void AssertSomething()
{
    // Helper method
}

}
```

์œ„์˜ ์˜ˆ์—์„œ [FixtureInstancePerTestCase] ๋˜๋Š” [SharedFixtureInstances(false)] ๋Š” ํด๋ž˜์Šค์— ์ค‘์ ์„ ๋‘์ง€ ์•Š๊ณ  ๊ณ„์ธต ๊ตฌ์กฐ(์ˆ˜ํŠธ)์— ์ค‘์ ์„ ๋‘์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ณ ์ • ์žฅ์น˜์— ์ค‘์ ์„ ๋‘๊ณ  ๊ณ ์ • ์žฅ์น˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„ค์ •/ํ•ด์ œ ๋…ผ๋ฆฌ ๋ฐ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ, ๊ฐ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด SomeFixture ๊ฐ€ ์ƒ์„ฑ๋˜๋Š”์ง€ ๋˜๋Š” ๋™์ผํ•œ ํ•ญ๋ชฉ์ด ๊ฐ ํ…Œ์ŠคํŠธ์— ์ „๋‹ฌ๋˜๋Š”์ง€ ์—ฌ๋ถ€์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

์ด ์†์„ฑ์€ ๋‹ค๋ฅธ ITest๊ฐ€ ITest.Fixture ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ œ์–ดํ•˜๊ณ  ์ œ์–ด๋˜๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ [TestFixture] (์ด๋ฆ„์— Fixture ๊ฐ€ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ์†์„ฑ)๋กœ ์žฅ์‹ํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ž…๋‹ˆ๋‹ค. Fixture๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” _consistent_ ์˜ต์…˜.

(ํ† ๋ก ํ•ด์•ผ ํ•  ์ค‘์š”ํ•ด ๋ณด์ด๋Š” ์š”์ ์„ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ์ง€๋งŒ ์ด๋ฆ„์ด ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด์„œ๋Š” ๋ณ„๋กœ ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค.)

@jnm2 Suite์™€ Fixture์˜ ๊ฐœ๋…์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š”

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ xunit.net์€ ํ”ฝ์Šค์ฒ˜๋ฅผ ํ…Œ์ŠคํŠธ ์ƒ์† ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ๋ถ„๋ฆฌ๋œ ์—”ํ„ฐํ‹ฐ๋กœ ๋งŒ๋“  ์ตœ์ดˆ์˜(์œ ์ผํ•œ?) ํ”„๋ ˆ์ž„์›Œํฌ์˜€์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ TestCaseSource๋ฅผ ๋ณ„๋„์˜ "ํ”ฝ์Šค์ฒ˜"๋กœ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ง€๊ธˆ ๊นจ์งˆ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ๋žŒ๋“ค์ด ๊ฐ€๋”(๋ณ‘๋ ฌํ™” ์ด์ „์—) ์‚ฌ๋ก€๋ณ„ ๋™์ž‘์— ๋Œ€ํ•ด ๋ฌป๋Š” ์ด์œ ๋Š” ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํ•˜๋Š” ์ผ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋น„์Šทํ•œ ์ด์œ ๋กœ ๊ทธ๋“ค์€ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅํ•œ ๋น„ํ’ˆ์„ ์š”๊ตฌํ•˜์ง€ __ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค__.

๊ฒฐ๋ก ์ ์œผ๋กœ ์ œ ์ƒ๊ฐ์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค...

  1. ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๋™์ž‘๋งˆ๋‹ค ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  2. ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ๊ฐ’์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  3. ๋ถ„๋ฆฌ ๊ฐ€๋Šฅํ•œ ๊ณ ์ • ์žฅ์น˜๋Š” ๋ฉ‹์ง„ ์•„์ด๋””์–ด์ด์ง€๋งŒ ๋ณ„๊ฐœ์˜ ๋ฌธ์ œ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

  4. ๋ถ„๋ฆฌ ๊ฐ€๋Šฅํ•œ ๊ณ ์ • ์žฅ์น˜๋Š” ์ตœ์†Œํ•œ ์ธ์Šคํ„ด์Šค ๊ณ ์ • ์žฅ์น˜๋งŒํผ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ๋ณต์žกํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด ๊ฒฝ์šฐ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค.

3๋ฒˆ๊ณผ 4๋ฒˆ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์ƒ˜ํ”Œ์„ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ œ์•ˆ์ด ์•„๋‹ˆ๋ผ ์ด ์†์„ฑ์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ์ด๋ฆ„์„ ์ฐพ๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์‚ฌ๊ณ  ์‹คํ—˜์œผ๋กœ ์˜๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๊ณ  ์‹คํ—˜์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ์šฐ์—ฐํžˆ ์ผ์น˜ํ•˜๋”๋ผ๋„ ํด๋ž˜์Šค๋‚˜ ์Šค์œ„ํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ณ ์ • ์žฅ์น˜์˜ ์•„์ด๋””์–ด์— ์ •๋ง๋กœ ์ง‘์ค‘ํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

์–ด๋–ค ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๋“  ์กฐ๋ช…๊ธฐ๋Š” ์„ค์ •/ํ•ด์ฒด/์ƒํƒœ์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ •์˜์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‹จ์–ด์˜ ์˜๋ฏธ๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. Fixture instance(setup/teardown/state์˜ ๋ฐœ์ƒ)๋Š” ์šฐ๋ฆฌ์˜ ์ƒˆ๋กœ์šด ์†์„ฑ์ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๊ฐ„์— ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ๊ณต์œ ํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฆ„์˜ ์–ด๋”˜๊ฐ€์— FixtureInstances ์žˆ์œผ๋ฉด ์ตœ๋Œ€์˜ ๋ช…๋ฃŒ์„ฑ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์˜ณ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ์–ด๋–ค ๋‹ค๋ฅธ ์ ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์•„! ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ„๊ณผ๋˜๋Š” ๋งค์šฐ ์ข‹์€ ์ ์„ ์ง€์ ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ๋น—๋‚˜๊ฐ„ ๊ฒƒ์€ ์•„๋‹๊นŒ ๊ฑฑ์ •๋„ ๋ฉ๋‹ˆ๋‹ค. :์•ฝ๊ฐ„_์ฐก๊ทธ๋ฆฐ_์–ผ๊ตด:

์ „์ฒด ์ด๋ฆ„(๋ฌด์—‡์„ ์ž…๋ ฅํ•˜๋“ ์ง€)์—๋Š” Fixture์™€ Instance๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜ํ–‰ ๋ฐฉ๋ฒ•์€ ์†์„ฑ ์ด๋ฆ„ ๋˜๋Š” ๊ตฌ์„ฑ์— ์‚ฌ์šฉ๋œ ์—ด๊ฑฐํ˜•์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜์— ์ •์ฐฉํ–ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋„ค, ์ข‹์€ ์ง€์ ์ž…๋‹ˆ๋‹ค.

์—ด๊ฑฐํ˜•์„ ํ•˜๋ฉด ์ž…๋ ฅํ•˜๋Š” ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์–ด์…ˆ๋ธ”๋ฆฌ ๋Œ€์ƒ ์†์„ฑ๋ณด๋‹ค ํด๋ž˜์Šค ๋Œ€์ƒ ์†์„ฑ์— ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ํด๋ž˜์Šค์—์„œ ์—ฌ๋Ÿฌ TestFixtureAttributes๊ฐ€ ํ—ˆ์šฉ๋˜๊ณ  ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ชจ์ˆœ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ด๊ฑฐํ˜•์„ TestFixtureAttribute ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์‹œ๊ฐ„ ์˜ค๋ฅ˜๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž˜๋ชป๋œ ์ƒํƒœ๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์˜ต์…˜์„ ์„ค์ •ํ•˜๊ณ  ๊ฑฐ๊ธฐ์—์„œ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๋Š” ์ง๊ด€์„ฑ, NUnit์˜ ์Šคํƒ€์ผ๊ณผ์˜ ์ผ๊ด€์„ฑ, ์ ์ ˆํ•œ ์–‘์˜ ์œ ์—ฐ์„ฑ ์‚ฌ์ด์—์„œ ๊ท ํ˜•์„ ์ด๋ฃจ๋Š” ๊ฒƒ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ๋‚ด์šฉ์€ ์ด๋ฏธ ์ค‘๋ณต๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜„)


์ œ์•ˆ A

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: FixtureOptions(InstancePerTestCase = true)]

[FixtureOptions(InstancePerTestCase = false)]
ํด๋ž˜์Šค SomeFixture
{
}

Pro: extending later if there's ever more options for fixture handling (doubtful?)
Pro: two names so there's less stuffed into a single name
Con: `[FixtureOptions]` would be legal but highly misunderstandable syntax. (Does it reset the assembly-wide setting to the default, `false`, or does it have no effect, e.g. `null`?)


### Proposal B

```c#
[assembly: FixtureOptions(FixtureCreationOptions.PerTestCase)]

[FixtureOptions(FixtureCreationOptions.Singleton)]
class SomeFixture
{
}

public enum FixtureCreationOptions
{
    Singleton, // = default
    PerTestCase,
    // Doubtful there will be other options?
    // Maybe Pool, where we reset and reuse between nonconcurrent tests?    
}

์žฅ์ : ์ž˜๋ชป๋œ ์ƒํƒœ๋Š” ํ‘œํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
์žฅ์ : ๊ณ ์ • ์žฅ์น˜ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์˜ต์…˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋‚˜์ค‘์— ํ™•์žฅ(์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๊นŒ?)
๋‹จ์ : ์†์„ฑ ์ด๋ฆ„๊ณผ ์—ด๊ฑฐํ˜• ์ด๋ฆ„์„ ๋ชจ๋‘ ์ž…๋ ฅํ•  ๋•Œ ์ค‘๋ณต๋จ

์ œ์•ˆ C

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: FixtureInstancePerTestCase]

[FixtureInstancePerTestCase(๊ฑฐ์ง“)]
ํด๋ž˜์Šค SomeFixture
{
}
```

์žฅ์ : ์ž˜๋ชป๋œ ์ƒํƒœ๋Š” ํ‘œํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
์žฅ์ : ์˜คํ•ดํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค(ํ•˜์ง€๋งŒ ์ €๋Š” ์‹ ๊ทœ ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์— ๋งน์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค)
๋‹จ์ : ๊ธด ์ด๋ฆ„
์•„๋งˆ๋„ con: ์˜ต์…˜๊ณผ ๊ฐ’์„ ๋ชจ๋‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. (ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” [NonParallelizable] ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.)


(๋Œ€์ฒด ์ œ์•ˆ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!)

์–ด์…ˆ๋ธ”๋ฆฌ์— ๋Œ€ํ•œ ์†์„ฑ๊ณผ ํด๋ž˜์Šค ์ž์ฒด์— ๋Œ€ํ•œ ์†์„ฑ์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์†์„ฑ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ : ์ปจํ…์ŠคํŠธ์—์„œ ๋‹ค๋ฅธ ๋™์ž‘์„ ๊ฐ€์ง„ ํ•˜๋‚˜์˜ ์†์„ฑ๋ณด๋‹ค ๋‘ ๊ฐœ์˜ ๊ฐ„๋‹จํ•œ ์†์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. (ParallelizableAttribute์—์„œ ๋ฐฐ์šด ๊ตํ›ˆ)
์žฅ์ : ๊ฐ๊ฐ์˜ ์ด๋ฆ„์„ ์ ์ ˆํ•˜๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์—๋Š” "๊ธฐ๋ณธ๊ฐ’"์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹จ์ : ๊ธฐ์–ตํ•ด์•ผ ํ•  ๋‘ ๊ฐ€์ง€ ์†์„ฑ.

๊ฐ๊ฐ์˜ ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘๊ทผ:

```C#
[์–ด์…ˆ๋ธ”๋ฆฌ: DefaultFixtureOptions(InstancePerTestCase = true)]

[FixtureOptions(InstancePerTestCase = false)]
ํด๋ž˜์Šค SomeFixture
{
}

[์–ด์…ˆ๋ธ”๋ฆฌ: DefaultFixtureOptions(FixtureCreationOptions.PerTestCase)]

[FixtureOptions(FixtureCreationOptions.Singleton)]
ํด๋ž˜์Šค SomeFixture
{
}

[์–ด์…ˆ๋ธ”๋ฆฌ: DefaultFixtureInstancePerTestCase]

[FixtureInstancePerTestCase(๊ฑฐ์ง“)]
ํด๋ž˜์Šค SomeFixture
{
}
```

๊ธฐํƒ€ ์˜๊ฒฌ:

  • ๋‚˜๋Š” C๋ณด๋‹ค A์™€ B๋ฅผ ๋” ์ข‹์•„ํ•œ๋‹ค
  • ๊ณต์œ  ์กฐ๋ช…๊ธฐ ๋™์ž‘์„ "์‹ฑ๊ธ€ํ†ค"์ด๋ผ๊ณ  ๋ถ€๋ฅด๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์ด ํ•˜๋‚˜๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. :smile: ์ƒ์†์„ ๋ฐ›์œผ๋ฉด ๊ธฐ๋ณธ ์„ค๋น„์˜ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์–ด์…ˆ๋ธ”๋ฆฌ์™€ ์กฐ๋ช…๊ธฐ ์ˆ˜์ค€์—์„œ ๋ณ„๋„์˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์‹ค์ œ๋กœ ์กฐ๋ช…๊ธฐ ์ˆ˜์ค€์—์„œ ์ด๋ฆ„์—์„œ ์กฐ๋ช…๊ธฐ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” SetUpFixtures๊ฐ€ ์ด๊ฒƒ์— ์–ด๋–ป๊ฒŒ ๋งž๋Š”์ง€ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉฐ ์†์„ฑ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ์†์„ฑ์˜ ํ•œ ๊ฐ€์ง€ ์žฅ์ ์€ ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์„ ๋‹ค๋ฃฐ ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋˜ํ•œ TestFixture, BTW์˜ ์†์„ฑ์— ๋Œ€ํ•œ ์žฅ์ ์ž…๋‹ˆ๋‹ค)
  • ์šฐ๋ฆฌ๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šค๊ฐ€ ์ •์  ํด๋ž˜์Šค์— ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊ฒฝ๊ณ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ ๋ชจ๋‘์—๊ฒŒ ๋ถ„๋ช…ํ•˜์ง€๋งŒ ์ฆ‰์‹œ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

BTW, ๋‚˜๋Š” ์ข…์ข… ์–ด์…ˆ๋ธ”๋ฆฌ ๋ฐ ๊ณ ์ • ์žฅ์น˜ ์ˆ˜์ค€์— ๋Œ€ํ•ด DefaultTestCaseTimeOut์„ ์‚ฌ์šฉํ•˜๊ณ  Timeout์„ ๋ฉ”์„œ๋“œ๋กœ๋งŒ ์œ ์ง€ํ–ˆ์œผ๋ฉด ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ€๋Šฅ์„ฑ์„ ์ œ์‹œํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ ์ €๋ฅผ ๊ดด๋กญํžˆ๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ด ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๊ณ  ์žˆ์ง€ ์•Š๋”๋ผ๋„ ์ด๊ฒƒ์ด ์ด๋ก ์ ์œผ๋กœ ์˜๋ฏธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

c# [DefaultFixtureOptions(InstancePerTestCase = true)] class SomeFixture { [FixtureOptions(InstancePerTestCase = false)] public void SomeTest() { } }

์ด๊ฒƒ์ด ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ๋ ˆ๋ฒจ์€ ์กฐ๋ช…๊ธฐ ๋ ˆ๋ฒจ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๋ ˆ๋ฒจ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ํŒŒ์ƒ๋œ ํ”ฝ์Šค์ฒ˜๋Š” ๊ธฐ๋ณธ ํ”ฝ์Šค์ฒ˜์˜ ์„ค์ •์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ ํ•˜๋Š” ์ผ์€ ํŒŒ์ƒ๋œ ํด๋ž˜์Šค์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์„ค์ •์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜๋Š”:

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: DefaultFixtureOptions(InstancePerTestCase = true)]

// ์ด๊ฒƒ์ด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ„์ฃผ๋˜์–ด์„œ๋Š” ์•ˆ ๋˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
[DefaultFixtureOptions(InstancePerTestCase = true)]
๊ณต๊ฐœ ์ถ”์ƒ ํด๋ž˜์Šค BaseFixture
{
}

๊ณต๊ฐœ ๋ด‰์ธ ํด๋ž˜์Šค SomeFixture : BaseFixture
{
}
```

Default ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•  ๋•Œ์™€ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•  ๋•Œ์— ๋Œ€ํ•œ ๊ทผ๊ฑฐ๋Š” ์–ด๋–ป๊ฒŒ ์ฐพ๋‚˜์š”?

๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์—์„œ ์ด ์†์„ฑ์„ ๊ตฌํ˜„ํ•˜๋ฉด ์ž‘์€ ์ด์ ์œผ๋กœ ๋งŽ์€ ๋ณต์žก์„ฑ์ด ๋„์ž…๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

"์ผ๋ฐ˜" ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์˜ ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์™€ ์—ฐ๊ฒฐ๋œ ๋ช…๋ น ์ฒด์ธ์˜ ์ผ๋ถ€๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณ„์† ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ณ„ ํ”ฝ์Šค์ฒ˜์˜ ๊ฒฝ์šฐ ์ธ์Šคํ„ด์Šคํ™”ํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ ์ฒด์ธ์˜ ์ผ๋ถ€๋กœ ์ƒˆ ๋ช…๋ น์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ ํ˜„์žฌ ํ”ฝ์Šค์ฒ˜ ์ฒด์ธ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๊ณ ์ • ์žฅ์น˜์— ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ ๋ชจ๋ธ์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์”ฉ ๋‘ ๋ฒˆ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณ„๋„์˜ ๊ณ ์ • ์žฅ์น˜๋กœ ๋ถ„ํ• ํ•˜์—ฌ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์ ์€ ์ž‘์•„ ๋ณด์ž…๋‹ˆ๋‹ค. ํ”ฝ์Šค์ฒ˜๋Š” ๊ฒฐ๊ตญ NUnit ์•„ํ‹ฐํŒฉํŠธ์ด๋ฉฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋™์ผํ•œ ํ”ฝ์Šค์ฒ˜ ๋™์ž‘์ด ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๋™์ผํ•œ ํ”ฝ์Šค์ฒ˜์— ๋„ฃ๋„๋ก ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.

"๊ธฐ๋ณธ๊ฐ’"์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ด€๋ จํ•˜์—ฌ... ์–ด๋–ค TestFixxture์—์„œ๋„ __not__ ์‚ฌ์šฉํ•˜๊ณ  ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์†์„ฑ์€ ์ƒ์† ๋•๋ถ„์— ํŒŒ์ƒ๋œ ํด๋ž˜์Šค์—์„œ ์‹ค์ œ๋กœ ๋ฐœ๊ฒฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ํด๋ž˜์Šค๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฒ ์ด์Šค์—์„œ ํŠน์ • ๋™์ž‘์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹™๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ๊ทธ๊ฒƒ์€ ๊ทธ ํด๋ž˜์Šค์™€ ๊ทธ๊ฒƒ์—์„œ ํŒŒ์ƒ๋œ ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•œ ์„ค์ •์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์ƒ์†๋œ ์†์„ฑ์˜ ๋ชจ๋“  ๊ฒฝ์šฐ์—์„œ์™€ ๊ฐ™์ด ๋ชจ์ˆœ๋˜๋Š” ์‚ฌ์–‘์€ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค๊ฑฐ๋‚˜ ๋ฌด์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ์†์„ฑ A๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ํŒŒ์ƒ ํด๋ž˜์Šค์— B๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ์ง์ ‘ A ๋ฐ B๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ตฌ๋ณ„๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋†€๋ž„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.

WRT ์„ค์ • ํ”ฝ์Šค์ฒ˜, btw, ๊ฑฐ๊ธฐ์—์„œ ์ธ์Šคํ„ด์Šคํ™” ์˜ต์…˜์„ ์ง€์ •ํ•˜๋ ค๋ฉด ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. SetUpFixtures๋Š” TestFixtures๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์ฆ‰, ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ์†์„ฑ A๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ํŒŒ์ƒ ํด๋ž˜์Šค์— B๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ ํด๋ž˜์Šค์— ์ง์ ‘ A ๋ฐ B๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ตฌ๋ณ„๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋†€๋ž„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ง™์†Œ์‚ฌ, [Apartment] ๋˜๋Š” [Parallelizable] ๊ฐ€ ๊ธฐ๋ณธ ํด๋ž˜์Šค' ๋˜๋Š” ๊ธฐ๋ณธ ๋ฉ”์†Œ๋“œ์˜ ์„ค์ •์„ ๋Œ€์ฒดํ•  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์ด ๋ชจ๋“  ๊ฒƒ์ด ๋‚˜์—๊ฒŒ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

FixtureCreationOptions ์™€ ๊ฐ™์€ ์—ด๊ฑฐํ˜•์„ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ฐฐ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? PerTestCase , PerFixture , ๊ฐ€์ƒ ReusedPerTestCase ?

๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ์ˆœ์„ฑ์— ๊ธฐ๋Œ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

```c#
[์–ด์…ˆ๋ธ”๋ฆฌ: DefaultFixtureOptions(InstancePerTestCase = true)]

[FixtureOptions(InstancePerTestCase = false)]
ํด๋ž˜์Šค SomeFixture
{
}

Hypothetical other creation options would then be added this way:
```c#
[FixtureOptions(InstancePerTestCase = false, ReuseInstances = true)]

@nunit/framework-team ๋‹น์‹ ์˜ ์ทจํ–ฅ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์— ๊ด€ํ•˜์—ฌ

[assembly: DefaultFixtureOptions(InstancePerTestCase = true)]

์ €๋งŒ ๊ทธ๋Ÿด ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์†์„ฑ์€ ํ‘œ์‹œ๋œ ๋Œ€์ƒ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŠน์ • ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์œผ๋กœ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์— ๋Œ€ํ•œ ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ํŠน์„ฑ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Serializable์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์žฅ์‹๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. InternalsVisibleTo--๋‚ด๋ถ€๋Š” ํŠน์ • ํ•ญ๋ชฉ์— ํ‘œ์‹œ๋˜๊ณ  ์ธ์ˆ˜๋Š” ์ด๋ฅผ ๊ตฌ์ฒดํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚ด๋ถ€ ํ•ญ๋ชฉ์€ ์•„๋ฌด์—๊ฒŒ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์†์„ฑ์€ ํŒจํ„ด์„ ๋”ฐ๋ฅด์ง€ ์•Š์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‚ฎ์€ ์ˆ˜์ค€(์˜ˆ: CompilationRepresentation, MethodImpl)์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ•„์ˆ˜ ์ƒ์„ฑ์ž ์ธ์ˆ˜์™€ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ๊ณ ๋ ค
c# [assembly: DefaultFixtureOptions]
InstancePerTestCase ๋Œ€ํ•œ ํ• ๋‹น์€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ฏ€๋กœ ์ด๊ฒƒ์€ ์ž˜ ๊ตฌ์„ฑ๋œ C#์ž…๋‹ˆ๋‹ค. ์˜๋ฏธ์ƒ์œผ๋กœ ๋ฌด์—‡์„ ํ‘œํ˜„ํ•ฉ๋‹ˆ๊นŒ?

๋‚˜์—๊ฒŒ [assembly: DefaultFixtureInstancePerTestCase] ๋Š” ๋” ์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์ธ๋‹ค(๊ทธ์˜ sesquipedalian ์ด๋ฆ„์„ ์ œ์™ธํ•˜๊ณ ๋Š”, ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ์˜๊ฒฌ์ผ ๋ฟ์ด๋ฉฐ ๋ฏธํ•™์ ์œผ๋กœ ์ •๋‹นํ™”๋  ์ˆ˜ ์—†์Œ). ํ•˜๋‚˜์˜ ์†์„ฑ, ํ•˜๋‚˜์˜ ํŠน์„ฑ. ์•„๋งˆ๋„ ์ด๊ฒƒ์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋‚˜ ์„ ํƒ์ ์œผ๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•œ ์†์„ฑ์ด ํ•„์š”ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์‚ฌ์šฉ์ž๋กœ์„œ ์ด๋ฆ„์ด ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ์†์„ฑ์ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋†€๋ž์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์—์„œ๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ ( DefaultSomething ) ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์œ ํ˜• ์ˆ˜์ค€์—์„œ๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹จ์ง€ Something ). . ๋‹น์—ฐํžˆ ๋‚˜๋Š” @CharliePoole ์ด Parallelizable ์†์„ฑ์— ๊ด€ํ•ด ์–ธ๊ธ‰ํ•œ "ํ•™์Šต๋œ ๊ตํ›ˆ"์ด ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜์ง€๋งŒ , ์„ฌ์˜ ์ด์ชฝ์—์„œ (์ด ์‚ฌ์šฉ์ž์˜ ํ”ผ์ƒ์ ์ธ ์ƒ๊ฐ์—์„œ) ์ˆ˜ํ–‰ํ•  ์œ„์น˜๋ฅผ ๋ฐฐ์šฐ๋Š” ํ•œ ์Œ์˜ ์†์„ฑ์€ ๋‹นํ˜น์Šค๋Ÿฌ์›Œ ๋ณด์ž…๋‹ˆ๋‹ค.

@kkm000 ๋‹จ์ผ ํŠน์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์†์„ฑ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ˆ˜์ค€์—์„œ "๋™์ผํ•œ" ํŠน์„ฑ์— ๋Œ€ํ•ด ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์†์„ฑ์„ WRTํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋™์ผํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด ๋™์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Timeout์„ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•์— ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ "์ด ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•์€ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์ง€์ •๋œ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฉด ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋ฉ๋‹ˆ๋‹ค."๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Timeout์ด ์„ค๋น„ ๋˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์— ๋ฐฐ์น˜๋˜๋ฉด "์ด ํ•ญ๋ชฉ์— ํฌํ•จ๋œ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ๊ธฐ๋ณธ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋Š” ์ง€์ •๋œ ๋ฐ€๋ฆฌ์ดˆ ์ˆ˜์ž…๋‹ˆ๋‹ค."๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ทธ ๊ธฐ๋ณธ๊ฐ’์€ ๋” ๋‚ฎ์€ ์ˆ˜์ค€์—์„œ ์žฌ์ •์˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‘ ๊ฐ€์ง€ ๋ณ„๋„์˜ ๊ตฌํ˜„์ด ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ๋‹ค์†Œ ๋‹ค๋ฅธ ์˜๋ฏธ. ์ฒซ ๋ฒˆ์งธ๋Š” ํ‘œ์‹œ๋˜๋Š” ํ…Œ์ŠคํŠธ์— ์‹œ๊ฐ„ ์ดˆ๊ณผ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ํฌํ•จ๋œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋ฐœ๊ฒฌ๋˜๊ณ  ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์— ๊ธฐ๋ณธ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ParallelizableAttribute๋„ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด ํŠน์ • ๊ฒฝ์šฐ์— ํ”ฝ์Šค์ฒ˜์— ๋ฐฐ์น˜๋œ ์†์„ฑ์€ "ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ํ•œ ๋ฒˆ ์ด ํ”ฝ์Šค์ฒ˜๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค."๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์—์„œ "๋‹ฌ๋ฆฌ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ด ์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ๊ณ ์ • ์žฅ์น˜๋‹น ํ•œ ๋ฒˆ ํ…Œ์ŠคํŠธ ๊ณ ์ • ์žฅ์น˜๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค."๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ด ํŠน์ • ๊ฒฝ์šฐ์— ํ”ฝ์Šค์ฒ˜์— ๋ฐฐ์น˜๋œ ์†์„ฑ์€ "ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ํ•œ ๋ฒˆ ์ด ํ”ฝ์Šค์ฒ˜๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค."๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€์—์„œ "๋‹ฌ๋ฆฌ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ด ์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ๊ณ ์ • ์žฅ์น˜๋‹น ํ•œ ๋ฒˆ ํ…Œ์ŠคํŠธ ๊ณ ์ • ์žฅ์น˜๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค."๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ ๋ฌธ์žฅ์—์„œ ๋ง์„ ์ž˜๋ชปํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด -- "๋‹ฌ๋ฆฌ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ ~ํ”ฝ์Šค์ฒ˜~ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๋‹น ํ•œ ๋ฒˆ ์ด ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค."_ ์˜๋„ํ–ˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋ฒ”์œ„์™€ ์˜๋„๋ฅผ ์‹ฌ๊ฐํ•˜๊ฒŒ ์˜คํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์˜๋ฏธ ์ฒด๊ณ„๋Š” ์ „ํ˜€ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. " ์†์„ฑ์œผ๋กœ ํ‘œ์‹œ๋œ ๋ฒ”์œ„ ๋‚ด์—์„œ ํ…Œ์ŠคํŠธ๋‹น ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค." ๊ทธ๊ฒƒ์€ ์‹ค์ œ๋กœ ๊ทธ๋Ÿฌํ•œ ๋‚ด๋ถ€ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.โ€ ๊ณ ์ •๋ฌผ์ด๋“  ์–ด์…ˆ๋ธ”๋ฆฌ์ด๋“ . ๋‚ด ์˜๊ฒฌ์ด์ง€๋งŒ ๋‘ ๊ฐ€์ง€ ์†์„ฑ์ด ์•ฝ๊ฐ„ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ์ œ ์ƒ๊ฐ์ผ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‘ ๊ฐœ์˜ ๊ฐœ๋ณ„ ๊ตฌํ˜„

์œ ๋‹ˆ์ฝ˜๊ณผ ๋ฌด์ง€๊ฐœ์˜ gedankenworld์—์„œ ๊ตฌํ˜„์€ ์‚ฌ์šฉ์ž ๋Œ€๋ฉด ์ธก๋ฉด์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ(๋‹น์‹ ๊ณผ NUnit์˜ ์‚ฌ์šฉ์ž ์ค‘ ํ•œ ๋ช…)๋Š” ๋ชจ๋‘ ์—”์ง€๋‹ˆ์–ด์ด๋ฉฐ ์—”์ง€๋‹ˆ์–ด๋ง์€ ๋ชจ๋‘ ํƒ€ํ˜‘์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ”์œ„์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์‹ค์ œ๋กœ ๋‚ด๋ถ€์ ์ธ ๋ฒˆ๊ฑฐ๋กœ์›€๊ณผ ์œ ์ง€ ๊ด€๋ฆฌ ๋ถ€๋‹ด์œผ๋กœ ์ด์–ด์ง„๋‹ค๋ฉด ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. :)

๊ฒฐ๊ตญ ๋‚˜์—๊ฒŒ ์ด๊ฒƒ์€ ์‚ฌ์†Œํ•œ ๋ฌธ์ œ์ด๊ณ  ๋‚˜๋Š” ๊ฐ™์€ ์†์„ฑ์— ๋Œ€ํ•ด ๊ฐ•ํ•˜๊ฒŒ ๋Š๋ผ์ง€ ์•Š์œผ๋ฉฐ ์–ด๋Š ์ชฝ์ด๋“  ์ •๋ ฌ๋œ ์†์„ฑ์œผ๋กœ ์‚ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@kkm000 ์˜ˆ, "ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ํ•œ ๋ฒˆ"์„ ์˜๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ จ์˜ ์ค‘์ฒฉ ๋ฒ”์œ„๋กœ ์ƒ๊ฐํ•˜๋ฉด ์ด ๋ชจ๋“  ๊ฒƒ์ด ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ด๋œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฒฝํ—˜์— ๋”ฐ๋ฅด๋ฉด ์‚ฌ์šฉ์ž๋Š” (a) ํ•ญ์ƒ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ (b) ๋ฒ”์œ„ ์ •์˜๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ค‘์ฒฉ ํด๋ž˜์Šค์™€ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ๋‘˜ ๋‹ค NUnit์—์„œ ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ ์ค‘์ฒฉ๋œ "๋ฒ”์œ„"๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์ง€๋งŒ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ๊ทธ๋ ‡๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Timeout / DefaultTimeout์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ๊ฐ€ ์ข€ ๋” ์‹ฌ๊ฐํ•˜๋‹ค๋Š” ์ ์„ ์ธ์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํ”ฝ์Šค์ฒ˜์˜ Timeout์€ ์ „์ฒด ํ”ฝ์Šค์ฒ˜์— ํƒ€์ž„์•„์›ƒ์ด ์ ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์‰ฝ๊ฒŒ ์˜๋ฏธํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฌผ๋ก  ๊ทธ๋ ‡์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋Š” ์ „์ฒด ์–ด์…ˆ๋ธ”๋ฆฌ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ ์ด๋ฆ„์— "per test case"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋Š ์ชฝ์ด๋“  ์‰ฝ๊ฒŒ ๊ฐˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจํ˜ธ์„ฑ์ด ๋œํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์–ด์จŒ๋“  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ผํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค. :์›ƒ๋‹ค:

์ƒ๊ฐํ•ด ๋ณด์„ธ์š”. Timeout์ด TestCaseTimeout์ด๋ผ๊ณ  ํ–ˆ๋‹ค๋ฉด ๋” ์ข‹์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

[FixtureInstancePerTestCase] 1๊ฐœ๋กœ ๋งŒ์กฑํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์ •์‹ ์  ๋ถ€๋‹ด์ด ๊ฐ€์žฅ ์ ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@nunit/framework-team https://github.com/nunit/nunit/issues/2574#issuecomment -426347735์—์„œ ์•„๋ž˜๋กœ ํ›‘์–ด๋ณด๊ณ  ๋ฐฉํ–ฅ์„ ์ •ํ•˜๋„๋ก ๋„์™€์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

[FixtureInstancePerTestCase] ๋„ ๋‚ด๊ฐ€ ๊ฐ€์žฅ ์‹ซ์–ดํ•˜๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค. ๐Ÿ˜„ ํ™•์žฅ์„ฑ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด ์œ ์ผํ•œ ๋‹จ์ ์ž…๋‹ˆ๋‹ค.

[FixtureOptions] ๋ฌธ์ œ๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ์–ด์…ˆ๋ธ”๋ฆฌ์™€ ํด๋ž˜์Šค ๋ชจ๋‘์— ๋Œ€ํ•ด ๋‹จ์ผ ์†์„ฑ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ด์ „์— Timeout ๋ฐ Parallelizable์— ๋Œ€ํ•ด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚จ ์ ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ์†์„ฑ์˜ ์ด๋ฆ„์— "Fixture"๊ฐ€ ์žˆ์œผ๋ฉด ๋œ ๋ชจํ˜ธํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ enum ์˜ต์…˜์ด ๋งˆ์Œ์— ๋“ ๋‹ค๊ณ  ์ธ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋ฆ„์„ ์ ์ ˆํ•˜๊ฒŒ ์ง€์ •ํ•˜์—ฌ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ ๋งŒ ๋นผ๋ฉด์š”!

์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋Š” ์ด ๋ฌธ์ œ์— ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ??
ํ˜„์žฌ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ž˜ํ•‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
csharp [Test] public void TestExample(){ using(var tc = new MyTestContext()){ //code goes here } }
์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ๋ฅผ ์„ค์ • ์‹œ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ํ•ด์ฒด ์‹œ ํ๊ธฐํ•˜๊ณ  ์—ฌ์ „ํžˆ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์ €ํฌ ํšŒ์‚ฌ์—์„œ๋„ ์ด ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ๊ธฐ๋Šฅ(Py.Test)์„ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ค‘์ด๋ฏ€๋กœ ์ด๊ฒƒ์€ ์•ฝ๊ฐ„์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ์ œ์–ดํ•˜๊ณ  ํ•„์š”ํ•œ ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ด ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ณด์—ฌ์ฃผ์‹œ๋ฉด ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@MChiciak
์ด ๋ฌธ์ œ๊ฐ€ ๊ณง ํ•ด๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉด xUnit์œผ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. xUnit์—์„œ๋Š” ์ด๊ฒƒ์ด ๊ธฐ๋ณธ ๋™์ž‘์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. "xUnit.net์€ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค." https://xunit .github.io/docs/shared-context

@LirazShay , @MChiciak ์ €๋„ ์ด ๋ฌธ์ œ์— ์ง๋ฉด ํ–ˆ์ง€๋งŒ [ThreadStatic] ์—์„œ ์ดˆ๊ธฐํ™”๋˜๋Š” ํ…Œ์ŠคํŠธ ์ „์šฉ ํ•„๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ  ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@dfal
์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ข‹์•„ํ•  ๊ฒƒ์ด๋‹ค. ํ˜„์žฌ ๊ณต์œ  ์ƒํƒœ๋กœ ์ธํ•ด ์‰ฝ๊ฒŒ ๋ณ‘๋ ฌํ™”ํ•  ์ˆ˜ ์—†๋Š” nunit์—์„œ ์‹คํ–‰๋˜๋Š” ์ˆ˜์ฒœ ๊ฐœ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๋Š” ๊ธฐ์กด ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์ด ์ œ๊ณต๋˜๋ฉด ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๋ฅผ ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ๋ณ‘๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ๊ณ  ์‹คํ—˜์œผ๋กœ TestFixture๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋‹จ์ˆœํžˆ ๋ณ€๊ฒฝํ–ˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์€ ๋ฌด์—‡์„ ๊นจ๋œจ๋ฆด๊นŒ์š”?

  1. ์ˆœ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ํ•œ ํ…Œ์ŠคํŠธ์—์„œ ์ˆ˜ํ–‰ํ•œ ์ƒํƒœ ๋ณ€๊ฒฝ์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ (์•„๋งˆ๋„) ๋…๋ฆฝ์ ์ธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ์— ๋งค์šฐ ๋‚˜์œ ์Šต๊ด€์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๊ฒƒ์„ ํ•˜์ง€ ๋ง๋ผ๊ณ  ๊ฒฝ๊ณ ํ•ด์™”๊ณ  ๋‚˜๋Š” ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์— ์˜์กดํ•˜๋Š” ํ…Œ์ŠคํŠธ(๋ฌผ๋ก  ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜)๋ฅผ ๊นจ๋Š” ๊ฒƒ์— ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  2. ์ผํšŒ์„ฑ ์„ค์ • ๋‚ด์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์— ๋”ฐ๋ผ ๊ฐœ๋ณ„ ์กฐ๋ช…๊ธฐ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ์˜ ๋™๊ธฐ๋Š” ๊ณ ์ • ์žฅ์น˜๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ์•„์ด๋Ÿฌ๋‹ˆํ•ฉ๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ์ด๋ฏธ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์•„๋‹ˆ์ง€๋งŒ ๋ณ‘๋ ฌํ™” ๋ถˆ๊ฐ€๋Šฅํ•œ 'OneTimeSetUp' ์ดํ›„์— ๋ณ‘๋ ฌ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์— ์ด๋ฏธ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ์ค‘์š”ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

  3. ๋ชจ๋“  ์กฐ๋ช…๊ธฐ ๋ ˆ๋ฒจ OneTimeSetUp ๋Š” ์ด์ œ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ผํšŒ์„ฑ ์„ค์ •์œผ๋กœ ์ธํ•œ ํšจ์œจ์„ฑ ํ–ฅ์ƒ์ด ์ œ๊ฑฐ๋˜๊ณ  ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์˜๋ฏธ ์ฒด๊ณ„๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ดˆ๊ธฐํ™”๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •) ์ „์—ญ ์ƒํƒœ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์šฉ๋‚ฉํ•  ์ˆ˜ ์—†๋Š” ํŒŒ์†์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์‚ฌ๊ณ  ์‹คํ—˜์ด ํ”ฝ์Šค์ณ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. NUnit 3์— ๋„์ž…๋œ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ด ์•„๋‹Œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. NUnit 4 ๋˜๋Š” ๋‹ค๋ฅธ ์ƒˆ ํ”„๋ ˆ์ž„์›Œํฌ(์˜ˆ: TestCentric)์˜ ๊ฒฝ์šฐ ์ƒˆ ๋™์ž‘์ด ์‰ฝ๊ฒŒ ๊ธฐ๋ณธ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ์ €๋Š” MSTest์˜ TestClass ๋ฐ TestMethod ๋ฅผ ๊ฐ๊ฐ TestFixture ๋ฐ Test ๊ต์ฒดํ–ˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์„œ NUnit๊ณผ MSTest๊ฐ€ ๋‹ค๋ฅธ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. MSTest๋Š” ๊ฐ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์ด ๊ธ€์„ ์ฝ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์€ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. NUnit์€ TestFixture ์ธ์Šคํ„ด์Šค๋ฅผ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด TestFixture(lifeCycle = OneTestPerInstance)] ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์“ธ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

_edit:_ ์‚ฌ์‹ค, Setup ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ํฌํŒ…ํ•œ ํ›„ ์‹ค์ œ๋กœ ๊ธฐ์กด ์ฝ”๋“œ ์ดˆ๊ธฐํ™” ํ”„๋กœ๊ทธ๋žจ/์ด์ „/๋ถ„ํ•ด ์ฝ”๋“œ๊ฐ€ MSTest์—์„œ ์ƒ๋‹นํžˆ ๊ณ ์ดˆ๋ฅผ ๊ฒช์—ˆ๊ณ  ์ด์ œ ๊ฐ„๋‹จํ•œ ์†์„ฑ ์ดˆ๊ธฐํ™” ์ƒ์„ฑ์ž์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋ฉ‹์ง€๊ณ  ์™„์„ฑ๋„๊ฐ€ ๋†’์•„์„œ ๋ฒˆ์—ญ์„ ํ•ด์„œ ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ํ˜ธํ™˜์„ฑ์˜ ๋ฌธ์ œ๋กœ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@์ฐฐ๋ฆฌํ’€

์ˆœ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ํ•œ ํ…Œ์ŠคํŠธ์—์„œ ์ˆ˜ํ–‰ํ•œ ์ƒํƒœ ๋ณ€๊ฒฝ์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

์•„, ๋„ค, ์ด ํ…Œ์ŠคํŠธ๋ฅผ ๊นจ๊ณ , ๊นจ์ฃผ์„ธ์š”, ์ œ๋ฐœ!!! ๐Ÿคฃ ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ตœ์•…์˜ ๋‚จ์šฉ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ์กฐ๋ช…๊ธฐ ๋ ˆ๋ฒจ OneTimeSetUp

์–ด, ๋‚˜๋Š” ์ด๊ฒƒ์ด ํ”„๋กœ์„ธ์Šค ๋‹น ํ•œ ๋ฒˆ ์‹คํ–‰๋œ๋‹ค๊ณ  ํ•ญ์ƒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•ญ์ƒ ์™œ ์ •์ ์ด์ง€ ์•Š์€์ง€ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์˜ˆ, ์„ฑ๋Šฅ๋„ ๋งค์šฐ ์œ ํšจํ•œ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์ด ๋…ผ์˜๋œ ์ง€ 2๋…„์ด ๋„˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ์พŒํ•˜๊ฒŒ ๋“ค๋ฆด ์ƒ๊ฐ์€ ์—†์ง€๋งŒ ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•  ๊ตฌ์ฒด์ ์ด๊ณ  ํ˜„์‹ค์ ์ธ ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ ํŒ€์ด ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๊ณ„ํšํ•ด์•ผ ํ•˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด ์•ž์œผ๋กœ ๋ช‡ ๋‹ฌ ์•ˆ์— ํ•ด๊ฒฐ๋  ๊ฒƒ์ธ์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ์šฐ๋ฆฌ์—๊ฒŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฌธ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋ฉฐ ํ˜„์žฌ ๊ธฐ๋Šฅ์— ์˜์กดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์™„์ „ํžˆ ์†์ƒ์‹œํ‚ค์ง€ ์•Š๋„๋ก ์ „์ฒด ์˜ํ–ฅ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ "ํ•ด๊ฒฐ"ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค๋ฅผ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ข‹์€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์„ค์ • ๋ฉ”์„œ๋“œ์—์„œ ์„ค์ •ํ•œ ๋‹ค์Œ ๋งŽ์€ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํด๋ž˜์Šค๋Š” ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค . ๊ทธ๊ฒƒ์€ NUnit์˜ ๊ฒฐํ•จ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์‹ฑ๊ธ€ํ†ค์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ํ…Œ์ŠคํŠธ์˜ ์ผ๋ถ€๋กœ ์ƒ์„ฑํ•œ ์ปจํ…์ŠคํŠธ ์ •๋ณด๋ฅผ ๋ณด์œ ํ•˜๋Š” TestFixture ๋‚ด๋ถ€์— ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์‹ฑ๊ธ€ํ†ค TestFixture๊ฐ€ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•˜๊ณ ...๋”ฐ๋ผ์„œ...๋ฌธ์ œ๋ฅผ "ํ•ด๊ฒฐ"ํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ "๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜"ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ๋ณด๋‚ด๋Š” ๊ฒƒ๋ณด๋‹ค ์‹ฑ๊ธ€ํ†ค TestFixtures๋ฅผ ์Šค๋ ˆ๋“œ์„ธ์ดํ”„ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ๊ทธ ์‹œ๊ฐ„์„ ํ• ์• ํ–ˆ๋‹ค๊ณ  ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.... ํ›จ์”ฌ ๋” ๋น ๋ฅธ ์—ฐ์Šต์ž„์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, NUnit TestFixture๊ฐ€ ์‹ฑ๊ธ€ํ†ค์ด๋ผ๋Š” ์‚ฌ์‹ค์„ ์ฒ˜์Œ ์•Œ๊ฒŒ ๋˜์—ˆ์„ ๋•Œ 500๊ฐœ ์ด์ƒ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ 100๊ฐœ ์ด์ƒ์˜ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜๋ฅผ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์•ฝ 4์ฃผ(์†”์งํžˆ Rhino -> Moq๊ฐ€ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„์„ ์†Œ์š”ํ–ˆ์Šต๋‹ˆ๋‹ค!)

์›์น™์ ์œผ๋กœ๋Š” 100% ์˜ณ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ~7000๊ฐœ ์ด์ƒ์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋กœ ๊ตฌ์„ฑ๋œ ๊ธฐ์กด ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋„๋ก ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์—„์ฒญ๋‚œ ํˆฌ์ž์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ํˆฌ์ž์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ(์ž๋™ํ™”ํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Œ) ์ด ๊ธฐ๋Šฅ ์š”์ฒญ์„ ์›์น™์ ์œผ๋กœ ํ๊ธฐํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. IMO

์ด ๊ธฐ๋Šฅ์„ ๋ณด์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค๊ณ  ์˜นํ˜ธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ nunit์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ ํฐ ๋ณ€ํ™”๋Š” ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ(๋งค์šฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Œ) ๋˜๋Š” ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฒ„์ „(์ž‘์€ ์ž‘์—…์ด ์•„๋‹˜)์„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” nunit์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋„๋ก ์Šค๋ ˆ๋“œ์„ธ์ดํ”„๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šด ํ˜•ํƒœ์˜ ์ž‘์—…์ด๋ผ๊ณ  ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๊ธฐ์—ฌํ•œ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋ฏ€๋กœ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ปจํ…์ŠคํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋งค์šฐ ์ˆœ์ง„ํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์„ ์„ ํƒ์  ์Šค์œ„์น˜๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์„๊นŒ์š”? ์ด๊ฒƒ์ด ์•„๋ฌด๊ฒƒ๋„ ๊นจ์ง€์ง€ ์•Š๋„๋ก?

์ด ์ „์ฒด ๋ฌธ์ œ๋Š” ์„ ํƒ์  ์Šค์œ„์น˜๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ „์ ์œผ๋กœ ์ž์› ๋ด‰์‚ฌ์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ด ์ˆ˜๋ฝ๋˜๋ฉด ํŒ€์ด๋‚˜ ์™ธ๋ถ€์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ์—๊ฒŒ๋‚˜ ์ž‘์—…์„ ํ• ๋‹นํ•˜๋Š” "๋ณด์Šค"๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ทธ๊ฒƒ์„ ์™„๋ฃŒํ•˜๋Š” ๋ฐ ์ „๋…ํ•  ์‹œ๊ฐ„์ด ์—†๋‹ค๋ฉด ์•„๋ฌด๋„ ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์€ ๊ฒƒ์€ ์ข‹์€ ์ผ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ๋Šฅ๋ ฅ๊ณผ ๊ด€์‹ฌ์ด ์žˆ๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PR์€ ํ•ญ์ƒ ํ™˜์˜ํ•˜์ง€๋งŒ NUnit์˜ ๋‹ค๋ฅธ ๋งŽ์€ ๊ฒƒ๋“ค์„ ๊นจ๋œจ๋ฆด ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ์ด๊ฒƒ์€ ์•„๋งˆ๋„ ์ฒ˜์Œ ๊ธฐ์—ฌ๊ฐ€ ์•„๋‹ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ๋‚ด ์˜๊ฒฌ.

๋‚˜๋Š” ๋” ์ด์ƒ ๊ณผ๊ฑฐ์ฒ˜๋Ÿผ ์ ๊ทน์ ์œผ๋กœ ๊ธฐ์—ฌํ•˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‚ด ์˜๊ฒฌ์€ ๊ทธ๊ฒƒ์„ ์„ ํƒํ•˜๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•œ ์กฐ์–ธ์œผ๋กœ ์ฃผ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ž ์‹œ ๋™์•ˆ ์ฃผ๋ณ€์— ์žˆ์—ˆ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•˜๋ฉฐ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@BlythMeister ์ œ ์ƒ๊ฐ์—๋Š” ์Šค์œ„์น˜๊ฐ€ ๊ทธ๊ฒƒ์„ ์กฐ๊ธˆ ์ง€๋‚˜์น˜๊ฒŒ ๋‹จ์ˆœํ™”ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์•„์‹œ๋‹ค์‹œํ”ผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์Šค์œ„์น˜์ง€๋งŒ ์ „๊ตฌ๋งŒ ์ผœ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ผ๋””์˜ค๋ฅผ AM์—์„œ FM์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ํšŒ๋กœ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ ๊ด€๋ จ๋œ ๊ฒƒ์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰์—์„œ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์ˆ˜๋ช… ์ฃผ๊ธฐ์ด๋ฏ€๋กœ ์ƒ๋‹นํ•œ ์–‘์˜ ์ฝ”๋“œ๋ฅผ ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์€ ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์œ„ํ—˜์€ ์ƒˆ๋กœ์šด "ํšŒ๋กœ"๊ฐ€ ์–ด๋–ค ์‹์œผ๋กœ๋“  ๊ธฐ์กด ํšŒ๋กœ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. "์Šค์œ„์น˜"๊ฐ€ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์€ ์ด์œ ์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋ชจํ˜ธํ–ˆ์Šต๋‹ˆ๋‹ค!

@BlythMeister ์ €๋Š” ์‹ค์ œ๋กœ Selenium ํ…Œ์ŠคํŠธ ์žฅ์น˜๋ฅผ ๊ตฌ๋™ํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์ค‘์— ์ƒํƒœ๋ฅผ ์ถ”์ ํ•œ ๋‹ค์Œ ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ํ๊ธฐํ•˜๊ธฐ ์œ„ํ•ด ์ผํšŒ์šฉ ๊ฐœ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์ •ํ™•ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ ‘๊ทผ ๋ฐฉ์‹์˜ ํ•œ ๊ฐ€์ง€ ์ฃผ์š” ๋ฌธ์ œ๋Š” ๊ตญ๊ฐ€๊ฐ€ ํ•ด์ฒด๋ฅผ ์ง€์†ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ ์ƒํƒœ๊ฐ€ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ์ž์ฒด ๋‚ด์—์„œ ํ™•์ธ๋˜์ง€ ์•Š๊ณ  ๋ถ„ํ•ด ์ค‘์—๋งŒ ํ‰๊ฐ€๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ(์Šคํฌ๋ฆฐ์ƒท, ๋กœ๊ทธ ๋˜๋Š” ๊ธฐํƒ€ ์ƒํƒœ ์กฐ๊ฐ ์บก์ฒ˜)์— ๋Œ€ํ•ด ์กฐ๊ฑด๋ถ€๋กœ ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒํƒœ ๊ฐœ์ฒด๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ๋ถ„ํ•ดํ•˜๋Š” ๋™์•ˆ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์€ TearDown์ด ์„ค๊ณ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋Š” ์ ์„ ์—ผ๋‘์— ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ๋™๊ธฐ๋ฅผ ์ดํ•ดํ•˜์ง€๋งŒ ๋ณธ์งˆ์ ์œผ๋กœ TearDown์ด ํ…Œ์ŠคํŠธ์˜ ์ผ๋ถ€์ด๊ณ  ๋๋‚  ๋•Œ๊นŒ์ง€ ๋๋‚œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋Š” ์‚ฌ์‹ค๋กœ ๊ท€๊ฒฐ๋˜๋Š” ๊นŒ๋‹ค๋กœ์šด ์ฝ”๋„ˆ ์ผ€์ด์Šค๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

NUnit 3๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ์—”์ง„ ํ™•์žฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋ ˆ์ž„์›Œํฌ ์™ธ๋ถ€์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋” ๋งŽ์€ ์‚ฌ์šฉ์ž๋ฅผ ๋ณด๊ธฐ๋ฅผ ํฌ๋งํ–ˆ์ง€๋งŒ ํ…Œ์ŠคํŠธ ์ž์ฒด ๋‚ด์—์„œ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์ด ๋” ์นœ์ˆ™ํ•˜๊ณ  ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@์ฐฐ๋ฆฌํ’€

  1. ๋ชจ๋“  ์กฐ๋ช…๊ธฐ ๋ ˆ๋ฒจ OneTimeSetUp ๋Š” ์ด์ œ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ผํšŒ์„ฑ ์„ค์ •์œผ๋กœ ์ธํ•œ ํšจ์œจ์„ฑ ํ–ฅ์ƒ์ด ์ œ๊ฑฐ๋˜๊ณ  ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์˜๋ฏธ ์ฒด๊ณ„๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ดˆ๊ธฐํ™”๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •) ์ „์—ญ ์ƒํƒœ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์šฉ๋‚ฉํ•  ์ˆ˜ ์—†๋Š” ํŒŒ์†์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋‹น ์ธ์Šคํ„ด์Šค ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†๊ณ  ์—ฌ์ „ํžˆ OneTimeSetUp์„ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ(๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๋„๋ก ์œ ์ง€)?

์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ๊ธฐ์กด OneTimeSetUp์ด ์†์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ๋ชจ๋“  ์Šค์œ„์น˜ ๊ธฐ๋ฐ˜ ์†”๋ฃจ์…˜์˜ ๋ฌธ์ œ๋กœ ๋ด…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์— ๋Œ€ํ•œ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ๋Œ€์•ˆ์„ ์ •์˜ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ์ƒ๋‹นํžˆ ๋งค๋ ฅ์ ์ž…๋‹ˆ๋‹ค.

์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ๊ธฐ์กด OneTimeSetUp์ด ์†์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

"ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋‹น ์ธ์Šคํ„ด์Šค" ๊ธฐ๋Šฅ์ด ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ์ •์  OneTimeSetUp ๋ฐ OneTimeTearDown ๋ฉ”์„œ๋“œ๋งŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ์ดˆ๊ธฐํ™”๋œ ๋ฉค๋ฒ„๊ฐ€ ์ •์ ์œผ๋กœ ๊ฐ•์ œ๋˜๋ฏ€๋กœ ์กฐ๋ช…๊ธฐ ์ธ์Šคํ„ด์Šค ๊ฐ„์— ๋ถ„๋ช…ํžˆ ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค.

์ด Github ๋ฌธ์ œ์˜ ์ฃผ์š” ๋™๊ธฐ๋Š” ๋ณ‘๋ ฌํ™”์ด์ง€๋งŒ _์ตœ์†Œํ•œ์˜ ๋†€๋ผ์›€์˜ ์›์น™_๊ณผ _์„œ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ํ…Œ์ŠคํŠธ๋กœ ์ธํ•œ ์˜ค๋ฅ˜ ๋ฐฉ์ง€_๋„ ๋™๊ธฐ๋กœ ์ œ์‹œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. (์ด๋ฏธ ๋‹ค๋ฅธ ๋ถ„์ด ์–ธ๊ธ‰ํ•˜์…จ๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.)

์ด ๋‹ค์†Œ ์˜ค๋ž˜๋œ ์Šค๋ ˆ๋“œ์—์„œ ์ถฉ๋ถ„ํžˆ ๋‹ค์‹œ ์ฝ์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ๋Œ€๋น„ํ•˜์—ฌ ๋‚ด ์˜๊ฒฌ์€ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ œ์•ˆ๋œ ํŠน์ • ๊ตฌํ˜„์— ๋Œ€ํ•ด ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” TestFixture๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ๊ณ ์ • ์žฅ์น˜๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ๊ธฐ์„œ ๋‚ด๊ฐ€ ์ตœ์†Œ์˜ ๋†€๋ผ์›€์˜ ๊ต์žฅ์„ ์ž˜ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ƒˆ ๊ณ ์ • ์žฅ์น˜๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ๊ธฐ์กด ์กฐ๋ช…๊ธฐ๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹ํ”Œ๋ž˜๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ํ˜„์žฌ ๊ตฌํ˜„์—์„œ ํ•ด๋‹น ํ”Œ๋ž˜๊ทธ์—์„œ ๋ถ„๊ธฐํ•ด์•ผ ํ•˜๋Š” 5๊ฐœ ๋˜๋Š” 6๊ฐœ์˜ ๋‹ค๋ฅธ ์œ„์น˜๋ฅผ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๊ณ  ๋‘ ์กฐ๋ช…๊ธฐ ์œ ํ˜•์ด ํŠน์ • ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ๊ด€์  ๋ฐ–์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@fschmied BTW, ์šฐ๋ฆฌ๊ฐ€ ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ(๋˜๋Š” NUnit 4)๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ๋‹ค๋ฉด ๋‚˜๋Š” ๋‹ค๋ฅด๊ฒŒ ์ฃผ์žฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค... NUnit 2์™€ 3์—์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ์„œ๋กœ ๊ฐ„์„ญํ•˜๋Š” ๊ฒƒ์„ ํ›จ์”ฌ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค์—ˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ , NUnit 3์—์„œ ๋ณ€๊ฒฝํ•˜๋Š” ํ•œ ํ˜ธํ™˜์„ฑ ๊ทœ์น™์„ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” TestFixture๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ๊ณ ์ • ์žฅ์น˜๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.
[...]
๋‚˜๋Š” ์—ฌ๊ธฐ์„œ ๋‚ด๊ฐ€ ์ตœ์†Œ์˜ ๋†€๋ผ์›€์˜ ๊ต์žฅ์„ ์ž˜ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ƒˆ ๊ณ ์ • ์žฅ์น˜๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋‹น์‹  ๋ง์ด ๋งž์•„์š”. ๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” ์›๋ž˜ ์ข…๋ฅ˜์˜ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์˜ ๊ฒฝ์šฐ ๋™์ž‘์ด ์—ฌ์ „ํžˆ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋†€๋ผ์šธ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (2์ฃผ ์ „์— ๋™๋ฃŒ๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ๋†€๋ž์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” 2013๋…„๋ถ€ํ„ฐ NUnit์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋ดค์Šต๋‹ˆ๋‹ค.)

๊ทธ๋Ÿฌ๋‚˜ ๋ฌผ๋ก  ํ•˜์œ„ ํ˜ธํ™˜์„ฑ, ๊ตฌํ˜„ ๋ณต์žก์„ฑ ๋ฐ ์›์ฃ„๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋Š” ๋ฐ”๋žŒ ์‚ฌ์ด์˜ ์ ˆ์ถฉ์ ์ž…๋‹ˆ๋‹ค[1].

OneTimeSetUp ๋ฌธ์ œ๋กœ ๋Œ์•„๊ฐ€์„œ : ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜ ํด๋ž˜์Šค๊ฐ€ ํ…Œ์ŠคํŠธ๋ณ„๋กœ ์ธ์Šคํ„ด์Šคํ™”๋˜๋”๋ผ๋„ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜๋‹น OneTimeSetUp ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์—ฌ์ „ํžˆ ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. OneTimeSetUp ๊ฐ€ ์ธ์Šคํ„ด์Šค ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ํ˜ผ๋ž€์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด OneTimeSetUp (๋ฐ OneTimeTearDown )๋ฅผ ํ…Œ์ŠคํŠธ๋‹น ์ธ์Šคํ„ด์Šค ๊ธฐ๋Šฅ๊ณผ ํ•จ๊ป˜ ์ •์ ์œผ๋กœ ์ ์šฉํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. (์Šค์œ„์น˜๋กœ ๊ตฌํ˜„ํ•˜๋“  ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜๋กœ ๊ตฌํ˜„ํ•˜๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.)


[1] ์ œ์ž„์Šค ๋‰ด์ปคํฌ ๋Š” ์ด๋ ‡๊ฒŒ ์ผ๋‹ค .

NUnit V2.0์„ ์ž‘์„ฑํ•  ๋•Œ ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ํฌํ•จ๋œ ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜ ํด๋ž˜์Šค์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” "์šฐ๋ฆฌ"๋ผ๊ณ  ๋งํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๋‚ด ์ž˜๋ชป์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ JUnit์˜ ์ถ”๋ก ์„ ์ž˜ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Š” ๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์”๋‹ˆ๋‹ค.

[...] ์ง€๊ธˆ NUnit์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋ถˆํ‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค [...]

:)

์˜ˆ, Jim๊ณผ ์ €๋Š” ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ˆ˜๋…„๊ฐ„ ๋…ผ์Ÿ์„ ๋ฒŒ์˜€์Šต๋‹ˆ๋‹ค. :smile: ์šฐ๋ฆฌ๊ฐ€ ๋™์˜ํ•˜๋Š” ํ•œ ๊ฐ€์ง€๋Š” ๋งˆ์ง€๋ง‰ ๋ฌธ์žฅ์ž…๋‹ˆ๋‹ค. Jim์€ ์„ ํ˜ธํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ™์€ ์ผ์„ ํ•˜๊ณ  ์žˆ๊ณ  SetUp/TearDown์€ ๋‚ด๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๊ฒƒ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

๊ฝค ๋งŽ์€ ๊ฒฝํ—˜์„ ๊ฐ€์ง„ NUnit ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ชจ๋ฅด๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์— ๊ณ„์† ๋†€๋ž์Šต๋‹ˆ๋‹ค. NUnit์ด ์ฒ˜์Œ ๋‚˜์™”์„ ๋•Œ JUnit๊ณผ ํ™•์—ฐํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋„๋ฆฌ ์•Œ๋ ค์กŒ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด์ œ ๊ทธ๊ฒƒ์€ ๋ชจ๋‘ ์žŠํ˜€์ง€๊ณ  ์ƒˆ๋กœ์šด ์‚ฌ๋žŒ๋“ค์€ NUnit์ด ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ธฐ๋Œ€๋ฅผ ๊ฐ€์ง€๊ณ  NUnit์—์˜ต๋‹ˆ๋‹ค. ์ƒ๊ฐํ•ด ๋ณผ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ .. ์ด๊ฒƒ์€ ์žก๊ธฐ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์•„์ง ์„ค๊ณ„ ๋‹จ๊ณ„์— ์žˆ์Šต๋‹ˆ๊นŒ?

์ง€๊ธˆ .NET์—์„œ๋Š” TestContext๊ฐ€ ์—†๋Š” XUnit ๋˜๋Š” ์ƒ์šฉ๊ตฌ ๋ณ‘๋ ฌ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๋Š” NUnit์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ์ด ์ˆ˜๋ฝ๋˜๊ณ  ์ผ๋ฐ˜ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ํ• ๋‹น๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์ด์ •ํ‘œ์— ๋‚˜์—ด๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž‘์—…ํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋ฏธํ„ฐ๋‚˜ ๊ธฐ์—ฌ์ž๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋””์ž์ธ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋””์ž์ธ ๋ ˆ์ด๋ธ”์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•, ํŠนํžˆ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์„ค๋ช…ํ•˜๋Š” ์˜๊ฒฌ์„ ๊ฒŒ์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž. ์ฝ”๋”ฉ์œผ๋กœ ์‹œ์ž‘ํ–ˆ๋‹ค๋ฉด ์–ด์จŒ๋“  ๋””์ž์ธ ํ† ๋ก ์œผ๋กœ ๋๋‚  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋จผ์ € ๋๋‚ด๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

์ž‘์—…์„ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋ฌผ๋ก , ๋‚˜๋Š” ๋ง‰ ์ผ์„ ์‹œ์ž‘ํ–ˆ๋‹ค
https://github.com/avilv/nunit/tree/instance-per-test

์ €๋Š” ์ด ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ํ•œ ์›๋ž˜์˜ ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ๊ณ ์ˆ˜ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ง€๊ธˆ๊นŒ์ง€ InstancePerTestCase ํŠน์„ฑ์„ ๋„์ž…ํ–ˆ์œผ๋ฉฐ ์ด๋ฅผ ์–ด์…ˆ๋ธ”๋ฆฌ ๋ฐ ํด๋ž˜์Šค ์ˆ˜์ค€์—์„œ ์ง€์›ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์—ฌ๊ธฐ ๊ธฐ์ง€์—์„œ ๋ฒ—์–ด๋‚˜๋ฉด ์•Œ๋ ค์ค˜

๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹์— ๋Œ€ํ•œ ์ผ๋ถ€ ๊ตฌํ˜„ ์„ธ๋ถ€ ์ •๋ณด์— ๋Œ€ํ•œ ์˜๊ฒฌ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋””์ž์ธ์— ๊ด€ํ•ด์„œ๋Š” IApplyToContext ์—์„œ ํŒŒ์ƒ๋œ ์†์„ฑ์ด ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” InstancePerTestCase๋ณด๋‹ค ๋” ์ผ๋ฐ˜์ ์ธ ๊ฒƒ์„ ์„ ํ˜ธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

C# [FixtureLifeCycle(LifeCycle.InstancePerTestCase]

๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์–ด์…ˆ๋ธ”๋ฆฌ ๋ ˆ๋ฒจ์—์„œ ์„ค์ •ํ•˜๊ณ  ๊ฐœ๋ณ„ ์กฐ๋ช…๊ธฐ์—์„œ ์žฌ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CharliePoole ๋‹น์‹ ์€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค. ํ”ผ๋“œ๋ฐฑ๊ณผ ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋ฌผ๊ฑด์ด ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์ง€๋Š”์ง€ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค / ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ๋“ฑ๋“ฑ ์ฒœ์ฒœํžˆ ๊ทธ๋Ÿฌ๋‚˜ ํ™•์‹คํ•˜๊ฒŒ

์—ฌ๊ธฐ LifeCycle ์—ด๊ฑฐํ˜•์— ๋Œ€ํ•œ ์ œ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค(๋˜ํ•œ ๊ท€ํ•˜์˜ ์ œ์•ˆ์œผ๋กœ ์ œ ๋ธŒ๋žœ์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค)

    /// <summary>
    /// Specifies the lifecycle for a fixture.
    /// </summary>
    public enum LifeCycle
    {
        /// <summary>
        /// A single instance is created and for all test cases.
        /// </summary>
        SingleInstance,

        /// <summary>
        /// A new instance is created for each test case for fixtures that are marked with <see cref="ParallelizableAttribute"/>.
        /// </summary>
        InstancePerTestCaseForParallelFixtures,

        /// <summary>
        /// A new instance is created for each test case.
        /// </summary>
        InstancePerTestCase
    }

@jnm2 ์ด ์ ‘๊ทผ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐ InstancePerTestCaseForParallelFixtures ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„ ๋ถˆํ™•์‹คํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ดˆ๊ธฐ ๊ตฌํ˜„์— ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Š˜ ๊ทธ๋ ‡๋“ฏ์ด, ์ผ๋‹จ ๊ตฌํ˜„๋˜๋ฉด ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ๊ณ ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์„ __do__ ๋ฐ›์•„๋“ค์ธ๋‹ค๋ฉด ์†์„ฑ ๊ธฐ๋ฐ˜์ด ์•„๋‹ˆ๋ผ ์ปจํ…์ŠคํŠธ ๊ธฐ๋ฐ˜์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ `InstancePerTestCaseWhenCasesAreParallel'๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ์„ค๋น„๋Š” ํŠนํžˆ ์ด ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ๊ทธ๊ฒƒ์ด ์–ด๋–ค ์‹์œผ๋กœ๋“  ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์™€ ๊ฒฐํ•ฉ๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋Š” ์ด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ ์ด์œ ์˜€์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์ด ์œ ์šฉํ•˜๋‹ค๋Š” ๋ฐ ๋™์˜ํ•˜๋ฉด ์ œ ์ƒ๊ฐ์—๋Š” ์ฝ”๋“œ์— ๋ฐ˜์˜๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

๋™์˜ํ•ฉ๋‹ˆ๋‹ค. NUnit์˜ ํ˜„์žฌ ๊ธฐ๋ณธ ๋ชจ๋ธ์ด ๋‹น์‹ ์„ ๋ฌผ์–ด๋œฏ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘๋ ฌ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์œ ์Šค ์ผ€์ด์Šค๋ฅผ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜์Œ๋ถ€ํ„ฐ ์ด๋žฌ์–ด

SingleInsance/InstancePerTestCase์— ๋‚จ๊ฒจ๋‘์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ์€ ์—ฌ๊ธฐ์—์„œ IDisposable ํŒจํ„ด์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด SetUp/TearDown์ด ๊ฑฐ์˜ ์ค‘๋ณต๋˜์ง€๋งŒ XUnit ์Šคํƒ€์ผ๋กœ ํ›จ์”ฌ ๋” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋Š๊ปด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด๋ฏธ IDisposable์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์„ค๋น„๋ฅผ ์ฒ˜๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์† ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ข‹์•„, ํ•  ๊ฒƒ์ด๋‹ค.

์•„๋งˆ๋„ ์˜ค๋Š˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•Œ๋ฌธ์— InstancePerTestCase๊ฐ€ ์ผœ์ ธ ์žˆ์„ ๋•Œ ๋™์ผํ•œ ์ž‘์—…์ด ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฝค ๋งŽ์€ ์ผ€์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์ˆ˜์ •ํ•ด ์ฃผ์„ธ์š”.

DisposeFixtureCommand๋Š” Dispose ํ˜ธ์ถœ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

IMO์˜ ์ฃผ์š” ๋ฌธ์ œ๋Š” ํ…Œ์ŠคํŠธ ํ”ฝ์Šค์ฒ˜์— ๋Œ€ํ•œ ์ „์ฒด ๋ช…๋ น ์ŠคํŠธ๋ฆผ์ด __๊ฐ ํ…Œ์ŠคํŠธ__์— ๋Œ€ํ•ด ํ˜ธ์ถœ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ๋ณธ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๋ช…๋ น ์ŠคํŠธ๋ฆผ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ƒ์„ฑํ•˜์ง€๋งŒ ํ•ต์‹ฌ ์งˆ๋ฌธ์€ ๊ฐ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ํ˜ธ์ถœ๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (ํ”ฝ์Šค์ฒ˜์˜ ๋ช…๋ น ๊ตฌ์กฐ๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ๊ตฌ์กฐ์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.) ๋‚˜๋Š” ๋ณตํ•ฉ ์ž‘์—… ํ•ญ๋ชฉ์ด ์ปจํ…์ŠคํŠธ์— ๋ฏผ๊ฐํ•ด์•ผ ํ•˜๊ณ  ๋ช…๋ น์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ(๋‹น์‹ ์ด ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ) ๊ธฐํšŒ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. __every__ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋Œ€ํ•ด ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด. (๋‚˜๋Š” ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์ค‘์ด๋ฏ€๋กœ ํ‹€๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

@CharliePoole ์€ ๋‹น์‹ ์ด ๋งž๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•์„ ์ •ํ™•ํžˆ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ๊ทธ๋ž˜ํ”„๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
image

ํ˜„์žฌ ๋‚˜๋Š” RunChildren ๋ฃจํ”„์—์„œ ํ…Œ์ŠคํŠธ ๊ฐœ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ๋†“์นœ ๋‹ค๋ฅธ ๋ž˜ํผ๊ฐ€ ์žˆ๋Š”์ง€/๋ˆ„๊ตฐ๊ฐ€ ์ƒˆ ๋ž˜ํผ๊ฐ€ ํ•„์š”ํ•œ์ง€ ์—ฌ๋ถ€๋Š” ๋งํ•  ๊ฒƒ๋„ ์—†์ด Retry/Repeat ๋ช…๋ น์—๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
TestMethodCommand์— ํ›จ์”ฌ ๋” ๊ฐ€๊นŒ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ตœ์‹  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/avilv/nunit/tree/instance-per-test-2

์ œ๊ฑฐ๋œ InstancePerTestCaseWhenCasesAreParallel
CompositeWorkItem MakeOneTimeSetUpCommand ๊ทธ๊ฒƒ์„ SimpleWorkItem MakeTestCommand ๋‚ด๋ถ€์— ๊ตฌ์ถ• / ํ๊ธฐ ์กฐ๋ช…๊ธฐ ์ถ”๊ฐ€, ์ƒ๋žต์„ ํ†ตํ•ด ๊ตฌํ˜„ FixtureLifeCycle

์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์œผ๋ฉฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๊ตฌ์ถ•๋˜๋Š” ๋ฐฉ์‹์— ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‹ค์Œ ๋ฒ„์ „ ์ด์ „์— ๊ฒ€ํ† ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฌผ๋ก  ๊ฐœ์„ /๋ณ€๊ฒฝ์„ ์œ„ํ•ด ์—ฌ์ „ํžˆ ๋ฉ”์‹ ์ €

์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋‚˜์—๊ฒŒ ์ข‹์€ ์†Œ๋ฆฌ์ด๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค!

์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์„ ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ •๋ง ๊ฐ€๊นŒ์›Œ์ง„ ๋Š๋‚Œ

์ด ๊ธฐ๋Šฅ์— ์–ด๋–ค ์›€์ง์ž„์ด ์žˆ์—ˆ๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹ญ๋‹ˆ๊นŒ? @avilv ๊ฐ€ ๊ฝค ๊ทผ์ ‘ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋Œ€ํ•ด ์™”์œผ๋ฉฐ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค!

๋ชจ๋‘ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ด ๊ธฐ๋Šฅ์ด ์ง€๊ธˆ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

@CharliePoole @avilv ์ตœ์‹  ๋ฒ„์ „์„ ๊ฒ€ํ† ํ•ด

@janissimson ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ €๋Š” ๋” ์ด์ƒ ์ด ํ”„๋กœ์ ํŠธ์— ์ฐธ์—ฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ œ ๋ฆฌ๋ทฐ์—์„œ ์ง„ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @nunit-framework-team ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด๊ฒƒ์„ ๊ฒ€ํ†  ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?

#3427์„ ๋ณ‘ํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰ํ•œ ๋ชจ๋“  ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. @rprouse ๋ฆด๋ฆฌ์Šค์—์„œ ์ด๋ฅผ ์–ธ์ œ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ? ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ƒˆ๋กœ์šด ์†์„ฑ๊ณผ ์ด๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์•ž์œผ๋กœ ๋ช‡ ์ฃผ ์•ˆ์— ์ถœ์‹œํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. NET 5๋Š” ์ตœ์ข… ๋ฒ„์ „์ด๋ฉฐ ๋ฆด๋ฆฌ์Šค ์ „์— ์•ฝ๊ฐ„์˜ ์ตœ์ข… ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์—†์„์ง€ ์˜๋ฌธ์ด์ง€๋งŒ ๋„ˆ๋ฌด ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ๋‚ซ์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

@rprouse ์–ธ์ œ ์ƒˆ ๋ฒ„์ „์„ ์ถœ์‹œํ•  ์˜ˆ์ •์ด์‹ ๊ฐ€์š”? ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@janissimsons ๊ณง. ์šฐ๋ฆฌ๋Š” .NET 5.0 ๋นŒ๋“œ์™€ ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฌธ์ œ์™€ ๊ด€๋ จ๋œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๋‹ค์Œ ๋ฆด๋ฆฌ์Šคํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ ๋ณด๋“œ์—์„œ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/nunit/nunit/projects/4

์ด๊ฒƒ์€ ๋ฉ‹์ง„ ์†Œ์‹์ž…๋‹ˆ๋‹ค!

์ด๊ฒƒ์ด NUnit์—์„œ ๋‹ค์Œ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ค์Œ์„ ๋ชจ๋‘ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.

  • ํ…Œ์ŠคํŠธ๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋จ
  • ํ…Œ์ŠคํŠธ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋™์ผํ•œ ํ…Œ์ŠคํŠธ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ๋ณ€ํ˜•์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ๊ฐ€๋Šฅ

https://github.com/jawn/dotnet-parallel-parameterized-tests ์—์„œ ๊ณผ๊ฑฐ์— ๋ช‡ ๊ฐ€์ง€๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ ๋ฆด๋ฆฌ์Šค๋Š” ์—ฌ์ „ํžˆ .NET Full Framework 4.7.2 ๋˜๋Š” ์ตœ์†Œ 4.8๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๊นŒ?

์นœ์• ํ•˜๋Š”,
๋ฐ•์‚ฌ

@jawn ๋‚˜๋Š” ๋ชจ๋“  ๊ฒƒ์ด ํšจ๊ณผ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ๋ชจ๋“  ๊ฒƒ์„ ํ…Œ์ŠคํŠธํ–ˆ์ง€๋งŒ NUnit์—๋Š” ๋งŽ์€ ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ถ€ ๊ธฐ๋Šฅ ์กฐํ•ฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ผ๊ฐ„ NuGet ํŒจํ‚ค์ง€๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๊ฐ€์ ธ์™€ ํ…Œ์ŠคํŠธํ•ด ๋ณด์„ธ์š”! ์ถœ์‹œํ•˜๊ธฐ ์ „์— ๋” ๋งŽ์€ ํ…Œ์ŠคํŠธ์™€ ํ”ผ๋“œ๋ฐฑ์„ ์›ํ•ฉ๋‹ˆ๋‹ค.

@drauch ์˜ˆ, 3.13 ๋ฆด๋ฆฌ์Šค๋Š” ์—ฌ์ „ํžˆ .NET 3.5๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

@avilv ์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค !!
๊ทธ๋Ÿฐ๋ฐ ์–ด๋–ค ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ ๋ฉ‹์ง„ ํ๋ฆ„๋„๋ฅผ ๋งŒ๋“œ์…จ์Šต๋‹ˆ๊นŒ?
๊ฐ์‚ฌ ํ•ด์š”

@rprouse ์ด ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”!

@janissimsons ๋ฆด๋ฆฌ์Šค์šฉ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์งง์€ ๋ฒ„์ „์€ [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] ๋ฅผ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ [Parallelizable(ParallelScope.All)] ์™€ ํ•จ๊ป˜ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ํด๋ž˜์Šค ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฐ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ์ธ์Šคํ„ด์Šคํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜์ง€ ์•Š๊ณ  ๋ณ‘๋ ฌ ํ…Œ์ŠคํŠธ ์‹คํ–‰์—์„œ ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@LirazShay ์Šคํฌ๋ฆฐ์ƒท์˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ Visual Studio Enterprise์—์„œ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์†”๋ฃจ์…˜ ํƒ์ƒ‰๊ธฐ์—์„œ ์„ ํƒ ํ•ญ๋ชฉ์„ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์œผ๋กœ ํด๋ฆญํ•˜๊ณ  "์ฝ”๋“œ ๋งต์— ํ‘œ์‹œ"๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://docs.microsoft.com/en-us/visualstudio/modeling/map-dependencies-across-your-solutions ReSharper์—๋„ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@jnm2 ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!!!
๋‚˜๋Š” VS ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋งค์šฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋Š” ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
ํŒ ๋„ˆ๋ฌด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

์ด๊ฒƒ์ด ๋ฆด๋ฆฌ์Šค๋˜์—ˆ์œผ๋ฉฐ 3.13 ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๋ผ๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์ด ๋ฆด๋ฆฌ์Šค๋˜์—ˆ์œผ๋ฉฐ 3.13 ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๋ผ๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?

ํŠนํžˆ #3720์˜ ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆ˜์ค€ ์†์„ฑ ์ ์šฉ๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๊ด€์ฐฐ ๋ฐ ์ˆ˜์ •๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉฐ ํ˜„์žฌ 3.13.1์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

NUnit 3.13.1์ด ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๋” ์ด์ƒ ๋ฌธ์ œ๊ฐ€ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ ๊ทธ๊ฒƒ์ด ํ์‡„ ๋œ ์ด์œ ์ž…๋‹ˆ๋‹ค @andrewlaser

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰