Autofixture: NCrunch ๋ฐ AutoFixture ํ†ตํ•ฉ ๋ฌธ์ œ

์— ๋งŒ๋“  2017๋…„ 08์›” 23์ผ  ยท  15์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: AutoFixture/AutoFixture

ํ˜„์žฌ NCrunch๋Š” AutoFixture๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฌธ์„œ์— ๋ช…ํ™•ํ•˜๊ฒŒ ๋ช…์‹œ๋˜์–ด ๋ฌธ์ œ ๋ฅผ ์ผ์œผํ‚ค๊ณ  ์–ด๋–ป๊ฒŒ๋“  ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋” ๋ณต์žกํ•œ ๋ฌธ์ œ๋กœ ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

NCrunch ๊ฐœ๋ฐœ์ž๋ฅผ ์—ฌ๊ธฐ์— ์ดˆ๋Œ€ํ•˜์—ฌ ๊ทธ ๋ฌธ์ œ๋ฅผ ํ•จ๊ป˜ ๋…ผ์˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ xUnit ํ‘œ๋ฉด์œผ๋กœ ๋” ์ด๋™ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์—”ํฌ๋Ÿฐ์น˜ ๋‘˜ ๋‹ค ๊ฝค ์œ ๋ช…ํ•œ ์ œํ’ˆ์ด๋‹ˆ ์—”ํฌ๋Ÿฐ์น˜๋ž‘ ๊ฐ™์ด ์ž‘์—…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ์ง€ ๐Ÿ˜‚

question

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

@remcomulder @zvirja ์ด ํ† ๋ก (๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋จ)๊ณผ ์—ฌ๊ธฐ์—์„œ ๋ณด์—ฌ ์ฃผ์‹  ํ—Œ์‹ ์ด ์ •๋ง ๋Œ€๋‹จํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค! ๋‘ ๋ถ„์˜ ํ›Œ๋ฅญํ•œ ์ œํ’ˆ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

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

์•ˆ๋…•ํ•˜์„ธ์š” ์—”ํฌ๋Ÿฐ์น˜ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค.

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

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

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ํ…Œ์ŠคํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋ชจ๋“  ๋ฌด์ž‘์œ„ ์ƒ์„ฑ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์‹  ๊ณ ์ • ๊ฐ’(์˜ˆ: ์ž๋ฆฌ ํ‘œ์‹œ์ž ๋˜๋Š” const)์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์˜ ์‹œ๋“œ๋ฅผ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž์ฒด๋กœ ์ œํ•œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ํ…Œ์ŠคํŠธ๋Š” ํ•ญ์ƒ ์ •ํ™•ํžˆ ๋™์ผํ•˜๋ฉฐ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์™€ ๋™์ผํ•˜๊ฒŒ ์ผ๊ด€๋˜๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ ์ƒ์„ฑ์„ ์œ„ํ•ด AutoFixture๋ฅผ ์‚ฌ์šฉํ•œ ๋ชจ๋“  ์‚ฌ์šฉ์ž๋Š” ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ '๊ด€์‹ฌํ•˜์ง€ ์•Š๋Š”' ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ๊ทธ๋ ‡๊ฒŒ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ ‘๊ทผ ๋ฐฉ์‹์ด ์‚ฌ์šฉ์ž์˜ ๋ˆˆ์— ์‹ค์ œ์ ์ธ ๋‹จ์ ์ด ์—†๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. . ์ด๊ฒƒ์˜ ์ด์ ์€ NCrunch์˜ ๋ชจ๋“  ๋ฒ„์ „์—์„œ ์ฆ‰์‹œ ์ž‘๋™ํ•˜๊ณ  NCrunch ๋˜๋Š” ๋‹ค๋ฅธ ๋Ÿฌ๋„ˆ์— ๋Œ€ํ•œ ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@remcomulder ์—ฌ๊ธฐ์— ์ฐธ์—ฌํ•ด์ฃผ์…”์„œ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์กฐ๊ธˆ ์กฐ์‚ฌํ–ˆ๊ณ  ๋‚ด ๋ฐœ๊ฒฌ์„ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ชจ๋“  ๊ฒฐ๊ณผ๋Š” xUnit์—๋งŒ ์ ์šฉ

