0

我有一个旧的 ASP.NET 4.0 WebForms 应用程序,我想为其构建一些端到端测试。我使用 Specflow 创建测试并使用 Selenium WebDriver 编写 Firefox 脚本。

该应用程序使用简单的 ADO.NET 来访问 DB (MS SQL Server 2008 R2 SP1)。

我想实现测试隔离,所以我希望在测试结束时删除一个测试在数据库中写入的所有内容,因此我使用以下方法:

        [BeforeScenario]
        public void ScenarioSetup()
        {

            Scope = new TransactionScope(TransactionScopeOption.RequiresNew,
                                         new TransactionOptions {IsolationLevel =    IsolationLevel.ReadUncommitted});
            Browser.CreateNew();
        }

        [AfterScenario]
        public void ScenarioCleanup()
        {
            if (Scope != null)
            {
                Scope.Dispose();
            }
            Browser.Close();
        }

所以打开一个事务范围并在最后处理它。

Given块中,我打开一个 EF5 DbContext 并编写一些设置数据:

  public void GivenIHaveAccountsWithDifferentStatusesInTheSystem()
    {
        using (var ctx = new WorkflowImprovementsContext())
        {
            try
            {
                _contact = new Contact()
                {
                    created = new DateTime(2010, 1, 18),
                    countryId = 1,
                    stateId = 1,
                    contactName = "Account Contact Name One",
                    companyName = "Company Company Account One",
                    address1 = "Address 1 One",
                    address2 = "Address 2 One",
                    city = "City Account One",
                    email = "Email Account One",
                    zipCode = "A123",
                    phone = "0735352244",
                    mobile = "0735352244",
                    pager = "0735352244",
                    fax = "0735352244",
                    webSite = "www.test.com"
                };
                ctx.Contacts.Add(_contact);

                ctx.SaveChanges();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }

        }

请注意上下文在使用后被释放。

我使用 ReSharper 测试运行程序运行我的 specflow 测试。在测试的“何时”步骤中的某个时间点启动 Firefox(单独的进程)并将浏览器编写脚本以转到通过 AJAX 调用读取刚刚放入数据库中的数据的页面。

这就是我卡住的地方,AJAX 调用不会返回(它背后的 Web 服务中的代码等待 DB 访问),直到我处理掉 TransactionScope。

为什么 Firefox 进程中的应用程序无法读取从 test runner 进程中写入的数据?(TS 是 ReadUncommitted,我尝试了所有其他但仍然没有运气)

我不能更早地处理范围,因为这会破坏目的,我需要稍后在读取数据后进行断言,然后处理 TS 并随之回滚 DB 中的数据。

4

1 回答 1

1

听起来您正试图在打开的事务中在数据库中创建数据,并在事务仍处于打开状态且未提交时从不同进程中的不同事务中读取相同的数据。这不适用于事务范围的默认隔离级别。除非您在应用程序中使用 ReadUncommitted 或在应用程序的查询中使用 nolock 提示,否则在事务提交之前您将无法读取该信息。

您可能不想让您的应用程序读取未提交的数据——这就是关系数据库遵循 ACID 属性并使用事务的原因。如果您可以读取未提交的信息,那么您的应用程序中可能会发生不好的事情。这对您的应用程序来说可能没问题 - 但如果这不是您正在做的事情,因为您的应用程序应该这样做,我不建议只为了测试而这样做。

无论如何,我从来都不喜欢使用事务来删除测试中的数据的想法——似乎以一种他们并非真正意图和混乱的方式使用事务。最好在单个进程中完成所有测试设置和拆卸以及应用程序代码的执行在单个事务中,但即使在那里我也不会对此感到疯狂。

真的,你可能想多了,让这太难了。如果您想要的是在执行被测操作之前创建数据并在之后删除它们,也许您应该做最简单的事情,只需在之前添加和之后删除。我更不喜欢你正在做的事情,因为你实际上是在跨进程边界打应用程序。

于 2013-07-27T18:50:23.870 回答