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

如何使用Selenium C#编写Dynamics 365 CRM通用文件上传测试

实现通用的Dynamics 365 CRM文件上传测试(Selenium C#)

问题描述

我正在用Selenium C#编写Microsoft Dynamics 365 CRM的测试用例,需要实现文件浏览与上传的测试功能,希望代码具备通用性,让任何人无需使用我的本地文件路径即可运行该代码。

现有代码

ContactPage.cs

public ContactsPage UploadDocumentContact(string iRType)
{
    WaitUntilElementIsVisible(uploadDocuments);
    Click(uploadDocuments);
    Wait(10);
    WaitUntilElementIsVisible(dontAllow_btn);
    Click(dontAllow_btn);
    WaitUntilElementIsVisible(browse_btn);
    Click(browse_btn);

    return this;
}

UploadDocumentSteps.cs

[When(@"Upload document from ""([^""]*)""")]
public void WhenCreateIllustrationRequestFrom(string IRType)
{
    switch (IRType.ToUpper())
    {
        case Data.Accounts:
            accountsPage = new AccountsPage(driver).OpenIRAccount();
            break;
        case Data.Investor:
            contactsPage = new ContactsPage(driver).OpenInvestorContact();
            break;
        case Data.Locations:
            locationsPage = new LocationsPage(driver).OpenExistingLocation();
            break;
        case Data.Cases:
            casesPage = new CasesPage(driver).SearchForCase();
            break;
            throw new Exception($"{IRType} type is not found...");
    }

    accountsPage = new AccountsPage(driver).UploadDocumentAccount(IRType);
    contactsPage = new ContactsPage(driver).UploadDocumentContact(IRType);
    locationsPage = new LocationsPage(driver).UploadDocumentLocation(IRType);
    casesPage = new CasesPage(driver).UploadDocumentCase(IRType);
}

Feature文件

Scenario Outline: Verify Upload Document
    Given User navigates to CRM application with valid credentials
    When User navigates to "<page>" page
    And Upload document from "<IRType>"
    Then Document should be Uploaded successfully
 
    Examples: 
    | page          | IRType        |
    | Accounts      | Accounts      |
    | Contacts      | Investor      |
    | Locations     | Locations     |
    | Cases         | Cases         |

解决方案

核心思路

  1. 使用嵌入式资源文件:将测试用文件嵌入到项目中,编译后随程序集分发,无需依赖本地路径。
  2. 绕过系统文件对话框:直接通过Selenium的SendKeys给文件输入框传递路径,避免系统级对话框的兼容性问题。
  3. 重构代码减少冗余:提取通用逻辑,避免重复实例化页面和执行无效操作。

具体实现步骤

1. 添加嵌入式测试文件

  • 将测试用文件(如TestDocument.pdf)添加到项目中(可创建Resources文件夹统一存放)。
  • 右键文件 → 属性 → 设置“生成操作”为嵌入的资源。

2. 编写文件上传辅助类

创建FileUploadHelper.cs,用于从嵌入式资源提取临时文件路径:

using System;
using System.IO;
using System.Reflection;

public static class FileUploadHelper
{
    public static string GetEmbeddedTestFilePath(string resourceFullName)
    {
        var assembly = Assembly.GetExecutingAssembly();
        using (var resourceStream = assembly.GetManifestResourceStream(resourceFullName))
        {
            if (resourceStream == null)
                throw new FileNotFoundException($"未找到嵌入式资源:{resourceFullName}");

            // 生成临时文件路径
            var tempFileName = $"{Guid.NewGuid()}{Path.GetExtension(resourceFullName)}";
            var tempFilePath = Path.Combine(Path.GetTempPath(), tempFileName);

            // 将嵌入式资源写入临时文件
            using (var fileStream = new FileStream(tempFilePath, FileMode.Create))
            {
                resourceStream.CopyTo(fileStream);
            }

            return tempFilePath;
        }
    }
}

3. 修改页面上传逻辑(以ContactPage为例)

去掉点击浏览按钮的操作,直接定位文件输入框并传入临时文件路径:

public ContactsPage UploadDocumentContact(string iRType)
{
    WaitUntilElementIsVisible(uploadDocuments);
    Click(uploadDocuments);
    WaitUntilElementIsVisible(dontAllow_btn);
    Click(dontAllow_btn);

    // 定位Dynamics 365的文件上传输入框(需根据实际页面调整选择器)
    var fileInputElement = driver.FindElement(By.CssSelector("input[type='file']"));
    
    // 获取嵌入式测试文件路径(替换为你的命名空间+文件路径)
    var testFilePath = FileUploadHelper.GetEmbeddedTestFilePath("CRMTest.Resources.TestDocument.pdf");
    
    // 直接传入路径,绕过系统对话框
    fileInputElement.SendKeys(testFilePath);

    // 等待上传完成(根据页面实际的成功提示元素调整)
    WaitUntilElementIsVisible(uploadSuccessIndicator);

    // 可选:测试完成后删除临时文件
    File.Delete(testFilePath);

    return this;
}

4. 重构步骤代码

修正UploadDocumentSteps.cs中的冗余操作,每个分支仅处理对应页面:

[When(@"Upload document from ""([^""]*)""")]
public void WhenCreateIllustrationRequestFrom(string IRType)
{
    switch (IRType.ToUpper())
    {
        case Data.Accounts:
            accountsPage = new AccountsPage(driver).OpenIRAccount();
            accountsPage.UploadDocumentAccount(IRType);
            break;
        case Data.Investor:
            contactsPage = new ContactsPage(driver).OpenInvestorContact();
            contactsPage.UploadDocumentContact(IRType);
            break;
        case Data.Locations:
            locationsPage = new LocationsPage(driver).OpenExistingLocation();
            locationsPage.UploadDocumentLocation(IRType);
            break;
        case Data.Cases:
            casesPage = new CasesPage(driver).SearchForCase();
            casesPage.UploadDocumentCase(IRType);
            break;
        default:
            throw new Exception($"{IRType} 类型未找到...");
    }
}

注意事项

  • 嵌入式资源名称:需确保resourceFullName是项目命名空间+文件所在路径+文件名,例如CRMTest.Resources.TestDocument.pdf。
  • 元素定位:Dynamics 365的文件输入框可能隐藏,若SendKeys无效,可先通过JavaScript设置元素可见:
    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    js.ExecuteScript("arguments[0].style.display = 'block';", fileInputElement);
    
  • 临时文件清理:建议在测试的[AfterScenario]钩子中统一清理临时文件,避免磁盘占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:58:10