TL DR: xUnit์€ ์ด๋Ÿฌํ•œ ์ด๋ก ์„ ์ง€์›ํ•˜๊ณ  NCrunch๋Š” xUnit์—์„œ๋„ ์ด๋ฅผ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. NUnit์˜ ๊ฒฝ์šฐ - ์ด๋Š” ๊ณต๊ฐœ ์งˆ๋ฌธ์ด๋ฉฐ ์•„์ง ์กฐ์‚ฌํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.


์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์€ xUnit์— ๋Œ€ํ•ด _ํ•ฉ๋ฒ•์ ์ธ_ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. (์ž„์˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์—) ์ด๋ก ์„ ๋ฏธ๋ฆฌ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์—†์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ž์ฒด TestDataDiscoverer ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ์ด ๋ฐœ๊ฒฌ ์ž๋กœ AutoDataAttribute ๋ฅผ ์žฅ์‹ํ•ฉ๋‹ˆ๋‹ค. xUnit ์€ ์ด ์†์„ฑ์„ ์กด์ค‘ ํ•˜๋ฉฐ ๊ฒ€์ƒ‰ ์ค‘์— ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋””์ž์ธ์—์„œ ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ํ•œ ์‚ฌ๋žŒ์€ ์ฃผ์ž๊ฐ€ ์œ ์ผํ•œ ์‚ฌ๋žŒ์ด ์•„๋‹ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค, ๊ทธ๊ฒƒ์€ ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋ฉฐ R#๊ณผ VS๋Š” ๋ชจ๋‘ ๊ทธ๋Ÿฌํ•œ ์ด๋ก ์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ž๋™ ์ƒ์„ฑ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ์—๋„ ํŠน์ • ์ด๋ก ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰ ๋ฐ ์‹คํ–‰ ๋‹จ๊ณ„๋„ ํฌํ•จํ•˜๊ณ  ์˜คํ”ˆ ์†Œ์Šค์ด๋ฏ€๋กœ VS์— ์ง‘์ค‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

using Ploeh.AutoFixture.Xunit2;
using Xunit;

namespace Playground
{
    public class UnitTest
    {
        [Fact]
        public void StableTest()
        {
            Assert.True(true);
        }

        [Theory]
        [InlineData(1)]
        public void StableInlineTest(int value)
        {
            Assert.Equal(1, value);
        }

        [Theory, AutoData]
        public void VolatileTest(int value)
        {
            Assert.True(value % 2 == 0);
        }

        [Theory]
        [InlineAutoData(10)]
        [InlineAutoData(20)]
        [InlineAutoData(30)]
        public void VolatileTestWithInline(int value, int autoValue)
        {
            Assert.NotEqual(value, 40);
        }
    }
}

.NET Framework ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ”„๋กœ์ ํŠธ. VS 2017.3. ๋Œ€์ƒ ํ”„๋ ˆ์ž„์›Œํฌ: 4.5.2. ์„ค์น˜๋œ ํŒจํ‚ค์ง€:

  • xunit 2.2.0
  • xunit.runner.visualstudio 2.2.0
  • AutoFixture 3.50.6
  • AutoFixture.Xunit2 3.50.6

VS์—์„œ ๊ฒ€์ƒ‰์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฉด ๋‹ค์Œ ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
image

