You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Microsoft.VisualStudio集成测试中触发网页按钮点击

问题

后端已通过单元测试充分验证,现需通过集成测试整合所有功能。我找到很多获取页面的示例,但没有执行页面功能的相关内容。我有一个标准HTML‘Scan’页面,包含如下下载按钮:

<li><img src="~/img/download.png" style="height: 1.5em; width: inherit; margin-right: 8px" /><a id="download-btn" href="#">Download</a></li>

点击该按钮可下载PDF,功能正常。对应的JavaScript代码如下:

$('#download-btn').click(function () { 
var qrKey = 'c40rj8f'; // Replace with your actual QRKey value

$.ajax({
    url: '/api/Scans/Download',
    method: 'GET',
    xhrFields: {
        responseType: 'blob'
    },
    data: { QRKey: qrKey },
    responseType: 'arraybuffer', // Important for handling binary data
    success: function (response) {
    .... 
});

现在我需要在Microsoft.VisualStudio.TestTools.UnitTesting集成测试中验证该功能。结合资料写出了如下测试代码,但返回400错误:

[TestMethod]
public async Task ScanDownloadTest()
{
    // get page content
    var page = await httpClient.GetAsync("Scan");
    Assert.AreEqual(HttpStatusCode.OK, page.StatusCode);
    string resultContent = page.Content.ReadAsStringAsync().Result;
    // load the page into an HtmlDocument 
    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(resultContent);
    var downloadBtn = htmlDoc.GetElementbyId("download-btn");
    // execute downloadBtn button click 
    var request = new HttpRequestMessage(HttpMethod.Post, "Scan");
    var content = new StringContent($"{{\"id\":1,\"method\":\"Runtime.evaluate\",\"params\":{{\"expression\":\"document.getElementById('{downloadBtn.Id}').click();\",\"returnByValue\":true}}}}");
    request.Content = content;
    var response = await httpClient.SendAsync(request); // returns 400 (Bad Request)
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    Assert.IsNotNull(response.Content.Headers.ContentType);
    Assert.AreEqual("application/octet-stream", response.Content.Headers.ContentType.MediaType);
}

请问如何解决该问题,让集成测试能正确触发按钮点击并验证下载功能?

解决方案

方案1:直接调用后端API(推荐,高效简洁)

按钮点击的本质是触发了一个携带QRKey参数的GET请求到/api/Scans/Download,没必要模拟前端点击,直接调用这个API即可完成集成测试:

[TestMethod]
public async Task ScanDownloadTest()
{
    // 模拟按钮点击后的AJAX请求,直接调用后端API
    var qrKey = "c40rj8f"; 
    var requestUrl = $"/api/Scans/Download?QRKey={Uri.EscapeDataString(qrKey)}";
    var response = await httpClient.GetAsync(requestUrl);

    // 验证响应状态
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    
    // 验证响应内容类型(PDF通常为application/pdf,根据后端实际返回调整)
    Assert.IsNotNull(response.Content.Headers.ContentType);
    Assert.AreEqual("application/pdf", response.Content.Headers.ContentType.MediaType);
    
    // 可选:验证返回的是有效二进制数据
    var contentBytes = await response.Content.ReadAsByteArrayAsync();
    Assert.IsTrue(contentBytes.Length > 0);
}

补充说明

  • 集成测试核心是验证后端逻辑,直接调用API可避免前端环境依赖,测试效率更高。
  • 如果QRKey需要从页面动态获取,可保留原代码中解析HTML的部分,从页面的隐藏域或其他元素中提取真实值。

方案2:用UI测试工具模拟真实点击(端到端测试场景)

如果必须模拟真实用户的点击行为,需使用Selenium这类UI自动化工具,而非直接用HttpClient:

  1. 安装相关NuGet包:Selenium.WebDriver、对应浏览器驱动包(如Selenium.WebDriver.ChromeDriver)
  2. 编写测试代码:
[TestMethod]
public void ScanDownloadTestWithSelenium()
{
    // 初始化Chrome驱动
    using var driver = new ChromeDriver();
    
    // 打开目标页面
    driver.Navigate().GoToUrl("http://your-test-server/Scan");
    
    // 找到下载按钮并触发点击
    var downloadBtn = driver.FindElement(By.Id("download-btn"));
    downloadBtn.Click();
    
    // 验证下载结果(检查浏览器默认下载目录)
    var downloadPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
    var downloadedPdfs = Directory.GetFiles(downloadPath, "*.pdf");
    Assert.IsTrue(downloadedPdfs.Any());
}

补充说明

  • 该方式更贴近真实用户操作,但需配置浏览器环境,测试速度较慢,适合端到端验收测试。
  • 需提前设置浏览器下载行为(如禁用弹窗、指定固定下载目录),避免测试被阻塞。

原代码错误原因

你之前的代码试图发送Chrome DevTools协议的Runtime.evaluate命令到普通Web服务器,但你的后端服务并不处理这类协议请求,因此返回400错误。这类命令仅Chrome浏览器的调试端口会响应,普通Web接口不支持。

内容的提问来源于stack exchange,提问作者BWhite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:22:47