我正在使用Junit 4w/ Selenium WebDriver进行一些自动化测试。我有一个测试,它记录一个页面上的一些值,单击页面上的一个按钮来加载下一个页面,然后比较记录的值以确保它们发生了变化。
问题是,这是一对值,其中只有一个必须改变,而不是两者兼而有之。
为了测试它,我目前实现了以下代码:
boolean orderNumberChanged = true;
try
{
assertThat(orderNumber,
is(not(getValueForElement(By.name("updateForm:j_id35")))));
}
catch (AssertionError ae) { orderNumberChanged = false; }
try
{
assertThat(orderDate,
is(not(getValueForElement(By.name("updateForm:j_id37")))));
}
catch (AssertionError ae)
{
if ( !orderNumberChanged )
{ fail("OrderNumber and OrderDate didn't change."); }
}虽然它应该工作得很好,但在我看来,它看起来很难看,而且它的接缝应该有一些方法来断言类似的东西。
对于记录,getValueForElement()是我写来包装的方法。
driver.findElement(locator).getAttribute("value");
发布于 2014-10-30 21:31:18
建议assertTrue(orderNumber.equals(...) || orderDate.equals(...));的答案/评论确实是最简单和最直接的解决方案。然而,我也想要更好的错误消息,而不仅仅是AssertionError。
为了做到这一点并不是微不足道的。我正在使用Selenium WebDriver,因此正在检查的实际数据属于WebDriver对象。
我找到了答案,多亏了这篇文章:http://www.planetgeek.ch/2012/03/07/create-your-own-matcher/博客文章。
原来Hamcrest有一个CombinableMatcher类和一个CombinableEitherMatcher
最后,我复制了CombinableEitherMatcher的逻辑,创建了自己的类Neither。
public class Neither<X>
{
/**
* Creates a matcher that matches when neither of the specified matchers
* match the examined object.
* <p/>
* For example:
* <pre>
* assertThat("fan", neither(containsString("a")).nor(containsString("b")))
* </pre>
*/
public static <LHS> Neither<LHS> neither(Matcher<LHS> matcher)
{ return new Neither<LHS>(matcher); }
private final Matcher<X> first;
public Neither(Matcher<X> matcher) { this.first = not(matcher); }
public CombinableMatcher<X> nor(Matcher<X> other)
{ return new CombinableMatcher<X>(first).or(not(other)); }
/**
* Helper class to do the heavy lifting and provide a usable error
* from: http://www.planetgeek.ch/2012/03/07/create-your-own-matcher/
*/
private class WebElementCombinableMatcher extends BaseMatcher<WebElement>
{
private final List<Matcher<WebElement>> matchers = new ArrayList<Matcher<WebElement>>();
private final List<Matcher<WebElement>> failed = new ArrayList<Matcher<WebElement>>();
private WebElementCombinableMatcher(final Matcher matcher)
{ matchers.add(matcher); }
public WebElementCombinableMatcher and(final Matcher matcher)
{
matchers.add(matcher);
return this;
}
@Override
public boolean matches(final Object item)
{
for (final Matcher<WebElement> matcher : matchers)
{
if (!matcher.matches(item))
{
failed.add(matcher);
return false;
}
}
return true;
}
@Override
public void describeTo(final Description description)
{ description.appendList("(", " " + "and" + " ", ")", matchers); }
@Override
public void describeMismatch(final Object item, final Description description)
{
for (final Matcher<WebElement> matcher : failed)
{
description.appendDescriptionOf(matcher).appendText(" but ");
matcher.describeMismatch(item, description);
}
}
}
}这让我打电话给assertThat(driver, niether(matcher(x)).nor(matcher(y));
由于我试图比较从驱动程序中获得的特定WebElements,所以我不得不创建匹配器,可以在niether/nor内部使用。
例如:
public class WebElementValueMatcher extends FeatureMatcher<WebDriver, String>
{
public static Matcher<WebDriver> elementHasValue(final By locator,
String elementValue)
{ return new WebElementValueMatcher(equalTo(elementValue), locator); }
public static Matcher<WebDriver> elementHasValue(final By locator,
Matcher<String> matcher)
{ return new WebElementValueMatcher(matcher, locator); }
By locator;
public WebElementValueMatcher(Matcher<String> subMatcher, By locator)
{
super(subMatcher, locator.toString(), locator.toString());
this.locator = locator;
}
public WebElementValueMatcher(Matcher<String> subMatcher,
String featureDescription, String featureName)
{ super(subMatcher, featureDescription, featureName); }
@Override
protected String featureValueOf(WebDriver actual)
{ return actual.findElement(locator).getAttribute("value"); }
}我还有另一个非常类似的名字叫actual.findElement(locator).getText(); in featureValueOf
不过,现在我可以直接打电话给
assertThat(driver,
niether(elementHasValue(By.id("foo"),"foo"))
.nor(elementHasValue(By.id("bar"),"bar")));` 并在我的测试中获得清晰的语法和可用的错误消息。
发布于 2014-10-14 22:13:05
如果没有严重的扭曲,就不可能像回到assertTrue那样让它的可读性大大降低。
就这么做
assertTrue(orderNumber.equals(...) || orderDate.equals(...));新的assertThat需要与单个对象进行匹配,因此您必须将它们放入数组或其他东西中才能通过。
https://stackoverflow.com/questions/26371032
复制相似问题