SpecFlow 上下文注入线程安全吗?

Is SpecFlow Context Injection Thread Safe?

我正在使用 SpecFlow 为 API 集成测试工具提供支持,它将提供新 UI API 的实时文档和测试范围。我编写了一些功能文件,最终达到了我尝试 运行 并行进行大约 60 个测试的地步。然而,虽然我可以 运行 单独地 运行 这些功能没有问题,但我 运行 在尝试使用 Visual Studio 2019 测试 运行 并行 运行 它们时遇到间歇性故障]ner 和 XUnit 运行ner 插件。

任何给定的 SpecFlow 场景都将利用来自两个不同步骤绑定 classes 的步骤,并且每个步骤绑定 classes 可能需要注入最多三个旨在捕获的上下文对象场景期间的状态并在场景完成后清理环境。例如,功能可能如下所示:

Scenario: Retrieving Message records returns data
Given I have created the following ClientAccounts:
    | Index | SiteID | IsActive |
    | 1     | 1      | 1        |
And I have created the following Logins:
    | Index | IsActive |
    | 1     | 1        |
And I have created the following Messages:
    | MessageID | MessageText |
    | 1         | Asdfasdf    |
When I send an authentication request using the first Login and the IP Address 127.0.0.1
And I send a read request to the v1 Message endpoint for the first Message record created:
Then the first Message response should be equivalent to the following data for the first Message record created:
    | MessageTest |
    | Asdfasdf    |

前三个步骤属于一个名为 DatabaseSteps 的 class ,其构造函数接受一个 class DataUtility 的实例,该实例有助于 CRUD 操作 to/from 数据库并跟踪记录的内容作为测试执行的一部分创建。还有一些 [StepArgumentTransformation] 绑定将这些表转换为可以插入到数据库中的数据库对象。

第四步、第五步和第六步属于附加步骤 classes,其构造函数将用于数据库访问的 DataUtility 和存储会话信息以及有关 [=27 的信息的 ApiClientContext 作为依赖项=] 先前已保存的响应,以便根据“Then”阶段获得的实际响应进行断言。 DataUtility class 实现 IDisposable 以简化 post-测试清理。

基于documentation,我预计通过内置 DI 容器注入的上下文 classes 是线程安全的。但是,我发现无论是使用 DataUtility 实现 IDisposable 还是通过不声明接口并直接从 [AfterScenario] 挂钩直接调用 Dispose(),在大多数测试 运行 期间,与预期返回数据有关的测试都会失败.很难肯定地说,因为解决并发问题很糟糕,但似乎 DataUtility 实例正在场景之间共享,并且当任何给定场景在数据实用程序上调用 Dispose() 时,我搭建的所有测试数据都是清除 - 即使在其他不相关的情况下也是如此。当我既没有在 DataUtility class 上声明 IDisposable 也没有从挂钩调用 Dispose() 时,测试执行时没有发生意外。有没有一种特殊的方法我需要设置一个注入的上下文 class 以便每个场景都有它自己的 class 实例?

其他详细信息:VS2019、SpecFlow 3、XUnit 测试运行器

我昨天和今天花了很多时间深入研究这个问题,在我的 DAL 中添加了日志记录,以弄清楚在数据库中创建和删除对象时做了什么,最终在我的辅助库中发现了一个非常狡猾的错误正在与 Dapper 一起使用;它选择了一个名称以 GUID 结尾的字段,并在 auto-built 删除查询中使用它,而不是使用实际的 ID 字段。由于我用于数据库的对象库是与产品团队共享的,所以我无法用我自己的属性来装饰它,并且愚蠢地解决了这个问题。感谢@GregBurghardt 的帮助!