2013-07-23 92 views
3

我使用Selenium来测试我的用户界面。Selenium - @FindBy和WebElement.findElement()之间的区别

我试图使用@ FindBy的注释。下面这段代码工作正常:

@FindBy(how=How.XPATH, xpath ="//input[contains(@id,'idOfInputField')]") 
    private WebElement someWebElement; 

private void someMethod(){ 
    WebElement a = someWebElement.findElement(By.xpath("//a[contains(@class, 'ui-spinner-up')][1]")); 
    WebElement span1 = a.findElement(By.xpath("//a[contains(@class, 'ui-spinner-up')][1]")); 
    WebElement span2 = span1.findElement(By.xpath("//span[contains(@class, 'ui-button-text')][1]")); 
    WebElement b = span2.findElement(By.xpath("//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]")); 
    b.click(); 
} 

我想用下面的代码,因为它是注释为主,但它不工作,但我认为这是完全一样的:

@FindBy(how=How.XPATH, xpath ="//input[contains(@id,'idOfInputField')]" 
     + "//a[contains(@class, 'ui-spinner-up')][1]" 
     + "//a[contains(@class, 'ui-spinner-up')][1]" 
     + "//span[contains(@class, 'ui-button-text')][1]" 
     + "//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]") 
private WebElement someWebElement; 

pivate void someMethod(){ 
    someWebElement.click(); 
} 

我得到的是以下情况例外:

java.lang.RuntimeException: Cannot invoke click on element null. Cannot find it. 
    Cause: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//input[contains(@id,'idOfInputField')]//a[contains(@class, 'ui-spinner-up')][1]//span[contains(@class, 'ui-button-text')][1]//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]"} 
    Command duration or timeout: 14 milliseconds 
    For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html 
    Build info: version: '2.32.0', revision: '6c40c187d01409a5dc3b7f8251859150c8af0bcb', time: '2013-04-09 10:39:28' 
    System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.5.0-28-generic', java.version: '1.7.0_21' 
    Session ID: 92f605a1-0a63-4ba0-b290-ca724b3c6386 
    Driver info: org.openqa.selenium.firefox.FirefoxDriver 
    Capabilities [{platform=LINUX, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true, acceptSslCerts=true, handlesAlerts=true, browserName=firefox, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=20.0}] 
     at path.to.package.utils.StaleReferenceAwareFieldDecorator$StaleReferenceAwareElementLocator.in 

    voke(StaleReferenceAwareFieldDecorator.java:86) 
      at com.sun.proxy.$Proxy9.click(Unknown Source) 
      at 
    .... 
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
      at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48) 
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:292) 
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

一些身体能解释什么这个品行或者原因其实是有这两个代码段之间的区别吗?

回答

3

首先,你不能用这样一个令人费解的XPath,杀死你的页面对象的可读性。您的选择器应尽可能简洁。其次,你不应该使用XPATH并使用CSS选择器。现在回到你的问题,

@FindBy(css="span[class*='ui-icon-triangle-1-n']") 
WebElement b; 

,或者尝试

@FindBy(css="span[class*='ui-button-text']>span[class*='ui-icon-triangle-1-n']") 
WebElement b; 
0

的@FindBy注释经由.initObjects方法中使用由PageFactory类加载注释。如果我的页面对象通过扩展LoadableComponent实现了LoadableComponent接口,我使用这个方法很多。 (注意:当然,通过扩展LoadableComponent,您不能通过页面对象扩展另一个类,但是如果您在已实现的接口中使用静态方法(一种JDK8功能),那么您可以获得类似于扩展多个类的功能,或者类似traits/mixins 。)

+0

在这两种情况下,我在我的基类,它调用initObjects ...... – joshi737

+0

做同样的东西,你应该能够用更短的选择,喜欢的cssSelector。你的选择器很长,这可能会造成一些混淆。 – djangofan

1

编辑:你的//a[contains(@class, 'ui-spinner-up')][1]在你的第一个例如两个XPath选择,但只有一个在你的第二个......这可能会导致您的问题。

+1

我也推荐使用CSS。它更易于阅读,而且写起来更简单。 XPath的那一行看起来像'#idOfInputField .ui-spinner-up .ui-spinner-up .ui-button-text .ui-icon.ui-icon-triangle-1-n'虽然,我想可以进一步简化 –

+0

谢谢,我纠正了它在我的代码和上面=>仍然没有工作...... CSS究竟如何,我从来没有使用CSS! – joshi737

+1

'@FindBy(CSS = “#idOfInputField的.ui微调向上的.ui微调向上的.ui按钮文本的.ui-icon.ui图标三角形-1-正”)' –

0

页对象需要被装饰的对象。我认为你得到这个错误是因为你没有装饰所需的课程。使用方法initElements(yourdriverobject,classToBeDecorated)。这应该可以解决问题。让我知道你是否需要任何帮助。