xUnit.net

wwiki
Jhkim (토론 | 기여)님의 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});
}