【问题标题】:Use object inside of a try/catch outside of the try/catch在 try/catch 之外使用 try/catch 内的对象
【发布时间】:2021-11-25 01:50:27
【问题描述】:

我需要一种使用对象或变量的方法,它位于 try/catch 内部,try/catch 外部。

我在 blazor 网页上使用 selenium 进行自动化测试。

网页上有一个元素,它确实会动态更改其名称。

我现在的想法是: 在 100 种情况下的 99 种情况下,它总能找到名为 selector 的变量,这意味着没有抛出异常。在这种情况下,我想在 try/catch 之外使用对象 Field

但在一种情况下,网页上有一个元素//div[@class='ql-editor']//p 在测试期间将其名称更改为//div[@class='ql-editor ql-blank']//p。现在,在测试抛出异常之前,它应该检查 //div[@class='ql-editor ql-blank']//p 是否可见。

如果是,那么我想使用 try/catch 之外的 catch 块中的对象 Field。 如果不是,它应该给我一个异常

注意:我知道这样一个事实,我认为解决该问题的方法可能不是最好的。我只是想防止只为 100 例中的​​ 1 例创建另一种方法。

        try
        {
            IWebElement Field = webDriver.FindElement(By.XPath(selector));
            Field.SendKeys(textToType);
        }
        catch (Exception e)
        {
            IWebElement Field = webDriver.FindElement(By.XPath("//div[@class='ql-editor ql-blank']//p"));
            Field.SendKeys(textToType);
        }

        string checkText = Field.GetAttribute("value");
        string checkInstruction = Field.Text;

【问题讨论】:

  • 只在尝试之外声明Field,但没有值:IWebElement Field;。请注意,您还可以将调用 SendKeys 移动到 try...catch... 之后,以避免代码重复。
  • 谢谢我试一试
  • 我已将其发布为答案,以防我不清楚:)

标签: c# selenium selenium-webdriver selenium-chromedriver


【解决方案1】:

RB怎么说...

    IWebElement field;
    try
    {
        field = webDriver.FindElement(By.XPath(selector));
    }
    catch
    {
        field = webDriver.FindElement(By.XPath("//div[@class='ql-editor ql-blank']//p"));
    }
    field.SendKeys(textToType);

    string checkText = field.GetAttribute("value");
    string checkInstruction = field.Text;

当您采用这种模式时,您可能会看到“使用未分配的局部变量...”编译器消息 - 在这些情况下,您可以在声明时分配 nulldefault,或者您可以分配一些适合的默认值:

    IWebElement field = "some sensible default";
    try{
      ...

RB 在 cmets 中明智地指出您会收到此消息,因为 C# 可以通过您的代码看到一些路径,其中变量从未被分配任何值。这可能是您所期望的,也可能不是;只有你能知道。如果您正在查看一些代码并认为“当我到达第 X 行时,变量 Y 肯定会有一些可用的值”,而 C# 告诉您没有,那么值得再次检查。虽然它并不完美/没有深入研究每一种可能的情况(有些事情在编译时无法知道,而有些事情不值得计算),但如果您期望它具有价值,则应确保分配您的值那个时候

ps;请使用 camelCase 声明本地变量,如果您正在捕获所有内容并且不对异常执行任何操作,您可以选择省略 Exception e 中的 e 甚至在 catch 之后的整个异常类型

【讨论】:

  • “您可能会看到“使用未分配的局部变量...”编译器消息”值得仔细注意这些消息 - 他们经常告诉您您忘记将变量分配给其中之一通过程序的可能路径。简单地分配null 将使编译器错误消失,但有可能将其变成运行时错误(当然,分配默认值可能是完全正确的 - 请仔细考虑您想要的行为)。
【解决方案2】:

只需在 try...catch... 块之外声明变量即可。

IWebElement Field;
try
{
     Field = webDriver.FindElement(By.XPath(selector));
}
catch (Exception e)
{
    Field = webDriver.FindElement(By.XPath("//div[@class='ql-editor ql-blank']//p"));
}

Field.SendKeys(textToType);
string checkText = Field.GetAttribute("value");
string checkInstruction = Field.Text;

【讨论】:

    【解决方案3】:

    另外两个答案是“简单”的答案,但在我看来,这不是正确的答案。您发布的代码未遵循将清理大量代码并消除您所询问的问题的最佳做法。

    对于您正在尝试的内容,有两种更好的方法。

    1. 首选方法是创建一个定位器来检查selectorql-blank 情况。我不能告诉你,因为你还没有发布selector 的定义。例如,我将向您展示使用您发布的两个定位器。与其在这里使用 XPath,不如选择 CSS 选择器。语法更简单,更容易阅读,执行速度更快,支持更好。如果您想了解更多信息,请观看一些 seleniumconf yt 视频,其中贡献者正在谈论定位器。

      这是您提供的两个 XPath。

      //div[@class='ql-editor']//p
      //div[@class='ql-editor ql-blank']//p
      

      让我们将这两个转换为 CSS 选择器。

      div.ql-editor p
      div.ql-editor.ql-blank p
      

      现在使用 OR 运算符 (,) 将它们组合成一个 CSS 选择器。

      div.ql-editor p, div.ql-editor.ql-blank p
      

      现在您可以将代码更新为

      By locator = By.CssSelector("div.ql-editor p, div.ql-editor.ql-blank p");
      IWebElement Field = webDriver.FindElement(locator);
      Field.SendKeys(textToType);
      
      string checkText = Field.GetAttribute("value");
      string checkInstruction = Field.Text;
      

      如您所见,这段代码要简单得多,而且完成的事情是一样的。

    2. 遵循处理可能不存在的元素的最佳实践的另一种方法是使用 .FindElements() 并检查空列表而不是使用异常。

      ReadOnlyCollection<IWebElement> Field = webDriver.FindElements(selector);
      if (!Field.Any())
      {
          Field = webDriver.FindElements(By.XPath("//div[@class='ql-editor ql-blank']//p"));
      }
      Field.ElementAt(0).SendKeys(textToType);
      
      string checkText = Field.GetAttribute("value");
      string checkInstruction = Field.Text;
      

      此方法不如方法 1 干净,但与使用异常相比,此方法更好、更干净。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多