当集合的固定装置抛出异常时,如何使集合失败?
我目前正在为成熟的 ASP.NET 应用程序编写一套集成测试。 作为应用程序支持服务的一部分,它使用 Azure blob 存储容器,我需要在运行测试之前确保该容器可访问且存在。我想添加实际上等于检查为应用程序配置的 Azure blob 容器(无论是在本地模拟器上还是在 CI 中运行时的 Azure 本身)是否已启动并准备好处理测试套件发出的请求。如果后端无法访问,大量测试将直接失败,并且由于 Azure 库会等待多次超时,因此需要几分钟时间才会失败。
当在集合固定装置中抛出或断言时,它似乎实际上并没有阻止集合中的任何测试运行,固定装置异常也不会出现在结果日志中。
如果在实例化过程中任何相关的固定装置抛出异常,是否有办法阻止测试运行?
我当前的代码如下:
夹具
using Azure.Storage.Blobs;
using Newtonsoft.Json.Linq;
using System.IO;
using Xunit;
namespace product.test.integration
{
/// <summary>
/// This fixture ensures the configured azure blob container used by the FileStorage system is accessible.
/// A concern mostly in local environments where the Azurite emulator may not be running, but also can alert to a misconfigured testing environment.
/// </summary>
public class FileStorageFixture
{
public FileStorageFixture()
{
//get the configuration
string appdataLocation = Path.Combine(Directory.GetCurrentDirectory(), "testappsettings.json");
string appdataContent = File.ReadAllText(appdataLocation);
var json = JObject.Parse(appdataContent);
string connectionString = json["Settings"]["FileStorage"]["AzureStorageKey"].Value<string>();
string containerName = json["Settings"]["FileStorage"]["ContainerName"].Value<string>();
//check if the container exists
var container = new BlobContainerClient(connectionString, containerName);
try
{
Assert.True(container.Exists()); //this line will throw if a timeout occurs
} catch
{
throw new System.Exception("Configured FileStorage backend is not accessible!");
}
}
}
}
所有测试扩展的基测试类(IntegrationTest)以及包含它们的集合:
//...
[CollectionDefinition("Integration Tests", DisableParallelization = true)]
public class IntegrationTestCollection :
//...
ICollectionFixture<FileStorageFixture> { }
[Collection("Integration Tests")]
public abstract class IntegrationTest : IClassFixture<WebApplicationFactory<product.api.Startup>>
{
//...
I'm currently writing a suite of integration tests for a mature ASP.NET application.
As part of the application's supporting services, it uses an Azure blob storage container which I need to make sure is accessible and existing prior to running the tests. I want to add what effectively amounts to a check that the configured Azure blob container for the application (be it on the local emulator or Azure itself when running in CI) is up and ready to handle the requests made by the test suite. A large amount of the tests will straight up fail if the backend is inaccessible and they take several minutes to fail as the Azure library waits through several timeouts.
When throwing or asserting in a collection fixture, it doesn't seem to actually prevent any test in the collection from running nor does the fixture exception appear in the resulting logs.
Is there a way to prevent tests from running if any of their associated fixtures throw during instantiation?
My current code is as follows:
The fixture
using Azure.Storage.Blobs;
using Newtonsoft.Json.Linq;
using System.IO;
using Xunit;
namespace product.test.integration
{
/// <summary>
/// This fixture ensures the configured azure blob container used by the FileStorage system is accessible.
/// A concern mostly in local environments where the Azurite emulator may not be running, but also can alert to a misconfigured testing environment.
/// </summary>
public class FileStorageFixture
{
public FileStorageFixture()
{
//get the configuration
string appdataLocation = Path.Combine(Directory.GetCurrentDirectory(), "testappsettings.json");
string appdataContent = File.ReadAllText(appdataLocation);
var json = JObject.Parse(appdataContent);
string connectionString = json["Settings"]["FileStorage"]["AzureStorageKey"].Value<string>();
string containerName = json["Settings"]["FileStorage"]["ContainerName"].Value<string>();
//check if the container exists
var container = new BlobContainerClient(connectionString, containerName);
try
{
Assert.True(container.Exists()); //this line will throw if a timeout occurs
} catch
{
throw new System.Exception("Configured FileStorage backend is not accessible!");
}
}
}
}
The base test class (IntegrationTest) which all tests extend, and the collection that contains them:
//...
[CollectionDefinition("Integration Tests", DisableParallelization = true)]
public class IntegrationTestCollection :
//...
ICollectionFixture<FileStorageFixture> { }
[Collection("Integration Tests")]
public abstract class IntegrationTest : IClassFixture<WebApplicationFactory<product.api.Startup>>
{
//...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实现您想要的目的的一种方法是让夹具在初始化不成功时设置一个标志,并在基测试类的构造函数中查询该标志。
在
FileStorageFixture
中添加标志作为属性,并根据初始化是否成功设置该属性
如果将其余代码包含在
FileStorageFixture
中,会更加可靠try
中的构造函数,因为任何地方的异常也会导致测试失败。我假设对固定装置的引用作为参数提供给
IntegrationTest
的构造函数,因此如果固定装置未正确初始化,您应该在那里抛出异常:没有
IntegrationTest 对象,它的任何测试都不会运行。
One way to accomplish what you desire is to have the fixture set a flag if its initialization was not successful and query the flag in the constructor of your base test class.
In
FileStorageFixture
add the flag as a propertyand set the property depending on whether the initialization was successful
It would be even more reliable if you included the rest of the code in the
FileStorageFixture
constructor inside thetry
, since an exception anywhere there would also bring your tests down.I assume the reference to the fixture is being provided as a parameter to the constructor of
IntegrationTest
, so you should throw an exception there if the fixture wasn't initialized properly:Without the
IntegrationTest
object, none of its tests will run.