添加到对象列表中正确的项目

问题描述 投票:0回答:1

我开发了 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 条记录:

我希望得到的清单如下:

我试图找出正确的决定,但我没有想法。 所以,我有两个问题:

  1. 如何让我的列表返回正确的值,换句话说,在循环中将项目添加到列表中的算法是什么,以便他们添加每个代码与相应的日期?

  2. 如何使用方法“.Sort()”应用于返回的列表,以便它按项目代码对我的列表进行排序?换句话说,如何重载 List(),它将按项目代码对列表进行排序 - 降序或升序。

c# selenium-webdriver automated-tests
1个回答
0
投票

我的列表应该只有 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;
        } 

但是...

  1. 目前假设
    ItemNextAvailableDates
    ItemProcCodes
    至少有两项。这可能是
    IndexOutOfRangeException
    的潜在来源,因此您可能希望在其周围放置
    try/catch
    块。
  2. 可读性不太好。

所以你可以尝试的是:

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);

一个很好的例子是这里

© www.soinside.com 2019 - 2024. All rights reserved.