ํ์ฌ NCrunch๋ AutoFixture๋ฅผ ์ง์ํ์ง ์์ผ๋ฉฐ ๋ฌธ์์ ๋ช ํํ๊ฒ ๋ช ์๋์ด ๋ฌธ์ ๋ฅผ ์ผ์ผํค๊ณ ์ด๋ป๊ฒ๋ ํด๊ฒฐํ๋ ค๊ณ ํ์ง๋ง ๋ ๋ณต์กํ ๋ฌธ์ ๋ก ๋ณด์์ต๋๋ค.
NCrunch ๊ฐ๋ฐ์๋ฅผ ์ฌ๊ธฐ์ ์ด๋ํ์ฌ ๊ทธ ๋ฌธ์ ๋ฅผ ํจ๊ป ๋ ผ์ํ๊ฒ ์ต๋๋ค. ์๋ง๋ xUnit ํ๋ฉด์ผ๋ก ๋ ์ด๋ํ ์๋ ์์ต๋๋ค.
์ํฌ๋ฐ์น ๋ ๋ค ๊ฝค ์ ๋ช ํ ์ ํ์ด๋ ์ํฌ๋ฐ์น๋ ๊ฐ์ด ์์ ํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ์ง ๐
์๋ ํ์ธ์ ์ํฌ๋ฐ์น ๊ฐ๋ฐ์์ ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ ์ฐพ๊ธฐ ์ํด ๊ธฐ๊บผ์ด ํ๋ ฅํ๊ฒ ์ต๋๋ค. ํ์ฌ ๋์์ธ์์๋ ์ฌํ๊ฒ๋ ํตํฉ ์ง์ ์ธก๋ฉด์์๋ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ต์ ์ด ์์ต๋๋ค. ํ์ฌ ๋์์ธ์์ ๋ฌธ์ ๋ฅผ ๊ฒฝํํ ์ฌ๋์ ์ฃผ์๊ฐ ์ ์ผํ ์ฌ๋์ด ์๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ด๊ฐ ์์ฑํ ๋ค์ํ ๋ฌธ์ ๋ฐ ์ง์ ํฌ๋ผ ๊ฒ์๋ฌผ์ ํตํด ์ดํดํ์ จ๊ฒ ์ง๋ง ๋ฌธ์ ์ ๊ทผ์์ 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.0xunit.runner.visualstudio
2.2.0AutoFixture
3.50.6AutoFixture.Xunit2
3.50.6VS์์ ๊ฒ์์ ํธ๋ฆฌ๊ฑฐํ๋ฉด ๋ค์ ์ถ๋ ฅ์ด ํ์๋ฉ๋๋ค.
์ ์ ์๋ฏ์ด ๋ฐ์ดํฐ ๊ฒ์์ ์ง์ํ๋ ์ด๋ก ( StableInlineTest
)์ ๊ฒฝ์ฐ VS runner๋ ํ
์คํธ๊ฐ ์คํ๋ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค( 1
). ๋ฐ์ดํฐ ๊ฒ์์ ์ง์ํ์ง ์๊ณ ์๋ ์์ฑ๋ ๋ฐ์ดํฐ( VolatileTest
, VolatileTestWithInline
)๋ฅผ ํฌํจํ๋ ํ
์คํธ์ ๊ฒฝ์ฐ VS๋ ์ด๋ก ์ฌ๋ก๋ฅผ ๋ฐ๊ฒฌํ์ง ์๊ณ ์ ์ฒด ์ด๋ก ๋ง ๋ณด์ฌ์ค๋๋ค. ์คํํ ํ์๋ง ์ด ํน์ ํธ์ถ์ ๋ํ ๊ฐ์ ๋ณผ ์ ์์ต๋๋ค.
์ด์ ํน์ ์ด๋ก ์ ๋ค์ ์คํํ ์ ์์ผ๋ฉฐ _๋ชจ๋ ์ด๋ก ์ฌ๋ก_๋ฅผ ๋ค์ ์คํํ ๊ฒ์ ๋๋ค.
๋ณด์๋ค์ํผ ์ค์ ๋ก ์ด๋ฌํ ์ด๋ก ์ ์ง์ํ๋ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉฐ 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 ์ด ํ ๋ก (๋น์ทํ ๋ฌธ์ ๋ฅผ ์ดํดํ๋ ๋ฐ ๋์์ด ๋จ)๊ณผ ์ฌ๊ธฐ์์ ๋ณด์ฌ ์ฃผ์ ํ์ ์ด ์ ๋ง ๋๋จํ๋ค๊ณ ๋งํ๊ณ ์ถ์์ต๋๋ค! ๋ ๋ถ์ ํ๋ฅญํ ์ ํ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@remcomulder @zvirja ์ด ํ ๋ก (๋น์ทํ ๋ฌธ์ ๋ฅผ ์ดํดํ๋ ๋ฐ ๋์์ด ๋จ)๊ณผ ์ฌ๊ธฐ์์ ๋ณด์ฌ ์ฃผ์ ํ์ ์ด ์ ๋ง ๋๋จํ๋ค๊ณ ๋งํ๊ณ ์ถ์์ต๋๋ค! ๋ ๋ถ์ ํ๋ฅญํ ์ ํ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.