์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰์„ ์ง€์›ํ•˜๋Š” ์ด๋ก ( StableInlineTest )์˜ ๊ฒฝ์šฐ VS runner๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰๋  ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค( 1 ). ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰์„ ์ง€์›ํ•˜์ง€ ์•Š๊ณ  ์ž๋™ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ( VolatileTest , VolatileTestWithInline )๋ฅผ ํฌํ•จํ•˜๋Š” ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ VS๋Š” ์ด๋ก  ์‚ฌ๋ก€๋ฅผ ๋ฐœ๊ฒฌํ•˜์ง€ ์•Š๊ณ  ์ „์ฒด ์ด๋ก ๋งŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์‹คํ–‰ํ•œ ํ›„์—๋งŒ ์ด ํŠน์ • ํ˜ธ์ถœ์— ๋Œ€ํ•œ ๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
image

์ด์ œ ํŠน์ • ์ด๋ก ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ _๋ชจ๋“  ์ด๋ก  ์‚ฌ๋ก€_๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ณด์‹œ๋‹ค์‹œํ”ผ ์‹ค์ œ๋กœ ์ด๋Ÿฌํ•œ ์ด๋ก ์„ ์ง€์›ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉฐ xUnit์€ ์ด๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. NCrunch๋Š” ์ผ๋ถ€ ์ด๋ก  ์‚ฌ๋ก€๋ฅผ ๋ฏธ๋ฆฌ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด๋ก ์˜ ๊ฒฝ์šฐ ํŠน์ • ์‚ฌ๋ก€๊ฐ€ ์•„๋‹ˆ๋ผ ์ „์ฒด ์ด๋ก ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ํ…Œ์ŠคํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋ชจ๋“  ๋ฌด์ž‘์œ„ ์ƒ์„ฑ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์‹  ๊ณ ์ • ๊ฐ’(์˜ˆ: ์ž๋ฆฌ ํ‘œ์‹œ์ž ๋˜๋Š” const)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ xUnit์€ ํ‘œ์‹œ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฆฌ ํ‘œ์‹œ์ž๋กœ ๋ฐ”๊พธ๋Š” API๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์„ ์œ„ํ•ด ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค( ์—ฌ๊ธฐ ์ฐธ์กฐ). ๊ทธ๋Ÿฌ๋‚˜ Brad์˜ ๋Œ€๋‹ต์€ ๊ทธ๊ฒƒ์ด ๋น„ํ˜„์‹ค์ ์ด๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ์ด๋ฏธ ํ•˜๊ณ  ์žˆ๋Š” ๋ฐœ๊ฒฌ์„ ๋‹จ์ˆœํžˆ ๋น„ํ™œ์„ฑํ™”ํ•  ๊ฒƒ์„ ์ œ์•ˆํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์˜ ์‹œ๋”ฉ์„ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž์ฒด๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ ํ˜„์žฌ ์šฐ๋ฆฌ ์ œํ’ˆ์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋‹จ์ผ ์‹œ๋“œ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


ํšŒ์› ๋ฐ์ดํ„ฐ

์—ฌ๊ธฐ ๋ฌธ์„œ์—๋Š” ๋‹ค๋ฅธ ์ƒ˜ํ”Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค(XUnit์œผ๋กœ ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค).

public class MemberDataSample
{
    public IEnumerable<object[]> GetData()
    {
        yield return new object[]
        {
            DateTime.Now
        };
    }

    [Theory, MemberData(nameof(GetData), DisableDiscoveryEnumeration = true)]
    public void DateTheory(DateTime dt)
    {
        Assert.True(DateTime.Now - dt < TimeSpan.FromMinutes(1));
    }
}

DisableDiscoveryEnumeration ์†์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ xUnit์— ๋Œ€ํ•ด ์ ˆ๋Œ€์ ์œผ๋กœ ํ•ฉ๋ฒ•์ ์ž…๋‹ˆ๋‹ค. ์œ„์˜ ์ƒ˜ํ”Œ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ก  ์‚ฌ๋ก€๋Š” ๋ฏธ๋ฆฌ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


๊ฒฐ๋ก 

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

