java 使用 TestNG 运行代码时出现空指针异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29065095/
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
Null Pointer Exception while running code using TestNG
提问by Ashwiinn Karaangutkar
I am trying to automate a Login and Logout Scenario in TestNG and passing the browser as parameter from XML on the basis of which chromedriver() instance will be created and the code will run.I have two classes TestRunner and Login where login method gets data (username and password) TestRunner and data is fetched from excel.Exception e is getting null value as I found out while debugging. Any way to fix it?
我正在尝试在 TestNG 中自动化登录和注销场景,并根据将创建 chromedriver() 实例并运行代码的基础上将浏览器作为参数从 XML 传递。我有两个类 TestRunner 和 Login 其中登录方法获取数据(用户名和密码)TestRunner 和数据是从 excel.Exception e 获取空值,因为我在调试时发现。有什么办法可以解决吗?
FAILED: Registration_data("[email protected]", "ashwin123")
java.lang.NullPointerException
at com.DataDriven.Login.login(Login.java:68)
at com.DataDriven.TestRunner.Registration_data(TestRunner.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:12)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
package com.DataDriven;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class TestRunner {
@Test(dataProvider = "Authentication")
public static void Registration_data(String sUserName, String sPassword)
throws Exception {
Login lp = new Login();
lp.login(sUserName, sPassword);
}
@DataProvider
public Object[][] Authentication() throws Exception {
Object[][] testObjArray = ReadData.getTableArray(
"F:\Automation\DataDrivenPractice\DataFiles\DataFile.xlsx",
"Sheet1");
return (testObjArray); } }
package com.DataDriven;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Login {
WebDriver driver = null;
@Parameters("browser")
@BeforeClass
// Passing Browser parameter from TestNG xml
public void beforeTest(String browser) {
// If the browser is Firefox, then do this
if (browser.equalsIgnoreCase("firefox")) {
driver = new FirefoxDriver();
// If browser is IE, then do this
} else if (browser.equalsIgnoreCase("chrome")) {
// Here I am setting up the path for my IEDriver
driver = new ChromeDriver(); } }
public void login(String username, String password) {
try {
driver.get("https://www.facebook.com/");
driver.findElement(By.id("email")).sendKeys(username);
driver.findElement(By.id("pass")).sendKeys(password);
driver.findElement(By.id("loginbutton")).click();
driver.findElement(By.linkText("Log Out")).click();
}
catch (Exception e) {
File srcfile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(srcfile, new File(
"F:\Automation\Screenshots\Login.jpg"));
} catch (Exception e1) {
e1.printStackTrace();
} } }}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none">
<test name="FirefoxTest">
<parameter name="browser" value="chrome" />
<classes>
<class name="com.DataDriven.TestRunner" />
<class name="com.DataDriven.Login" />
</classes>
</test>
</suite>
回答by Fenio
Your problem is - your method beforeTest
doesn't invoke. Your driver
doesn't point to any type of object.
你的问题是 - 你的方法beforeTest
没有调用。你driver
没有指向任何类型的对象。
TestNG search through all your classes only for @Test
annotation. How it's supposed to know that @BeforeClass
annotation lies in specific class you've created?
TestNG 搜索您所有的类只是为了@Test
注释。它应该如何知道@BeforeClass
注释位于您创建的特定类中?
To run @BeforeClass
annotation, you either have to set extends
for Login
class (it won't be effective for multiple scripts) or run beforeTest
method manually. Or set it to running class containing @Test
annotation.
要运行@BeforeClass
注释,您必须extends
为Login
类设置(它不会对多个脚本有效)或beforeTest
手动运行方法。或者将其设置为包含@Test
注释的运行类。
Correct me if i'm wrong. Hope it helps!
如我错了请纠正我。希望能帮助到你!
EDIT:
编辑:
Move your method and WebDriver variable to Test Runner
Class
将您的方法和 WebDriver 变量移动到Test Runner
Class
WebDriver driver = null;
@Parameters("browser")
@BeforeClass
// Passing Browser parameter from TestNG xml
public void beforeTest(String browser) {
// If the browser is Firefox, then do this
if (browser.equalsIgnoreCase("firefox")) {
driver = new FirefoxDriver();
// If browser is IE, then do this
} else if (browser.equalsIgnoreCase("chrome")) {
// Here I am setting up the path for my IEDriver
driver = new ChromeDriver(); } }
TestRunner
class should contain both, @Test
and @BeforeClass
. As TestNG reads Annotations from classes containing @Test
annotation.
TestRunner
类应该同时包含,@Test
和@BeforeClass
。当 TestNG 从包含@Test
注解的类中读取注解时。
回答by Nguyen Vu Hoang
There are many issues in your scripts
你的脚本有很多问题
1 - Your classes init separately. The driver from @BeforeClass doesnot inherite into your @Test
1 - 您的课程单独初始化。来自 @BeforeClass 的驱动程序不会继承到您的 @Test
2 - When you do
2 - 当你这样做时
Login lp = new Login();
you have
你有
WebDriver driver = null;
@BeforeClass is not invoked, no driver init, your driver is still null
Then
然后
lp.login(sUserName, sPassword);
NullPointException throws because driver in following line of code is null
NullPointException 抛出,因为以下代码行中的驱动程序为空
driver.get("https://www.facebook.com/");
Suggest action
建议行动
- You need to get driver goes through all your classes
- 你需要让司机完成你所有的课程
TestBase.class
测试库类
Put your @BeforeClass here
LoginPage.class, be sure you allow to cast driver into it
LoginPage.class,确保您允许将驱动程序转换到其中
public LoginPage(WebDriver driver) {
// your code here
}
// Put login(sUserName, sPassword) method here
TestRunner.class
TestRunner.class
inherite/extends from TestBase.class
LoginPage lp = new LoginPage(driver);
lp.login(sUserName, sPassword);