"XUnit.net"의 두 판 사이의 차이

wwiki
이동: 둘러보기, 검색
36번째 줄: 36번째 줄:
 
|[TestInitialize]
 
|[TestInitialize]
 
|Constructor
 
|Constructor
|We believe that use of [SetUp] is generally bad. However, you can implement a parameterless constructor as a direct replacement. See Note 2
+
|We believe that use of [SetUp] is generally bad. However, you can implement a parameterless constructor as a direct replacement. See [[XUnit.net#Note%202|Note 2]]
 
|-
 
|-
 
|[TearDown]
 
|[TearDown]
 
|[TestCleanup]
 
|[TestCleanup]
 
|IDisposable.Dispose
 
|IDisposable.Dispose
|We believe that use of [TearDown] is generally bad. However, you can implement IDisposable.Dispose as a direct replacement. See Note 2
+
|We believe that use of [TearDown] is generally bad. However, you can implement IDisposable.Dispose as a direct replacement. See [[XUnit.net#Note%202|Note 2]]
 
|-
 
|-
 
|[OneTimeSetUp]
 
|[OneTimeSetUp]
 
|[ClassInitialize]
 
|[ClassInitialize]
 
|IClassFixture<T>
 
|IClassFixture<T>
|To get per-class fixture setup, implement IClassFixture<T> on your test class. See Note 3
+
|To get per-class fixture setup, implement IClassFixture<T> on your test class. See [[XUnit.net#Note%203|Note 3]]
 
|-
 
|-
 
|[OneTimeTearDown]
 
|[OneTimeTearDown]
 
|[ClassCleanup]
 
|[ClassCleanup]
 
|IClassFixture<T>
 
|IClassFixture<T>
|To get per-class fixture teardown, implement IClassFixture<T> on your test class. See Note 3
+
|To get per-class fixture teardown, implement IClassFixture<T> on your test class. See [[XUnit.net#Note%203|Note 3]]
 
|-
 
|-
 
|''n/a''
 
|''n/a''
 
|''n/a''
 
|''n/a''
 
|ICollectionFixture<T>
 
|ICollectionFixture<T>
|To get per-collection fixture setup and teardown, implement ICollectionFixture<T> on your test collection. See Note 3
+
|To get per-collection fixture setup and teardown, implement ICollectionFixture<T> on your test collection. See [[XUnit.net#Note%203|Note 3]]
 
|-
 
|-
 
|[Ignore("reason")]
 
|[Ignore("reason")]
73번째 줄: 73번째 줄:
  
 
[XxxData]
 
[XxxData]
|Theory (data-driven test). See Note 4
+
|Theory (data-driven test). See [[XUnit.net#Note%204|Note 4]]
 
|}
 
|}
  
92번째 줄: 92번째 줄:
 
{
 
{
 
     var person = new Person(null!);
 
     var person = new Person(null!);
 +
}
 +
</syntaxhighlight>
 +
 +
===== Note 2 =====
 +
각 테스트를 실행하기 전에 실행할 코드를 지정할 때 사용한다.<syntaxhighlight lang="csharp">
 +
// Use TestInitialize to run code before running each test
 +
[TestInitialize()]
 +
public void MyTestInitialize()
 +
{
 +
    // To generate code for this test, select "Generate Code for Coded
 +
    // UI Test" from the shortcut menu and select one of the menu items.
 +
    // For more information on generated code, see
 +
    // http://go.microsoft.com/fwlink/?LinkId=179463
 +
 +
    // You could move this line from the CodedUITestMethod1() method
 +
    this.UIMap.LaunchCalculator();
 +
}
 +
 +
// Use TestCleanup to run code after each test has run
 +
[TestCleanup()]
 +
public void MyTestCleanup()
 +
{
 +
    // To generate code for this test, select "Generate Code for Coded
 +
    // UI Test" from the shortcut menu and select one of the menu items.
 +
    // For more information on generated code, see
 +
    // http://go.microsoft.com/fwlink/?LinkId=179463
 +
 +
    // You could move this line from the CodedUITestMethod1() method
 +
    this.UIMap.CloseCalculator();
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
===== Note 3 =====
 
===== Note 3 =====
<br />
+
클래스의 첫 번째 테스트를 실행하기 전에 실행할 코드를 지정한다.<syntaxhighlight lang="csharp">
 +
using System;
 +
 
 +
namespace SampleClassLib
 +
{
 +
    public class DivideClass
 +
    {
 +
        public static int DivideMethod(int denominator)
 +
        {
 +
            return (2 / denominator);
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>테스트 코드<syntaxhighlight lang="csharp">
 +
using Microsoft.VisualStudio.TestTools.UnitTesting;
 +
using SampleClassLib;
 +
using System;
 +
using System.Windows.Forms;
 +
 
 +
namespace TestNamespace
 +
{
 +
    [TestClass()]
 +
    public sealed class DivideClassTest
 +
    {
 +
        [AssemblyInitialize()]
 +
        public static void AssemblyInit(TestContext context)
 +
        {
 +
            MessageBox.Show("AssemblyInit " + context.TestName);
 +
        }
 +
 
 +
        [ClassInitialize()]
 +
        public static void ClassInit(TestContext context)
 +
        {
 +
            MessageBox.Show("ClassInit " + context.TestName);
 +
        }
 +
 
 +
        [TestInitialize()]
 +
        public void Initialize()
 +
        {
 +
            MessageBox.Show("TestMethodInit");
 +
        }
 +
 
 +
        [TestCleanup()]
 +
        public void Cleanup()
 +
        {
 +
            MessageBox.Show("TestMethodCleanup");
 +
        }
 +
 
 +
        [ClassCleanup()]
 +
        public static void ClassCleanup()
 +
        {
 +
            MessageBox.Show("ClassCleanup");
 +
        }
 +
 
 +
        [AssemblyCleanup()]
 +
        public static void AssemblyCleanup()
 +
        {
 +
            MessageBox.Show("AssemblyCleanup");
 +
        }
 +
 
 +
        [TestMethod()]
 +
        [ExpectedException(typeof(System.DivideByZeroException))]
 +
        public void DivideMethodTest()
 +
        {
 +
            DivideClass.DivideMethod(0);
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
===== Note 4 =====
 +
데이터 기반 단위 테스트<syntaxhighlight lang="csharp">
 +
public int AddIntegers(int first, int second)
 +
{
 +
    int sum = first;
 +
    for( int i = 0; i < second; i++)
 +
    {
 +
        sum += 1;
 +
    }
 +
    return sum;
 +
}
 +
</syntaxhighlight>테스트 클래스에 TestContext 추가<syntaxhighlight lang="csharp">
 +
private TestContext testContextInstance;
 +
public TestContext TestContext
 +
{
 +
    get { return testContextInstance; }
 +
    set { testContextInstance = value; }
 +
}
 +
</syntaxhighlight>테스트 메서드 작성<syntaxhighlight lang="csharp">
 +
[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")]
 +
[TestMethod()]
 +
public void AddIntegers_FromDataSourceTest()
 +
{
 +
    var target = new Maths();
 +
 
 +
    // Access the data
 +
    int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);
 +
    int y = Convert.ToInt32(TestContext.DataRow["SecondNumber"]);
 +
    int expected = Convert.ToInt32(TestContext.DataRow["Sum"]);
 +
    int actual = target.IntegerMethod(x, y);
 +
    Assert.AreEqual(expected, actual,
 +
        "x:<{0}> y:<{1}>",
 +
        new object[] {x, y});
 +
}
 +
</syntaxhighlight><br />
 
{{DEFAULTSORT:xUnit.net}}
 
{{DEFAULTSORT:xUnit.net}}

2021년 6월 14일 (월) 12:36 판


https://xunit.net

Document

https://xunit.net/#documentation

Comparing xUnit.net to other frameworks

https://xunit.net/docs/comparisons

NUnit 3.x MSTest 15.x xUnit.net 2.x Comments
[Test] [TestMethod] [Fact] Marks a test method.
[TestFixture] [TestClass] n/a xUnit.net does not require an attribute for a test class; it looks for all test methods in all public (exported) classes in the assembly.
Assert.That

Record.Exception

[ExpectedException] Assert.Throws

Record.Exception

xUnit.net has done away with the ExpectedException attribute in favor of Assert.Throws. See Note 1
[SetUp] [TestInitialize] Constructor We believe that use of [SetUp] is generally bad. However, you can implement a parameterless constructor as a direct replacement. See Note 2
[TearDown] [TestCleanup] IDisposable.Dispose We believe that use of [TearDown] is generally bad. However, you can implement IDisposable.Dispose as a direct replacement. See Note 2
[OneTimeSetUp] [ClassInitialize] IClassFixture<T> To get per-class fixture setup, implement IClassFixture<T> on your test class. See Note 3
[OneTimeTearDown] [ClassCleanup] IClassFixture<T> To get per-class fixture teardown, implement IClassFixture<T> on your test class. See Note 3
n/a n/a ICollectionFixture<T> To get per-collection fixture setup and teardown, implement ICollectionFixture<T> on your test collection. See Note 3
[Ignore("reason")] [Ignore] [Fact(Skip="reason")] Set the Skip parameter on the [Fact] attribute to temporarily skip a test.
[Property] [TestProperty] [Trait] Set arbitrary metadata on a test
[Theory] [DataSource] [Theory]

[XxxData]

Theory (data-driven test). See Note 4

Attribute Notes

Note 1

기대되는 예외지정

#nullable enable
public class Person
{
    public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

    public string Name { get; }
}

테스트 코드

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void NullNameShouldThrowTest()
{
    var person = new Person(null!);
}
Note 2

각 테스트를 실행하기 전에 실행할 코드를 지정할 때 사용한다.

// Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
    // To generate code for this test, select "Generate Code for Coded
    // UI Test" from the shortcut menu and select one of the menu items.
    // For more information on generated code, see
    // http://go.microsoft.com/fwlink/?LinkId=179463

    // You could move this line from the CodedUITestMethod1() method
    this.UIMap.LaunchCalculator();
}

// Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
    // To generate code for this test, select "Generate Code for Coded
    // UI Test" from the shortcut menu and select one of the menu items.
    // For more information on generated code, see
    // http://go.microsoft.com/fwlink/?LinkId=179463

    // You could move this line from the CodedUITestMethod1() method
    this.UIMap.CloseCalculator();
}
Note 3

클래스의 첫 번째 테스트를 실행하기 전에 실행할 코드를 지정한다.

using System;

namespace SampleClassLib
{
    public class DivideClass
    {
        public static int DivideMethod(int denominator)
        {
            return (2 / denominator);
        }
    }
}

테스트 코드

using Microsoft.VisualStudio.TestTools.UnitTesting;
using SampleClassLib;
using System;
using System.Windows.Forms;

namespace TestNamespace
{
    [TestClass()]
    public sealed class DivideClassTest
    {
        [AssemblyInitialize()]
        public static void AssemblyInit(TestContext context)
        {
            MessageBox.Show("AssemblyInit " + context.TestName);
        }

        [ClassInitialize()]
        public static void ClassInit(TestContext context)
        {
            MessageBox.Show("ClassInit " + context.TestName);
        }

        [TestInitialize()]
        public void Initialize()
        {
            MessageBox.Show("TestMethodInit");
        }

        [TestCleanup()]
        public void Cleanup()
        {
            MessageBox.Show("TestMethodCleanup");
        }

        [ClassCleanup()]
        public static void ClassCleanup()
        {
            MessageBox.Show("ClassCleanup");
        }

        [AssemblyCleanup()]
        public static void AssemblyCleanup()
        {
            MessageBox.Show("AssemblyCleanup");
        }

        [TestMethod()]
        [ExpectedException(typeof(System.DivideByZeroException))]
        public void DivideMethodTest()
        {
            DivideClass.DivideMethod(0);
        }
    }
}
Note 4

데이터 기반 단위 테스트

public int AddIntegers(int first, int second)
{
    int sum = first;
    for( int i = 0; i < second; i++)
    {
        sum += 1;
    }
    return sum;
}

테스트 클래스에 TestContext 추가

private TestContext testContextInstance;
public TestContext TestContext
{
    get { return testContextInstance; }
    set { testContextInstance = value; }
}

테스트 메서드 작성

[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")]
[TestMethod()]
public void AddIntegers_FromDataSourceTest()
{
    var target = new Maths();

    // Access the data
    int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);
    int y = Convert.ToInt32(TestContext.DataRow["SecondNumber"]);
    int expected = Convert.ToInt32(TestContext.DataRow["Sum"]);
    int actual = target.IntegerMethod(x, y);
    Assert.AreEqual(expected, actual,
        "x:<{0}> y:<{1}>",
        new object[] {x, y});
}