R#๊ณผ VS ๋ชจ๋‘ ์ด๋Ÿฌํ•œ ํ›Œ๋ฅญํ•œ ์ด๋ก ์„ ์ง€์›ํ•œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ์‹ค์ œ๋กœ ๋ชจ๋“  ๊ฒƒ์ด ์šฐ๋ฆฌ ์ œํ’ˆ์— ๋งž๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค..

NUnit์— ๊ด€ํ•ด์„œ๋Š” - ์•„์ง ์กฐ์‚ฌํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์ค‘์— ๋…ผ์˜ํ•ฉ์‹œ๋‹ค. ์•„๋งˆ๋„ ๊ทธ๋Ÿฐ API๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ฐพ์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์•ˆํ•  ๋•Œ xUnit ์ง€์›์— ๋Œ€ํ•œ ์˜๊ฒฌ์„ ๊ณต์œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?
xUnit(๋ชจ๋“  ํ…Œ์ŠคํŠธ ์žฌ์‹คํ–‰ ์ค‘์ง€) ๋ฐ ์ค‘์ง€ํ•˜์—ฌ ๋น„ํ˜ธํ™˜์„ฑ ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๐Ÿ˜‰

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

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

NCrunch์™€ VS Runner๋ฅผ ๋ชจ๋‘ ๊นจ๋œจ๋ฆด ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋Š” ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ReSharper ๋ฐ TD.NET๋„ ์†์ƒ๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์ง€๋งŒ ์„ค์น˜ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

using Ploeh.AutoFixture;
using Ploeh.AutoFixture.Xunit2;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace XUnitAutoFixture
{
    public class TestFixture
    {
        private static readonly Fixture Fixture = new Fixture();

        public static IEnumerable<object[]> SomeTestData()
        {
            yield return new object[] { Fixture.Create<string>() };
            yield return new object[] { Fixture.Create<string>() };
        }

        [Theory, MemberData(nameof(SomeTestData))]
        public void Test(object value)
        {

        }
    }
}

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

๋‚ด ํ˜„์žฌ ๊ฐ€์ •์€ ๋‹น์‹ ์ด ๊ทธ๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€?

์ง€๊ธˆ ์ด๊ฒƒ์„ ํ…Œ์ŠคํŠธํ•˜๋ฉด NCrunch๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€๋‹จํ•ด! ์‹ค์ œ๋กœ xUnit์ด NCrunch์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›๋œ๋‹ค๋Š” ์†Œ์‹์„ ๋“ฃ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค ๐ŸŽ‰ NUnit์€ ํ•ญ์ƒ ์„œํˆด๋ €๊ณ  ์—ฌ๊ธฐ์„œ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์กฐ์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ NCrunch ๋ฐ AutoFixture์˜ ๋ฌธ์ œ๋ฅผ ๊ด€์ฐฐํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ AutoFixture๊ฐ€ ํฌํ•จ๋œ xUnit ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์œผ๋ฉฐ ํ•œ ์ค„์ด๋ผ๋„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ˆ„๋ฝ๋œ ํ•ญ๋ชฉ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด AutoFixture๋ฅผ ๊ฐ์ง€ํ•  ๋•Œ ์ด๋Ÿฌํ•œ ๋™์ž‘์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด xUnit์—์„œ ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ด๋ฏ€๋กœ ํ•ด๋‹น ๋™์ž‘์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋„๋ก ์ˆ˜์ •ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?


NCrunch์™€ VS Runner๋ฅผ ๋ชจ๋‘ ๊นจ๋œจ๋ฆด ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋Š” ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
๋‚ด ํ˜„์žฌ ๊ฐ€์ •์€ ๋‹น์‹ ์ด ๊ทธ๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€?

์˜ˆ, ๊ทธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋ชจ๋“  ์ฃผ์ž๋ฅผ ๊นจ๋œจ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํฌ๋Ÿผ์˜ ์–ด๋”˜๊ฐ€์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ ๋˜์—ˆ์œผ๋ฏ€๋กœ AutoFixture ๋•Œ๋ฌธ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

