NUnit 2.6.4์์ ๋ด ํ
์คํธ์ ์์
๋๋ ํ ๋ฆฌ๋ ํ
์คํธ DLL์ ํด๋น bin/Debug
๋๋ ํ ๋ฆฌ๋ก ์ค์ ๋์์ต๋๋ค. ์ด๋ฅผ ํตํด ์๋ ๊ฒฝ๋ก๋ก ํ
์คํธ์์ ์ธ๋ถ ํ์ผ์ ๋ก๋ํ ์ ์์ต๋๋ค.
์ด์ ์์ ๋๋ ํ ๋ฆฌ๊ฐ ์ฝ์ ๋ฌ๋์ ์์ ๋๋ ํ ๋ฆฌ๋ก ์ค์ ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ ์๋์ ์ผ๋ก ์ค๊ณ๋ ๊ฒ์ ๋๊น?
ํ
์คํธ ๊ฒฐ๊ณผ(*.xml ํ์ผ)๋ฅผ ์ฝ์ ๋ฌ๋์ ์์
๋๋ ํ ๋ฆฌ์ ๋จ๊ฒจ๋๊ณ ํ
์คํธ์ ์์
๋๋ ํ ๋ฆฌ๋ฅผ bin/Debug
์ค์ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์ด๊ฒ์ https://github.com/nunit/nunit/wiki/Breaking-Changes์ ํ์๋ ๋๋ก ์๋์ ์ผ๋ก ์ค๊ณ๋ ๊ฒ์ ๋๋ค.
์ด์ ๋ฒ์ ์์ NUnit์ ์์ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค. ๋ ์ด์ ๊ทธ๋ ๊ฒ ํ์ง ์์ต๋๋ค. TestContext.TestDirectory๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ์ด์ ๋ธ๋ฆฌ๊ฐ ํฌํจ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋ง์ ํ ์คํธ๋ฅผ ๋ง์นฉ๋๋ค! ์ ๋ฐ๊ฟจ์ด? ํ ์คํธ๋ ์ฑ์ ๋ฐํ์ ์ฝ๋์ ์์ ๋๋ ํฐ๋ฆฌ๊ฐ ํ ์คํธ ์ด์ ๋ธ๋ฆฌ์ ์์น๋ผ๋ ์ข ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ์ผ๋ถ ํ ์คํธ๋ฅผ ์์ ํ ์ ์์ต๋๋ค.
@imakowski ์ด์ ๋ธ๋ฆฌ ์ค์ ์์ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ๋ฅผ ์๋ ค์ง ๋๋ ํ ๋ฆฌ๋ก ์ค์ ํด
``` C#
[ํฝ์ค์ฒ ์ค์ ]
๊ณต๊ฐ ํด๋์ค MySetUpClass
{
[์ํ์์
์
]
RunBeforeAnyTests()
{
var ๋๋ ํ ๋ฆฌ = ๊ฒฝ๋ก.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);
Environment.CurrentDirectory = ๋๋ ํ ๋ฆฌ;
// or
Directory.SetCurrentDirectory(dir);
}
}
```
@imakowski ๋น์ ์ ๊ทธ๊ฒ์ ์ ์ดํ ์ ์์ง๋ง ์ฝ๋/์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ๋๋ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ์ ์์กดํด์๋ ์๋ฉ๋๋ค. ์์ฉ ํ๋ก๊ทธ๋จ์ ํญ์ ์์์ ์ ์ํ ๊ฒ๊ณผ ๊ฐ์ ์ฝ๋๋ก bin ๋๋ ํ ๋ฆฌ๋ฅผ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค. Windows์๋ ์ฌ์ฉ์๊ฐ ์์ง ๋ชปํ๋ ์ฌ์ด์ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ๋ ์ฌ๋ฌ API ํธ์ถ์ด ์์ต๋๋ค. ๊ทํ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ ์์ ์ผ๋ก ์คํ๋ ์ ์์ง๋ง ์ฌ์ฉ์๊ฐ ๊ทํ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์๋ ๋ถ๋ถ์ ๋ฐฉ๋ฌธํ ํ์๋ ์คํจํฉ๋๋ค.
@rprouse ์ด ์ฝ๋๋ ์๋ ๋ณต์ฌ ๋ชจ๋์ ์์ ๋ ์๋ํ์ง ์์ต๋๋ค.
var dir = Path.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);
์ด ๊ฒฝ์ฐ ๋ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
var dir = Path.GetDirectoryName(new Uri(typeof(MySetUpClass).Assembly.CodeBase).LocalPath);
๋๋ TestContext.CurrentContext.TestDirectory๋ก ์ ๊ณตํฉ๋๋ค. :-)
์ฐ๋ฆฌ๋ ํน๋ณํ ๊ฒฝ์ฐ๋ฅผ ์ํด ์ฝ๊ฐ์ ์กฐ์ ๊ณผ ํจ๊ป ์ ์๋ ๋๋ก Uri๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋๋ TestContext.CurrentContext.TestDirectory๋ก ์ ๊ณตํฉ๋๋ค. :-)
CurrentContext์๋ ๋ ์ด์ TestDirectory ์์ฑ์ด ์์ต๋๋ค. ๋๋ nunit 3.6.1์ ์ฌ์ฉํฉ๋๋ค. ๋ด ๊ฒฝ์ฐ์๋ resharper์์ ํ ์คํธ๋ฅผ ์์ํ ๋ ์๋ชป๋ ์์น๋ฅผ ๊ฐ๋ฆฌํค๋ WorkDirectory๋ง ์์ต๋๋ค.(
TestContext.TestDirectory๊ฐ ์์ต๋๋ค. ์ ์ ์์ฑ์ ๋๋ค. WorkDirectory๋ ๋ง์ฐฌ๊ฐ์ง๋ผ๊ณ ์๊ฐํฉ๋๊น?
๊ธ์, Visual Studio ๋ธ๋ผ์ฐ์ ๋ ์ปดํ์ผ๋ฌ ๋๋ ํ
๋ ๋ฆญ ๋์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฐพ์ ์ ์์ต๋๋ค.
ํ์ง๋ง nunit 3.5์์ ๋ณผ ์ ์์ต๋๋ค. ๋ฌด์์ด ์๋ชป๋์๋์ง ํ์คํ์ง ์๋ค
๋ด๊ฐ ํ๋ ธ์ด.
TestContext.CurrentContext.TestDirectory์ ๋๋ค.
๊ทธ๋ฌ๋ PORTABLE ๋น๋์๋ ์์ต๋๋ค.
#if !PORTABLE
/// <summary>
/// Gets the directory containing the current test assembly.
/// </summary>
public string TestDirectory
{
get
{
Assembly assembly = _testExecutionContext?.CurrentTest?.TypeInfo?.Assembly;
if (assembly != null)
return AssemblyHelper.GetDirectoryName(assembly);
#if NETSTANDARD1_6
// Test is null, we may be loading tests rather than executing.
// Assume that the NUnit framework is in the same directory as the tests
return AssemblyHelper.GetDirectoryName(typeof(TestContext).GetTypeInfo().Assembly);
#else
// Test is null, we may be loading tests rather than executing.
// Assume that calling assembly is the test assembly.
return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly());
#endif
}
}
#endif
3.6.0์๋ ์์ง๋ง 3.6.1์๋ ์์ต๋๋ค.
ํ์ฌ github repo๋ฅผ ๋ณด๊ณ ์๋๋ฐ ์์์ ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ์ ๊ทธ๋๋ก์ ๋๋ค.
์ด๋ป๊ฒ๋ PORTABLE ๋น๋๋ฅผ ์ฌ์ฉํ๊ณ ์์ง ์์ต๋๊น?
์, ์ฌ์ฉํ๊ณ ์์ต๋๋ค
๊ธ์, ๊ทธ๊ฒ์ด ๊ฑฐ๊ธฐ์์๋ ์ด์ ์ ๋๋ค. PORTABLE ๋น๋์์๋ ์ง์๋์ง ์์ผ๋ฉฐ ๋ด๊ฐ ์๋ ํ ์ง์ํ ์ ๋ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ PORTABLE ๋น๋๋ฅผ ์ฌ์ฉํ ์ ์ด ์์ผ๋ฉฐ CI ํ ์คํธ๋ฅผ ์คํํ์ญ์์ค.
๊ฐ์ฌ ํด์
๋๋ ํ ๋ฆฌ.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
@CharliePoole ๊ณผ @rprouse๊ฐ ๋งํ ๊ฒ์ ์ข ํฉ ํ๋ฉด ์ค์ ์ฝ๋๋ฅผ
[SetUpFixture]
public class MySetUpClass
{
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
// or identically under the hoods
Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
}
}
๋ค์์คํ์ด์ค ์์ ์์ ๋ ผ๋ฆฌ๋ฅผ ๋ฌถ์ง ๋ง์ญ์์ค. ์ฆ
using NUnit.Framework;
using System;
using System.IO;
[SetUpFixture]
public class GlobalSetup
{
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
// or identically under the hoods
Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
}
}
๋ํ TestContext.CurrentContext.TestDirectory
์๋ ์ฝ๋ ์ผ์ด์ค๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๋ ๋ง์ ์ ๋ณด๊ฐ ์๋ ๊ฒ ๊ฐ์ผ๋ฏ๋ก typeof(MySetUpClass).Assembly.Location
๋ณด๋ค ์ ํํ๊ฒ ์ต๋๋ค.
๊ทธ๋์ typeof(MySetUpClass).Assembly.Location๋ณด๋ค ์ ํํ๊ฒ ์ต๋๋ค.
Location
๋ ์ด์
๋ธ๋ฆฌ๊ฐ ์๋ ๋ณต์ฌ๋ ๊ฒฝ์ฐ ์๋ ์์น๋ฅผ ๋ฐํํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ์ํ์ง ์์ต๋๋ค. CodeBase
๋์ Uri
๊ฐ ๋ฐํ๋ฉ๋๋ค.
๋ถ๋ช
ํ TestDirectory
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ง๋ง ํด๋น ์์ฑ์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. #2872 ์ฐธ์กฐ, catchํ ์ ์๋ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. OneTimeSetup
๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ๋ํ๋ ์ ์๋์ง ์ฌ๋ถ๋ ์ ์ ์์ง๋ง(๊ทธ๋ ์ง ์๋ค๊ณ ๊ฐ์ ํจ) ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์ฃผ์๋ฅผ ๊ธฐ์ธ์ฌ์ผ ํฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@imakowski ์ด์ ๋ธ๋ฆฌ ์ค์ ์์ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ๋ฅผ ์๋ ค์ง ๋๋ ํ ๋ฆฌ๋ก ์ค์ ํด
``` C#
[ํฝ์ค์ฒ ์ค์ ]
๊ณต๊ฐ ํด๋์ค MySetUpClass
{
[์ํ์์ ์ ]
RunBeforeAnyTests()
{
var ๋๋ ํ ๋ฆฌ = ๊ฒฝ๋ก.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);
Environment.CurrentDirectory = ๋๋ ํ ๋ฆฌ;
}
```