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; }
现存在两个问题:
- 如何修改循环逻辑,使列表中每个物料编码与对应日期正确匹配,仅生成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
相关产品推荐
相关产品推荐