public class TestFixture
{
    public static IEnumerable<object[]> SomeTestData()
    {
        yield return new object[] { DateTime.Now.Ticks };
        yield return new object[] { DateTime.Now.Ticks };
    }

    [Theory, MemberData(nameof(SomeTestData))]
    public void Test(object value)
    {

    }
}

์ด๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ๊ฒฝ์šฐ ์‚ฌ์ „ ๊ฒ€์ƒ‰์„ ์ˆ˜๋™์œผ๋กœ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค( DisableDiscoveryEnumeration ์†์„ฑ์— ์ฃผ์˜).

public class TestFixture
{
    private static readonly Fixture Fixture = new Fixture();

    public static IEnumerable<object[]> SomeTestData()
    {
        yield return new object[] { Fixture.Create<string>() };
        yield return new object[] { Fixture.Create<string>() };
    }

    [Theory, MemberData(nameof(SomeTestData), DisableDiscoveryEnumeration = true)]
    public void Test(object value)
    {

    }
}

์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ์„ ์œ„ํ•œ AutoData ๋ฐ InlineAutoData ์†์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ๋งค์šฐ ๋“œ๋ฌธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ AutoFixture๋Š” ๋‹จ์ˆœํ•œ ๋„๊ตฌ์ด๋ฉฐ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐœ๋ฐœ์ž์˜ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค.

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


AutoFixture๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๊ฒฝ์šฐ ํŠน๋ณ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š”์ง€ ํ™•์ธํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด xUnit์— ๋Œ€ํ•ด ํ•ด๋‹น ๋ชจ๋“œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ(NUnit์˜ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค). ๋˜ํ•œ ์ด ํŽ˜์ด์ง€๋„ ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

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

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

ํ•œํŽธ, ์ง€๋‚˜์นœ ํ˜ธํ™˜์„ฑ ๊ฒฝ๊ณ ์— ๋Œ€ํ•ด ์ €๋ฅผ ์šฉ์„œํ•  ์ด์œ ๋ฅผ ์ฐพ์œผ์‹ ๋‹ค๋ฉด, ์ด๊ฒƒ์„ ์ž˜๋ชป๋œ ๊ฒฐ๋ก ์œผ๋กœ โ€‹โ€‹ํ…Œ์ŠคํŠธํ•˜๊ณ  ๊ฒ€์ฆํ•œ ์ œ ๋ถ€๋„๋Ÿฌ์›€์„ ์žŠ๋„๋ก ๋…ธ๋ ฅํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฑฑ์ • ๋งˆ! ์ •๋ง ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ ๋ชจ๋‘๋Š” ์„œ๋กœ์˜ ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜… ํ‹ฐ์ผ“์„ ํ™•์ธํ•˜๊ณ  ์ด์— ๋Œ€ํ•ด ๋…ผ์˜ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค ๐Ÿฅ‡

๋‹น์‹ ์—๊ฒŒ์„œ ๋ฐฐ์šด ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ NCrunch์—์„œ AutoFixture ๊ฒฝ๊ณ ๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ธ€์Ž„์š”, ์šฐ๋ฆฌ๋Š” ์—ฌ์ „ํžˆ NUnit์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์šฐ๋ฆฌ๋Š” ์ง„ํ–‰ ์ค‘ ์ž…๋‹ˆ๋‹ค ). ๊ทธ๋ž˜์„œ ์ด ๋ฉ”์‹œ์ง€๋Š” NUnit ํ”„๋กœ์ ํŠธ์™€ ๊ด€๋ จ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. NUnit์— ๋Œ€ํ•œ ์ „์ฒด ์ง€์›(๋˜๋Š” ์ตœ์†Œํ•œ ํ•ด๋‹น ์ง€์›์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•)์„ ๋„์ž…ํ•˜์ง€ ์•Š๋Š” ํ•œ xUnit์— ๋Œ€ํ•ด์„œ๋งŒ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ๋Š” ์•„์ง ํ•œ ๊ฐ€์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. AutoFixture & NUnit ๋“ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ๋„ค, ํ…Œ์ŠคํŠธ ์ด๋ฆ„์€ ๋งค๋ฒˆ ๋‹ค๋ฅด์ง€๋งŒ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ์ƒ๊ด€์—†๋‚˜์š”(์—”์ง„ ๋ชจ๋“œ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ)? ์•„๋‹ˆ๋ฉด "์˜ํ–ฅ์„ ๋ฐ›์€ ์ „์šฉ" ์—”์ง„์„ ๋” ์ด์ƒ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ? ๋‚ด ์ƒ๊ฐ์€ No support ๋ผ๊ณ  ๋งํ•˜๋Š” ๋Œ€์‹  ์šฐ๋ฆฌ๊ฐ€ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ๋ฒ”์œ„๋ฅผ ์ขํžˆ๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

