java 如何在 Selenium Webdriver 中使用异常处理?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33338959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use Exception Handling in Selenium Webdriver?
提问by testing
The Scenario is as follows:
When the code driver.get(url);
runs, if the URL is not able to access (if server is not reachable) then it should throw an exception that server is not reachable and the code should stop executing the next line
场景如下:当代码driver.get(url);
运行时,如果URL无法访问(如果服务器不可达)那么它应该抛出服务器不可达的异常并且代码应该停止执行下一行
driver.findElement(By.id("loginUsername")).sendKeys(username);
The following code I'm running in eclipse as follows:
我在 eclipse 中运行的以下代码如下:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class A {
static Properties p= new Properties();
String url=p.getProperty("url");
private static Logger Log = Logger.getLogger(A.class.getName());
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, InterruptedException {
WebDriver driver = new FirefoxDriver();
A a = new A();
Actions actions = new Actions(driver);
DOMConfigurator.configure("src/log4j.xml");
String url = a.readXML("logindetails","url");
String username = a.readXML("logindetails","username");
String password = a.readXML("logindetails","password");
//use username for webdriver specific actions
Log.info("Sign in to the OneReports website");
driver.manage().window().maximize();
driver.get(url);// In this line after opens the browser it gets the URL from my **D://NewFile.xml* file and try to open in the browser. If the Server is not reachable then it should stop here. else it takes the username and password from the same file then it will open the page in browser.
Thread.sleep(5000);
Log.info("Enter Username");
driver.findElement(By.id("loginUsername")).sendKeys(username);
Log.info("Enter Password");
driver.findElement(By.id("loginPassword")).sendKeys(password);
//submit
Log.info("Submitting login details");
waitforElement(driver,120 , "//*[@id='submit']");
driver.findElement(By.id("submit")).submit();
Thread.sleep(5000);
}
private static void waitforElement(WebDriver driver, int i, String string) {
// TODO Auto-generated method stub
}
public String readXML(String searchelement,String tag) throws SAXException, IOException, ParserConfigurationException{
String ele = null;
File fXmlFile = new File("D://NewFile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName(searchelement);
Node nNode = nList.item(0);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
ele=eElement.getElementsByTagName(tag).item(0).getTextContent();
}
return ele;
}
}
I tried this try block method as well. But it's not catching the exception just moving to the
我也尝试过这种 try 块方法。但它并没有捕捉到异常只是移动到
driver.findElement(By.id("loginUsername")).sendKeys(username);
driver.findElement(By.id("loginUsername")).sendKeys(username);
Error in code
代码错误
line and I'm getting error as follows in the console:Unable to locate element: {"method":"id","selector":"loginUsername"} Command duration or timeout: 262 milliseconds
行,我在控制台中收到如下错误:无法定位元素:{"method":"id","selector":"loginUsername"} 命令持续时间或超时:262 毫秒
try
{
driver.get(url);
}
catch(Exception e)
{
Reporter.log("network server is slow..check internet connection");
Log.info("Unable to open the website");
throw new Error("network server is slow..check internet connection");
}
回答by JRodDynamite
Basically, what you want to do is check the HTTP response code of the request that the browser is sending. If the code is 200
, then you want the code to continue executing. If it is not then you want it to skip the code following it.
基本上,您要做的是检查浏览器发送的请求的 HTTP 响应代码。如果代码是200
,那么您希望代码继续执行。如果不是,那么您希望它跳过它后面的代码。
Well, selenium has not yet implemented a method for checking the response code yet. You can check this linkto see details regarding this issue.
好吧,selenium 还没有实现检查响应代码的方法。您可以查看此链接以查看有关此问题的详细信息。
At the moment, all you can do is send a request to link by using HttpURLConnection
and then check the response status code.
目前,您所能做的就是使用 using 发送链接请求HttpURLConnection
,然后检查响应状态代码。
METHOD 1:
方法一:
You can try something like this before calling driver.get()
method:
你可以在调用driver.get()
方法之前尝试这样的事情:
public static boolean linkExists(String URLName){
try {
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection conn = (HttpURLConnection) new URL(URLName).openConnection();
conn.setRequestMethod("HEAD"); // Using HEAD since we wish to fetch only meta data
return (conn.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (Exception e) {
return false;
}
}
Then you can have:
然后你可以有:
if(linkExists(url)) {
driver.get(url);
// Continue ...
} else {
// Do something else ...
}
EDIT:
编辑:
METHOD 2:Otherwise you can try this. Create an Exception class named LinkDoesNotExistException
like this:
方法2:否则你可以试试这个。创建一个LinkDoesNotExistException
像这样命名的异常类:
LinkDoesNotExistException.java
LinkDoesNotExistException.java
public class LinkDoesNotExistException extends Exception {
public LinkDoesNotExistException() {
System.out.println("Link Does Not Exist!");
}
}
And then add this function, in class A.
然后在A类中添加这个函数。
public static void openIfLinkExists(WebDriver driver, String URLName) throws LinkDoesNotExistException {
try {
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection conn = (HttpURLConnection) new URL(URLName).openConnection();
conn.setRequestMethod("HEAD"); // Using HEAD since we wish to fetch only meta data
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
driver.get(URLName);
} else {
throw new LinkDoesNotExistException();
}
} catch (Exception e) {
throw new LinkDoesNotExistException();
}
}
Now, instead of using driver.get(url)
simply use openIfLinkExists(driver, url)
within a try-catch block.
现在,不是在 try-catch 块中driver.get(url)
简单地使用 use openIfLinkExists(driver, url)
。
try {
WebDriver driver = new FirefoxDriver();
openLinkIfExist(driver, url);
// Continues with execution if link exist
} catch(LinkDoesNotExistException e) {
// Exceutes this block if the link does not exist
}
回答by Priyanshu Shekhar
Other way around is if you are just looking solution for firefox browser then you can do something like this:
另一种方法是,如果您只是在寻找 Firefox 浏览器的解决方案,那么您可以执行以下操作:
if(driver.getTitle() == 'Problem loading page') {
return false;
}
Or you can have multiple conditions for different browser.
或者您可以为不同的浏览器设置多个条件。
回答by ekostadinov
I like your approach and I think such optimization will improve the performance of your UI tests greatly. If I had to do it, I would add an API layer to my Selenium framework. We need to keep the SRP. Since you just need a very simple API call(only the response status), maybe a single Sender class will do the job just fine. If you decide to extend it in future a Command patternwill be a good fit.
我喜欢你的方法,我认为这样的优化将大大提高你的 UI 测试的性能。如果必须这样做,我会在我的 Selenium 框架中添加一个 API 层。我们需要保留SRP。由于您只需要一个非常简单的API 调用(仅响应状态),也许单个 Sender 类就可以完成这项工作。如果您决定将来扩展它,命令模式将是一个不错的选择。
When the code driver.get(url); runs, if the URL is not able to access (if server is not reachable) then it should throw an exception that server is not reachable and the code should stop executing the next line driver.findElement(By.id("loginUsername")).sendKeys(username);
当代码 driver.get(url); 运行,如果 URL 无法访问(如果服务器无法访问)那么它应该抛出一个服务器无法访问的异常并且代码应该停止执行下一行 driver.findElement(By.id("loginUsername")) .sendKeys(用户名);
One advice on this one - the API call (checking the Server accessibility) can be utilized as a test fixture. Either Fresh fixtureor even better - Shared fixture, in case the Server returns 500
type of error, then no need for you to run the entire test suite (you can handle it in a TestSuiteContext
object). By doing this, you'll save creating driver and browser instances for those just being destroyed right after.
关于这一点的一个建议 - API 调用(检查服务器可访问性)可以用作测试装置。无论是新鲜的夹具,甚至更好-共享夹具,万一服务器返回500
错误的类型,则没有必要为你来运行整个测试套件(您可以在处理它TestSuiteContext
的对象)。通过这样做,您将节省为那些刚刚被销毁的驱动程序和浏览器实例创建的时间。
it should throw an exception
它应该抛出异常
You can create your own custom exceptions(e.g. ServerAvailabilityException
) in Java. Example:
您可以在 Java 中创建自己的自定义异常(例如ServerAvailabilityException
)。例子:
public class CustomException extends Exception{}
回答by Prashant Palve
Try this one:
试试这个:
try {
driver.get(url);
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception Occured:", e);
}