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

Selenium C#自动化测试:列表对象匹配与排序问题

问题描述

我正在使用C#和Selenium开发自动化测试,测试的Web应用页面包含Item Code(物料编码)及其对应的Next Available Dates(下次可用日期)。我需要将指定的Item Code(A7030、A4604)与对应日期存入列表,以便后续断言日期计算是否正确。

已声明以下Web元素列表:

private IList<IWebElement> ItemNextAvailableDates => Driver.FindElements(By.XPath("//*[contains(@id, 'ctl00_ctl00_c_c_rgItems_ctl00')]/td[4]"));

private IList<IWebElement> ItemProcCodes => Driver.FindElements(By.XPath("//*[contains(@id, 'ctl00_ctl00_c_c_rgItems_ctl00')]/td[1]"));

并创建了ProcCodesDates类来存储物料编码和对应日期:

public class ProcCodesDates
{
    public string ProcCodeDate { get; set; }
    public string ProcCode { get; set; }
}

预期列表中仅包含2个对象,但编写的GetItemProcCodeAndNextAvilableDates方法使用嵌套循环后,生成了4个对象,而非预期的对应匹配结果。当前方法代码如下:

public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
    List<ProcCodesDates> listOfProcCodesDates = new List<ProcCodesDates>();

    foreach (var x in ItemNextAvailableDates)
    {
        foreach (var y in ItemProcCodes)
        {
            listOfProcCodesDates.Add(item: new ProcCodesDates { ProcCodeDate = x.GetValue(), ProcCode = y.GetValue() });
        }
    }

    listik = listOfProcCodesDates;
    return this;
} 

现存在两个问题:

  1. 如何修改循环逻辑,使列表中每个物料编码与对应日期正确匹配,仅生成2个对象?
  2. 如何对返回的列表调用.Sort()方法,使其按Item Code进行升序或降序排序?

解决方案

1. 修正循环逻辑,匹配对应物料编码和日期

嵌套循环会把每个日期和每个物料编码强制组合,导致生成N*M个对象,这是错误的。正确逻辑是按相同索引位置配对物料编码和日期,同时过滤出指定的两个编码:

方法一:for循环按索引遍历

public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
    List<ProcCodesDates> listOfProcCodesDates = new List<ProcCodesDates>();
    // 取两个列表的最小长度,避免索引越界
    int count = Math.Min(ItemNextAvailableDates.Count, ItemProcCodes.Count);
    
    for (int i = 0; i < count; i++)
    {
        string currentProcCode = ItemProcCodes[i].GetValue();
        // 只保留目标物料编码
        if (currentProcCode == "A7030" || currentProcCode == "A4604")
        {
            listOfProcCodesDates.Add(new ProcCodesDates 
            { 
                ProcCode = currentProcCode, 
                ProcCodeDate = ItemNextAvailableDates[i].GetValue() 
            });
        }
    }

    listik = listOfProcCodesDates;
    return this;
} 

方法二:LINQ Zip方法配对(更简洁)

如果两个列表长度一致,用Zip可直接将对应位置元素配对,再过滤目标编码:

using System.Linq; // 需引入LINQ命名空间

public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
    var targetProcCodes = new HashSet<string> { "A7030", "A4604" };
    
    var listOfProcCodesDates = ItemProcCodes.Zip(ItemNextAvailableDates, (codeElem, dateElem) => new ProcCodesDates
    {
        ProcCode = codeElem.GetValue(),
        ProcCodeDate = dateElem.GetValue()
    })
    .Where(item => targetProcCodes.Contains(item.ProcCode))
    .ToList();

    listik = listOfProcCodesDates;
    return this;
} 

2. 按Item Code排序列表

有两种方式实现排序,按需选择:

方式一:实现IComparable接口(全局默认排序)

修改ProcCodesDates类,实现IComparable<ProcCodesDates>接口,之后可直接调用.Sort():

public class ProcCodesDates : IComparable<ProcCodesDates>
{
    public string ProcCodeDate { get; set; }
    public string ProcCode { get; set; }

    // 升序排序逻辑
    public int CompareTo(ProcCodesDates other)
    {
        if (other == null) return 1;
        return string.Compare(this.ProcCode, other.ProcCode, StringComparison.Ordinal);
    }
}

使用示例:

listik.Sort(); // 默认升序
listik.Sort((x, y) => y.CompareTo(x)); // 降序,反转升序逻辑

方式二:传入自定义比较器(临时排序逻辑)

无需修改类,直接在调用Sort时传入比较逻辑:

// 升序排序
listik.Sort((a, b) => string.Compare(a.ProcCode, b.ProcCode, StringComparison.Ordinal));

// 降序排序
listik.Sort((a, b) => string.Compare(b.ProcCode, a.ProcCode, StringComparison.Ordinal));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:29:57