'์˜ํ–ฅ์„ ๋ฐ›๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ๋Š” ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰'

3.10.0.20 ์„ค์น˜์—์„œ ์ด ์„ค์ •์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ Only consider tests 'Out of date' if they are 'Impacted' ๊ทธ๋กœ ์„ค์ •ํ•ด์•ผ ์„ค์ •์ด true ? ์–ด๋””์„ ๊ฐ€ ๋†“์ณค๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค - ์ €๋Š” ์ด ์ œํ’ˆ์ด ์กฐ๊ธˆ ์ƒ์†Œํ•ฉ๋‹ˆ๋‹ค..


๋ฌธ์„œ ์—…๋ฐ์ดํŠธ

์ด ํŽ˜์ด์ง€์—์„œ xUnit ๋ฐ AutoFixture์˜ ๊ฒฝ์šฐ๋ฅผ _์ œ๊ฑฐ_ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค( DisableDiscoveryEnumeration ์†์„ฑ ์‚ฌ์šฉ). ๋˜ํ•œ xUnit์— ๋Œ€ํ•œ "NUnit Test Case With Inconsistent Name" ์ƒ˜ํ”Œ์„ ์„ค๋ช…ํ•˜๊ณ  DisableDiscoveryEnumeration ์†์„ฑ์„ MemberDataAttribute ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ๋Š” ์•„์ง ํ•œ ๊ฐ€์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. AutoFixture & NUnit ๋“ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ๋„ค, ํ…Œ์ŠคํŠธ ์ด๋ฆ„์€ ๋งค๋ฒˆ ๋‹ค๋ฅด์ง€๋งŒ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ์ƒ๊ด€์—†๋‚˜์š”(์—”์ง„ ๋ชจ๋“œ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ)? ์•„๋‹ˆ๋ฉด "์˜ํ–ฅ์„ ๋ฐ›์€ ์ „์šฉ" ์—”์ง„์„ ๋” ์ด์ƒ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ? ๋‚ด ์ƒ๊ฐ์€ ์ง€์› ์•ˆ ํ•จ์ด๋ผ๊ณ  ๋งํ•˜๋Š” ๋Œ€์‹  ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ๋ฒ”์œ„๋ฅผ ์ขํžˆ๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

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

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

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

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

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

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

๋‚ด 3.10.0.20 ์„ค์น˜์—์„œ ์ด ์„ค์ •์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. true๋กœ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” '์˜ํ–ฅ์„ ๋ฐ›์€' ์„ค์ •์ธ ๊ฒฝ์šฐ์—๋งŒ ํ…Œ์ŠคํŠธ๊ฐ€ '์˜ค๋ž˜๋จ'์œผ๋กœ ๊ฐ„์ฃผ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ์–ด๋””์„ ๊ฐ€ ๋†“์ณค๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค - ์ €๋Š” ์ด ์ œํ’ˆ์ด ์กฐ๊ธˆ ์ƒ์†Œํ•ฉ๋‹ˆ๋‹ค..

