【问题标题】:TempData Empty on Redirect During SpecFlow Tests Only仅在 SpecFlow 测试期间重定向时 TempData 为空
【发布时间】:2020-01-03 01:06:05
【问题描述】:

我正在使用 SpecFlow、Selenium 和 ChromeDriver 测试一个 .Net Core 2.2 Web 应用程序,但遇到的一些事情让我很困惑。

我正在使用 TempData 在发布数据的页面和显示数据的页面之间传递警报消息的数据。当在本地部署到 IIS 以进行调试等时,我会看到 TempData,直到它被使用并作为格式化消息显示在页面上。但是,我在 SpecFlow 场景中有一个步骤,当由于 TempData 为空而未显示警报时失败。 SpecFlow 场景遵循手动测试期间所采取的相同步骤。

我正在通过引用的 XUnit/Specflow 测试项目测试 .Net Core 2.2 Web 项目。使用了以下相关依赖:

  • Microsoft.NetCore.App v2.2.0
  • SpecFlow v3.0.225
  • SpecFlow.xUnit v3.0.225
  • Selenium.WebDriver v3.141.0
  • Selenium.WebDriver.ChromeDriver v76.0.3809.12600

我已确认在本地调试应用程序时,TempData 已按预期填充消息数据。调试测试显示 TempData 在成功发布表单数据时填充,但在重定向期间处理生成的 OnGet 时为空。

这是添加帐户的帖子处理程序:

public async Task<IActionResult> OnPostAsync()
{
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Account.UserName, Email = Account.EmailAddress };
        var result = await _userManager.CreateAsync(user);

        if (result.Succeeded)
        {

            Dictionary<string, string> SuccessAlert = new Dictionary<string, string>()
            {
                { "Type", "success" },
                { "Title", "Account Added" },
                { "Text",  "Account for user " + Account.UserName + " was added successfully."}
            };

            TempData["Alert"] = SuccessAlert;

            _logger.LogInformation($"account added successfully. Alert title: {SuccessAlert["Title"]}");

            return RedirectToPage("/Accounts/Index", new
            {
                area = "Administration"
            });
        }

        foreach (var error in result.Errors)
        {
            ModelState.AddModelError("", error.Description);
        }

    }

    Dictionary<string, string> ErrorAlert = new Dictionary<string, string>()
            {
                { "Type", "error" },
                { "Title", "Uh-oh!" },
                { "Text",  "Account for user " + Account.UserName + " was not added. See errors below."}
            };

    TempData["Alert"] = ErrorAlert;

    return Page();
}

以及上述成功完成后重定向到的 /Accounts/Index 页面的 get 处理程序(非常基本):

public void OnGet()
{
    Accounts = _accountService.FindAll();
    _logger.LogInformation("AccountsIndexModel.OnGet");
    _logger.LogInformation($"Items in TempData: {TempData.Count}");
}

以下是上面代码中的日志记录对应的日志文件中的sn-ps。

手动添加帐户的日志:

2019-08-28 16:18:53.917 -04:00 First.Web.Areas.Administration.Accounts.AddAccountModel [Information] account added successfully. Alert title: Account Added
2019-08-28 16:19:08.587 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] AccountsIndexModel.OnGet
2019-08-28 16:19:08.588 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] Items in TempData: 1

对于 SpecFlow 自动化测试:

2019-08-28 17:19:02.014 -04:00 First.Web.Areas.Administration.Accounts.AddAccountModel [Information] account added successfully. Alert title: Account Added
2019-08-28 17:19:02.105 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] AccountsIndexModel.OnGet
2019-08-28 17:19:02.105 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] Items in TempData: 0

这是 SpecFlow 场景:

Scenario: Add new account succeeds
    Given I have access to the "Administration" module
    When I navigate to the "Add Account" page
        And I submit an account with values
            | accountname | emailaddress         |
            | mcullen     | mcullen@mnhockey.com |
    Then I should be on the "Accounts" page
        And I should see a success message with
            | title         | description      |
            | Account Added | Account for user |

以及账户提交步骤的步骤定义:

[When(@"I submit an account with values")]
public void WhenISubmitAnAccountWithValues(Table table)
{
    var accountName = "";
    var emailAddress = "";

    var row = table.Rows[0];

    row.TryGetValue("accountname", out accountName);
    row.TryGetValue("emailaddress", out emailAddress);

    _accountsAddPage.AccountNameField.SendKeys(accountName);
    _accountsAddPage.EmailAddressField.SendKeys(emailAddress);

    _accountsIndexPage = _accountsAddPage.Submit();

    _context.Set<string>("Accounts", "currentpage");
}

【问题讨论】:

  • 您确定_accountsAdPage.Submit() 方法正在提交您认为的页面吗?
  • 嗨,格雷格。是因为我调试过测试看到了,数据库反映了新提交的数据。

标签: asp.net-mvc testing specflow razor-pages


【解决方案1】:

在对我的问题进行更多故障排除时,我观察到 ChromeDriver 打开的浏览器未在响应标头中发送 .AspNetCore.Mvc.CookieTempDataProvider cookie。

为了解决这个问题,我在 Startup.cs 中添加了以下配置:

services.Configure<CookieTempDataProviderOptions>(options =>
{
    options.Cookie.IsEssential = true;
});

或者,也可以省略上述代码,将非必要 cookie 的 CheckConsentNeeded 更改为 false:

services.Configure<CookiePolicyOptions>(options =>
{
    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
    options.CheckConsentNeeded = context => false;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

这是基于找到的文档here。因为我的项目是针对内网站点的,所以我没有使用CookiePolicyMiddleware,上面的解决方案是合适的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-06
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多