我开发了 Selenium 自动化测试(C#、Selenium)。
我有一个 Web 应用程序,其中包含与网页上的商品代码相对应的商品代码和下一个可用日期:
我需要将项目代码(A7030 和 A4604 )值和日期(参见屏幕截图)相应添加到列表中,以便我可以在接下来的步骤中断言相应项目的日期计算正确。
所以,我声明了网页元素列表:
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]"));
我创建了班级:
public class ProcCodesDates
{
public string ProcCodeDate { get; set; }
public string ProcCode { get; set; }
}
该类允许在一个对象中包含项目代码和日期。
所以,现在我可以将此类的对象添加到列表中。
顺便说一句,我的列表应该只有 2 个对象。
然后我创建了 GetItemProcCodeAndNextAvilableDates() 方法,它将创建的类的对象(见上文)添加到列表中,并返回 ProcCodesDates 类的对象列表。方法是:
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(两)条记录,我有 4 条记录:
我希望得到的清单如下:
如何让我的列表返回正确的值,换句话说,在循环中将项目添加到列表中的算法是什么,以便他们添加每个代码与相应的日期?
如何使用方法“.Sort()”应用于返回的列表,以便它按项目代码对我的列表进行排序?换句话说,如何重载 List(),它将按项目代码对列表进行排序 - 降序或升序。
我的列表应该只有 2 个对象。
如果在任何给定时间你只有 2 个对象,那么你可以简单地假设并通过它们的索引访问它们:
public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
listik = new List<ProcCodesDates>
{
new ProcCodesDates { ItemNextAvailableDates[0].GetValue(), ItemProcCodes[0].GetValue() },
new ProcCodesDates { ItemNextAvailableDates[1].GetValue(), ItemProcCodes[1].GetValue() }
};
return this;
}
但是...
ItemNextAvailableDates
和 ItemProcCodes
至少有两项。这可能是 IndexOutOfRangeException
的潜在来源,因此您可能希望在其周围放置 try/catch
块。所以你可以尝试的是:
const string expectedItemsCount = 2;
public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
listik = new List<ProcCodesDates>();
for (int i = 0; i < expectedItemsCount ; i++)
{
listik.Add(new ProcCodesDates
{
NextAvailableDate = ItemNextAvailableDates[i].GetValue(),
ProcCode = ItemProcCodes[i].GetValue()
});
}
return this;
}
看起来更干净!但你仍然有同样的问题
IndexOutOfRangeException
。因此,我们可以更进一步,使用Math.Min
。这将采用给定 2 个数组中的最小值,即使在最坏的情况下也不会抛出异常。
public SalesOrderTemplateBase GetItemProcCodeAndNextAvilableDates(out List<ProcCodesDates> listik)
{
listik = new List<ProcCodesDates>();
// Check if both lists have at least 2 items to avoid out of range exceptions
int itemsCount = Math.Min(ItemNextAvailableDates.Count, ItemProcCodes.Count);
for (int i = 0; i < itemsCount; i++)
{
listik.Add(new ProcCodesDates
{
NextAvailableDate = ItemNextAvailableDates[i].GetValue(),
ProcCode = ItemProcCodes[i].GetValue()
});
}
return this;
}
对于订购,如果您可以访问 LINQ,请使用
.OrderBy()
。例如:
listik.OrderBy(x => x.ProcCodeDate);
listik.OrderByDescending(x => x.ProcCodeDate);
一个很好的例子是这里