NCrunch ๋ฉ”๋‰ด๋กœ ์ด๋™ํ•˜์—ฌ '์—”์ง„ ๋ชจ๋“œ ์„ค์ •'์„ ์„ ํƒํ•˜๋ฉด ์˜ต์…˜์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— ์—†์œผ๋ฉด ํ›จ์”ฌ ์ด์ „ ๋ฒ„์ „์˜ NCrunch์—์„œ ์‹คํ–‰ํ•œ ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉ ์ค‘์ด๊ณ  ๋ ˆ๊ฑฐ์‹œ ์—”์ง„ ๋ชจ๋“œ๋งŒ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋”˜๊ฐ€์—์„œ ์ƒˆ๋กœ์šด ์†”๋ฃจ์…˜์„ ์ƒ์„ฑํ•˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

@remcomulder ์™€์šฐ! ์ด๋ ‡๊ฒŒ ์ž์„ธํ•œ ์„ค๋ช… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ด์ œ ์‹ค์ œ๋กœ AutoFixture & NUnit์ด ํ˜„์žฌ ์ง€์›๋˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ํ›„๋“œ ์•„๋ž˜์— ๋ช‡ ๊ฐ€์ง€ ๊ฑฐ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค ๐Ÿ˜…

๋‚˜๋Š” ์—ฌ์ „ํžˆ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๋ถˆ์•ˆ์ •ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ผ๊ด€๋œ ์‹œ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ด๋ฒˆ PR์—์„œ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅธ ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์•ˆ์ •์ ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ…Œ์ŠคํŠธ๊ฐ€ ์ฃผ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

    [Test, StableNameAutoData]
    public void Sample(int a, Data d1, DataWithToString d2, ISomeData d3)
    {
        Assert.IsTrue(true);
    }

ํ…Œ์ŠคํŠธ ์ด๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

NUnit3RunnerTest709.TestNameTester.Sample(auto<System.Int32>,auto<NUnit3RunnerTest709.Data>,auto<NUnit3RunnerTest709.DataWithToString>,auto<Castle.Proxies.ISomeDataProxy>)

์ด๋ฆ„์€ ๊ฐ ๊ฒ€์ƒ‰/์‹คํ–‰ ์ค‘์— ํ•ญ์ƒ ๋™์ผํ•˜์ง€๋งŒ ์‹ค์ œ ์ธ์ˆ˜ ๊ฐ’์€ ๋งค๋ฒˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

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

ํ…Œ์ŠคํŠธ๋Š” ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๊ณ  ์ผ๊ด€์„ฑ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฐœ๋…์ด ํ•ญ์ƒ ์กด์žฌํ•˜๋Š”๋ฐ, ์ด๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ๋ชจ๋“  ์ž…๋ ฅ์„ ์™„์ „ํžˆ ๋ฌด์ž‘์œ„ํ™”ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ฌ์„ฑํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

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

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

๋ถˆํ–‰ํžˆ๋„ NUnit์— ๋Œ€ํ•œ ๋‚ด ์ง€์‹์€ ๊นŠ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. NCrunch๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ NUnit์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์ด๋ฅผ ์‹๋ณ„์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ก ์ ์œผ๋กœ ์†”๋ฃจ์…˜์ด ํ…Œ์ŠคํŠธ์˜ ๋ฌผ๋ฆฌ์  ์ด๋ฆ„์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝ/์•ˆ์ •ํ™”ํ•˜๋Š” ํ•œ NUnit API์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์—์„œ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.
์ ์–ด๋„ NCrunch์˜ ๊ฒฝ์šฐ.

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

@remcomulder ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋„๋ก ์—…๋ฐ์ดํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

