我正在用C#/ Selenium测试UI,并且有一个数据输入部分,然后是一个结果窗口。返回结果或没有结果。我正在测试这两种情况
我为此测试创建了一种方法,如下所示。可以用来测试是/否方案是否存在元素...
public bool HasResults()
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
if (yesResultElement.Count > 0)
{
return true;
}
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (noResultElement.Count > 0)
{
return false;
}
throw new Exception("Could not determine if there were results");
}
问题是,当我测试'noResultElement'时,此方法挂断并超时,因为找不到'yesResultElement'。
我尝试在第一个IF语句周围添加try / catch
public bool HasResults()
{
try
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
if (yesResultElement.Count > 0)
{
return true;
}
}
catch
{
Console.WriteLine("element does not exist");
}
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (noResultElement.Count > 0){
return false;
}
throw new Exception("Could not determine if there were results");
}
这可以解决问题,但也可以将20秒的测试转换为> 1分钟(由于在测试文件中指定了隐式等待)
除了将其分为2种方法外,还有没有更好的方法来处理此问题?如果没有yesResultElement,请忽略该IF语句,然后移到下一个我想要的语句。
测试看起来像这样
[TestMethod]
public void NoRecordsFoundTest()
{
// Tests whether no records are found when that is the expected outcome
var searchPage = new SearchPage(driver);
var firstTest = testData.First();
searchPage.EnterSearchInfo(firstTest);
var result = searchPage.HasResults();
try
{
result.Should().BeFalse();
log.Debug("The No Records Found Test Passed");
}
catch (AssertFailedException ex)
{
log.Debug("The No Records Found Test Failed",ex);
Assert.Fail();
}
}
[TestMethod]
public void RecordsFoundTest()
{
// Tests whether records are found when that is the expected outcome
var searchPage = new SearchPage(driver);
var firstTest = testData.Skip(1).First();
searchPage.EnterSearchInfo(firstTest);
var result = searchPage.HasResults();
try
{
result.Should().BeTrue();
log.Debug("The Records Found Test Passed");
}
catch (AssertFailedException ex)
{
log.Debug("The Records Found Test Failed", ex);
Assert.Fail();
}
}
不确定其相关性,但测试数据已从JSON文件加载并传递到EnterSearchInfo()方法中。
此外,即使返回结果,UI也会出现一个小故障,一瞬间出现noResultElement,然后消失。
答案 0 :(得分:1)
您可以将隐式等待超时临时设置为一个较小的值,重复尝试查找您的元素,等待直到找到至少一个组(使用OpenQA.Selenium.Support.UI.WebDriverWait
),然后根据所使用的组返回布尔值。找到。
这样的扩展方法可能会有所帮助:
public static class WebDriverExtensions
{
/// <summary>
/// Executes the specified `action` with `ImplicitWait` set to the specified `timeout`.
/// </summary>
/// <typeparam name="T">The action return type.</typeparam>
/// <param name="b">The WebDriver instance.</param>
/// <param name="timeout">
/// The duration that WebDriver should implicitly wait until it gives up on trying to
/// find an element.
/// </param>
/// <param name="action">
/// The action to execute with the special ImplicitWait setting.
/// </param>
/// <returns>The action result.</returns>
public static T WithImplicitWait<T>(this ChromeDriver b, TimeSpan timeout, Func<T> action)
{
ITimeouts timeouts = b.Manage().Timeouts();
TimeSpan oldImplicitWait = timeouts.ImplicitWait;
try
{
timeouts.ImplicitWait = timeout;
return action();
}
finally
{
timeouts.ImplicitWait = oldImplicitWait;
}
}
}
然后您将像这样使用它:
public bool HasResults()
{
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10))
{
Message = "Could not find neither 'yes' nor 'no' results."
};
var implicitTimeout = TimeSpan.FromMilliseconds(200);
string found =_driver.WithImplicitWait(implicitTimeout, () => wait.Until(b =>
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (yesResultElement.Count == 0 && noResultElement.Count == 0)
{
return null;
}
if (yesResultElement.Count > 0 && noResultElement.Count > 0)
{
return "both";
}
return yesResultElement.Count > 0 ? "yes" : "no";
}));
bool result = found switch
{
"yes" => true,
"no" => false,
_ => throw new Exception("Could not determine if there were results")
};
return result;
}
WebDriverWait.Until
将重复调用您的回调,直到它返回非null值为止,因此当找不到两个组时,我们将返回null
。 (在这种情况下)它将在10秒后放弃,并失败并显示指定的错误消息。