xUnit.net의 모든 테스트 전후에 한 번 코드 실행
TL; DR-MSTest의 xUnit에 해당하는 기능을 찾고 있습니다 AssemblyInitialize
(내가 좋아하는 하나의 기능).
특히 다른 종속성없이 실행할 수있는 Selenium 연기 테스트가 있기 때문에 찾고 있습니다. 나는 나를 위해 IisExpress를 시작하고 처분 할 때 죽일 Fixture가 있습니다. 그러나 모든 테스트 전에 이것을 수행하면 런타임이 엄청나게 부풀어집니다.
테스트를 시작할 때이 코드를 한 번 트리거하고 마지막에 폐기 (프로세스 종료)하고 싶습니다. 어떻게하면 되나요?
"현재 실행중인 테스트 수"와 같은 것에 프로그래밍 방식으로 액세스 할 수 있어도 뭔가 알아낼 수 있습니다.
2015 년 11 월부터 xUnit 2가 출시되었으므로 테스트간에 기능을 공유하는 표준 방법이 있습니다. 여기에 문서화되어 있습니다 .
기본적으로 픽스쳐를 수행하는 클래스를 만들어야합니다.
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
CollectionDefinition
속성이 있는 더미 클래스 입니다. 이 클래스는 Xunit이 테스트 컬렉션을 생성 할 수 있도록하며 컬렉션의 모든 테스트 클래스에 대해 주어진 조명기를 사용할 것입니다.
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
그런 다음 모든 테스트 클래스에 컬렉션 이름을 추가해야합니다. 테스트 클래스는 생성자를 통해 픽스처를받을 수 있습니다.
[Collection("Database collection")]
public class DatabaseTestClass1
{
DatabaseFixture fixture;
public DatabaseTestClass1(DatabaseFixture fixture)
{
this.fixture = fixture;
}
}
AssemblyInitialize
어떤 테스트 컬렉션이 속하는지 각 테스트 클래스에서 선언해야하기 때문에 MsTests보다 조금 더 장황 하지만 모듈화도 더 가능합니다.
참고 : 샘플은 설명서 에서 가져 왔습니다 .
정적 필드를 만들고 종료자를 구현합니다.
xUnit이 AppDomain을 만들어 테스트 어셈블리를 실행하고 완료되면 언로드한다는 사실을 사용할 수 있습니다. 앱 도메인을 언로드하면 종료자가 실행됩니다.
이 방법을 사용하여 IISExpress를 시작하고 중지합니다.
public sealed class ExampleFixture
{
public static ExampleFixture Current = new ExampleFixture();
private ExampleFixture()
{
// Run at start
}
~ExampleFixture()
{
Dispose();
}
public void Dispose()
{
GC.SuppressFinalize(this);
// Run at end
}
}
편집 : ExampleFixture.Current
테스트에서 사용하여 조명기에 액세스합니다 .
오늘날 프레임 워크에서는 불가능합니다. 이것은 2.0에 계획된 기능입니다.
2.0 이전에이 작업을 수행하려면 프레임 워크에서 중요한 재 아키텍처를 수행하거나 자신의 특수 속성을 인식하는 자체 러너를 작성해야합니다.
어셈블리 초기화에서 코드를 실행하려면 다음을 수행 할 수 있습니다 (xUnit 2.3.1로 테스트 됨).
using Xunit.Abstractions;
using Xunit.Sdk;
[assembly: Xunit.TestFramework("MyNamespace.MyClassName", "MyAssemblyName")]
namespace MyNamespace
{
public class MyClassName : XunitTestFramework
{
public MyClassName(IMessageSink messageSink)
:base(messageSink)
{
// Place initialization code here
}
public new void Dispose()
{
// Place tear down code here
base.Dispose();
}
}
}
https://github.com/xunit/samples.xunit/tree/master/AssemblyFixtureExample 도 참조하십시오.
내가 사용 AssemblyFixture ( NuGet을 ).
그것이하는 일은 테스트 어셈블리로서 개체의 수명을 원하는 곳을 IAssemblyFixture<T>
대체 하는 인터페이스를 제공 한다는 것입니다 IClassFixture<T>
.
예:
public class Singleton { }
public class TestClass1 : IAssemblyFixture<Singleton>
{
readonly Singletone _Singletone;
public TestClass1(Singleton singleton)
{
_Singleton = singleton;
}
[Fact]
public void Test1()
{
//use singleton
}
}
public class TestClass2 : IAssemblyFixture<Singleton>
{
readonly Singletone _Singletone;
public TestClass2(Singleton singleton)
{
//same singleton instance of TestClass1
_Singleton = singleton;
}
[Fact]
public void Test2()
{
//use singleton
}
}
빌드 도구가 이러한 기능을 제공합니까?
Java 세계에서 Maven 을 빌드 도구로 사용할 때 빌드 수명주기 의 적절한 단계를 사용합니다 . 예를 들어 귀하의 경우 (Selenium과 유사한 도구로 수용 테스트) pre-integration-test
및 post-integration-test
단계를 잘 사용 하여 웹 응용 프로그램 을 시작 / 중지 할 수 integration-test
있습니다.
귀하의 환경에 동일한 메커니즘을 설정할 수 있다고 확신합니다.
You can use IUseFixture interface to make this happen. Also all of your test must inherit TestBase class. You can also use OneTimeFixture directly from your test.
public class TestBase : IUseFixture<OneTimeFixture<ApplicationFixture>>
{
protected ApplicationFixture Application;
public void SetFixture(OneTimeFixture<ApplicationFixture> data)
{
this.Application = data.Fixture;
}
}
public class ApplicationFixture : IDisposable
{
public ApplicationFixture()
{
// This code run only one time
}
public void Dispose()
{
// Here is run only one time too
}
}
public class OneTimeFixture<TFixture> where TFixture : new()
{
// This value does not share between each generic type
private static readonly TFixture sharedFixture;
static OneTimeFixture()
{
// Constructor will call one time for each generic type
sharedFixture = new TFixture();
var disposable = sharedFixture as IDisposable;
if (disposable != null)
{
AppDomain.CurrentDomain.DomainUnload += (sender, args) => disposable.Dispose();
}
}
public OneTimeFixture()
{
this.Fixture = sharedFixture;
}
public TFixture Fixture { get; private set; }
}
EDIT: Fix the problem that new fixture create for each test class.
참고URL : https://stackoverflow.com/questions/13829737/run-code-once-before-and-after-all-tests-in-xunit-net
'Nice programing' 카테고리의 다른 글
JavaScript에 C #과 유사한 람다 구문이 있습니까? (0) | 2020.12.01 |
---|---|
Psql 출력에서 결과 집합 장식을 숨기는 방법 (0) | 2020.12.01 |
빈 행렬 곱셈을 통해 배열을 초기화하는 더 빠른 방법? (0) | 2020.12.01 |
Vim에 NERD Commenter를 사용하는 방법 — 사용 방법 (0) | 2020.12.01 |
NotifyIcon은 응용 프로그램을 닫은 후에도 트레이에 남아 있지만 마우스를 가리키면 사라집니다. (0) | 2020.12.01 |