์šฐ๋ฆฌ๋Š” ์ตœ๊ทผ์— PR์„ ๋ณ‘ํ•ฉํ•˜๊ณ  NUnit์˜ ์•ˆ์ •์ ์ธ ์ด๋ฆ„์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ƒˆ ๋ฒ„์ „์˜ AutoFixture( v3.51.0 )๋ฅผ ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์‚ฌ์šฉ์ž ์ธก์—์„œ ์ˆ˜๋™ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ( ์—ฌ๊ธฐ ์ฐธ์กฐ) v4์—์„œ๋Š” ์ฆ‰์‹œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐฉ๊ธˆ ํ…Œ์ŠคํŠธํ•œ ๊ฒฐ๊ณผ ์œ„์˜ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด NCrunch๊ฐ€ ์ˆ˜์ •๋œ ํ…Œ์ŠคํŠธ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด์ œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ผ๋ถ€ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•œ์ง€ ์—ฌ๋ถ€๊ฐ€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ: ์–ด๋”˜๊ฐ€์— ๋ฌธ์„œํ™”). ๋˜ํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์ง€๊ธˆ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ํœด์‹์„ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜„

@zvirja ์ด์— ๋Œ€ํ•ด

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

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

์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋‚˜์š”?

๋‚˜๋Š” ์ด ์ž‘์—…์— ๋น ๋ฅธ ํ…Œ์ŠคํŠธ๋ฅผ ํ–ˆ๊ณ  ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๊ฒฌ๊ณ ํ•ด ๋ณด์ธ๋‹ค.

๊ต‰์žฅํ•ด! ๐ŸŽ‰ ์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ์™€ ์ฐธ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค ๐Ÿฅ‡

์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋‚˜์š”?

ํ›จ์”ฌ ๋” ์šฐ์ˆ˜ํ•˜๊ณ  ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. FixedNameTestMethodBuilder ๋ฅผ ๋‹ค์Œ ๋‹ฌ ๋˜๋Š” ๋‘ ๋‹ฌ์— ์ถœ์‹œ๋  v4(์ฐจ๊ธฐ ์ฃผ์š” ๋ฆด๋ฆฌ์Šค)์˜ ๊ธฐ๋ณธ ์ „๋žต์œผ๋กœ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ ์ ˆํ•œ PR ์ด ์ด๋ฏธ ์Šน์ธ ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž˜ ์ž‘๋™ํ•˜๊ณ  ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํœ˜๋ฐœ์„ฑ ํ…Œ์ŠคํŠธ ์ด๋ฆ„์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ˆ˜๋™์œผ๋กœ ์„ ํƒํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์ค‘์— ์ œ์•ˆํ•œ ๋Œ€๋กœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜/AppConfig๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ์ „ํ™˜ ์ „๋žต์„ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

ํ›จ์”ฌ ๋” ์šฐ์ˆ˜ํ•˜๊ณ  ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹ฌ ๋˜๋Š” ๋‘ ๋‹ฌ์— ์ถœ์‹œ๋  v4(์ฐจ๊ธฐ ์ฃผ์š” ๋ฆด๋ฆฌ์Šค)์—์„œ FixedNameTestMethodBuilder๋ฅผ ๊ธฐ๋ณธ ์ „๋žต์œผ๋กœ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค :) ๋‚˜๋Š” ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค! ๋ชจ๋“  ๋…ธ๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋ฉ‹์ง€๋‹ค ๐Ÿ˜‰ ๋‹ต๋ณ€๊ณผ ์ฝœ๋ผ๋ณดํ•ด์ฃผ์…”์„œ ๋‹ค์‹œํ•œ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค ๐Ÿ‘

์–‘์ธก์—์„œ ๋” ์ด์ƒ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด ์ž‘์—…์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

@remcomulder @zvirja ์ด ํ† ๋ก (๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋จ)๊ณผ ์—ฌ๊ธฐ์—์„œ ๋ณด์—ฌ ์ฃผ์‹  ํ—Œ์‹ ์ด ์ •๋ง ๋Œ€๋‹จํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค! ๋‘ ๋ถ„์˜ ํ›Œ๋ฅญํ•œ ์ œํ’ˆ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

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