12

我想运行使用 Azure 存储模拟器而不是来自 Azure DevOps 构建的真实存储的单元/集成测试。

模拟器安装在托管构建控制器上,作为 Azure SDK 的一部分,位于其通常的位置 (C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe)。

但是,模拟器在构建控制器上处于未初始化状态。尝试从命令行运行命令Init时,出现以下错误:

This operation requires an interactive window station

是否有已知的解决方法或计划在 Azure DevOps 构建中支持模拟器?

4

5 回答 5

19

尽管这里的所有答案都是相反的,但我已经在 VS2017 托管的构建代理上运行 Azure 存储模拟器一年多了。

诀窍是首先初始化 SQL LocalDB(模拟器使用它),然后启动模拟器。您可以使用运行的命令行任务来执行此操作:

sqllocaldb create MSSQLLocalDB
sqllocaldb start MSSQLLocalDB
sqllocaldb info MSSQLLocalDB

"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe" start
于 2018-08-07T11:54:18.480 回答
3

如前所述,您无法运行 Azure 存储模拟器。您可以运行的是Azurite一种开源替代方案。

请注意:Azurite 可以模拟 blob、表和队列。但是,我只以这种方式使用了 blob 存储仿真。

在构建配置开始时,添加一个运行自定义 nuget 命令的 nuget 步骤install Azurite -version 2.2.2。然后添加一个运行的命令行步骤start /b $(Build.SourcesDirectory)\Azurite.2.2.2\tools\blob.exe

它与 Azure 存储模拟器在同一端口上运行,因此您可以使用标准连接字符串。

于 2018-03-09T08:22:30.320 回答
1

不,Hosted Build Controller 不在交互模式下运行,因此模拟器无法在该环境下运行。有关详细信息,请参阅XAML 构建的托管构建控制器中的问答。

问:您需要以交互模式运行构建服务吗?

答:不。然后您可以使用托管的构建控制器。

我建议您设置本地构建控制器并在交互模式下运行构建服务器。有关详细信息,请参阅设置构建服务器设置构建控制器

于 2015-11-16T06:09:51.700 回答
1

似乎答案可能来自 Visual Studio Online 方面。如果有人有类似的问题,有一个用户语音条目。

不太确定为什么模拟器没有非交互模式,我个人 99% 的时间都不使用它的 UI。有一个通用的用户语音条目可让 Azure 存储更易于单元测试。

于 2015-11-19T18:43:07.567 回答
1

如果您想直接在 C# 的集成测试代码中启动 Azure 存储模拟器,您可以将其放入您的测试初始化​​(启动)代码中(示例适用于 xUnit):

[Collection("Database collection")]
public sealed class IntegrationTests
{
    public IntegrationTests(DatabaseFixture fixture)
    {
        this.fixture = fixture;
    }

    [Fact]
    public async Task TestMethod1()
    {
        // use fixture.Table to run tests on the Azure Storage
    }

    private readonly DatabaseFixture fixture;
}

public class DatabaseFixture : IDisposable
{
    public DatabaseFixture()
    {
        StartProcess("SqlLocalDB.exe", "create MSSQLLocalDB");
        StartProcess("SqlLocalDB.exe", "start MSSQLLocalDB");
        StartProcess("SqlLocalDB.exe", "info MSSQLLocalDB");
        StartProcess(EXE_PATH, "start");

        var client = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient();
        Table = client.GetTableReference("tablename");
        InitAsync().Wait();
    }

    public void Dispose()
    {
        Table.DeleteIfExistsAsync().Wait();
        StartProcess(EXE_PATH, "stop");
    }

    private async Task InitAsync()
    {
        await Table.DeleteIfExistsAsync();
        await Table.CreateAsync();
    }

    static void StartProcess(string path, string arguments, int waitTime = WAIT_FOR_EXIT) => 
        Process.Start(path, arguments).WaitForExit(waitTime);

    public CloudTable Table { get; }

    private const string EXE_PATH = 
    "C:\\Program Files (x86)\\Microsoft SDKs\\Azure\\Storage Emulator\\AzureStorageEmulator.exe";
    private const int WAIT_FOR_EXIT = 60_000;
}

[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.
}
于 2020-05-07T21:32:11.160 回答