1

I am facing this 'Cannot insantiate class' error on running one of my test cases in Selenium webdriver using Java.

Below is the class of the functionality of the test,

package Pages;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;

import Lib.lib;

public class KnowledgeBase extends lib{

    By sortBylink = By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/div");
    By featuredOption = By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/ul/li[1]");
    By mostRcnt = By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/ul/li[2]");

    String featOption = driver.findElement(By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/ul/li[1]")).getText();

    String mostRecent = driver.findElement(By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/ul/li[2]")).getText();

    public void initSBy() throws Exception
    {
        driver.findElement(sortBylink).click();
        Thread.sleep(1500);
    }

    public void selectfO() throws Exception
    {
        driver.findElement(featuredOption).click();
        Thread.sleep(5000);
    }

    public void selectMr() throws Exception
    {
        driver.findElement(mostRcnt).click();
        Thread.sleep(5000);
    }

    public void sortBy(String sProp) throws Exception
    {
        this.initSBy();

        if (sProp == "featOption") {

            this.selectfO();

        }

        else if (sProp == "mostRecent"){

            this.selectMr();
        }

        else {

            System.out.println("Incorrect option. Test failed.");
        }
    }


}

Below is my Test Case Class

package TestCases;

import org.testng.annotations.Test;

import Lib.lib;
import Pages.KnowledgeBase;
import Pages.LoginPage;

public class sortingTextKB extends lib {

    LoginPage uLogin = new LoginPage();
    KnowledgeBase sortObj = new KnowledgeBase();

    //Logging In
    @Test (priority = 1)
    public void loggingIn() throws Exception
    {
        uLogin.loginToKB("uzii@test.com", "uziiiii");
    }

    //Sorting
    @Test (priority = 2)
    public void sortIn() throws Exception
    {
        sortObj.sortBy("Most Recent");
    }

}

Below is my Lib class, that contains the chrome driver configuration

package Lib;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;

public class lib {

    protected static WebDriver driver = null;

    @BeforeTest
    public void chrome_extension()
    {
        System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
        driver.get("http://www.testsite.com");
    }


    @AfterTest
    public void quit()
    {
        driver.quit();
    }

}

When I run my test case class, I am getting the following error,

org.testng.TestNGException: 
Cannot instantiate class TestCases.sortingTextKB
    at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:38)
    at org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:387)
    at org.testng.internal.ClassHelper.createInstance(ClassHelper.java:299)
    at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:110)
    at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:186)
    at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:120)
    at org.testng.TestRunner.initMethods(TestRunner.java:409)
    at org.testng.TestRunner.init(TestRunner.java:235)
    at org.testng.TestRunner.init(TestRunner.java:205)
    at org.testng.TestRunner.<init>(TestRunner.java:160)
    at org.testng.remote.RemoteTestNG$1.newTestRunner(RemoteTestNG.java:141)
    at org.testng.remote.RemoteTestNG$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG.java:271)
    at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:561)
    at org.testng.SuiteRunner.init(SuiteRunner.java:157)
    at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
    at org.testng.TestNG.createSuiteRunner(TestNG.java:1299)
    at org.testng.TestNG.createSuiteRunners(TestNG.java:1286)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
    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)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29)
    ... 21 more
Caused by: java.lang.NullPointerException
    at Pages.KnowledgeBase.<init>(KnowledgeBase.java:22)
    at TestCases.sortingTextKB.<init>(sortingTextKB.java:12)
    ... 26 more

Following is line 22 of KnowledgeBase class,

String featOption = driver.findElement(By.xpath("html/body/div[1]/featured-studies-grid/div[2]/featured-studies-toolbar/div/div[2]/div[2]/div/ul/li[1]")).getText();

Please let me know why I am facing this 'cannot instantiate class' error. Thanks

  • BTW, package names should be lower case, and class names should start from Capital letter in Java. – dzieciou Dec 14 '15 at 10:07
  • Rename ClassName of Lib to another. I also got an error.This can be resolved by changing Classname. – vinay goswami Jan 26 '18 at 15:50
1

It looks like your driver instance is created in one class(lib, (should start with Capital letter BTW)) but you are trying to access it in another class(KnowledgeBase).

If you want to use a class instance in another class, you have options. Some of them are:

  1. Add a getter method. Add a public getDriverInstance() method in the class where the instance is created that will just return the driver instance.
  2. Keep everything in the same class. Keep the driver initialization method as well as the tests themselves in the same class. That's obviously a messy solution but it will work.
  3. Use a Dependency Injection framework. You can use a DI framework like Spring, PicoContainer, etc.., which is probably the cleanest solution but has some learning curve to it.
0

Use @BeforeMethod annotation in place of @BeforeTest.

  • Just curious, what does this do? What other impacts does this change make? – corsiKa Sep 14 '15 at 4:15
  • It’s purely intuitive; there aren’t any issues in the code. So either user14403 has made a logical error in loginToKB method (for which code isn’t shared) or since details are specified in BeforeTest and it is expected to call this before each Test (priority=1) and Test2 (priority=2), to achieve this BeforeMethod has to be used (this being a common mistake made). – JustARandomGuy Sep 14 '15 at 4:36
  • 1
    The explanation of the difference between @BeforeMethod and @BeforeTest needs to be in your answer. – Kate Paulk Sep 14 '15 at 11:12
  • @KatePaulk Explaining the difference would be a great idea, because it's a confusing concept in TestNG. @BeforeMethod runs before each @Test method. @BeforeTest runs before each test, which is not the same thing as a @Test method. A TestNG test is defined in the XML or JSON file that defines what to run. It's essentially a sub-suite, and can invoke many test methods. Yeah, like I said, confusing. That said, explaining the difference would not help this answer, because (while it may be a good idea) it does not solve the problem described in the question. – Dale Emery Jan 26 '18 at 22:09
0

There are a few problems here. The construction of your classes is confusing and will give you issues if not corrected. First, @BeforeTest is run once before the entire suite of tests (This is a common error). You would instead want either @BeforeClass or @BeforeMethod. @BeforeMethod would be a better choice as it would ensure a fresh browser before each test method. You'll need a matching @AfterMethod as well.

Next, you are extending all of your Classes from the same Lib class. This is a very unwieldy design pattern. Instead create a class with all of your test setup and tear down. Extend the classes with the actual tests from this.

From here you can pass the driver to the Page objects and Knowledgebase object using a getdriver() method as suggested by Eugene.

public class ChromeTest {
    private ChromeDriver driver;

    @BeforeMethod
    public void beforeMethod(){
        driver = new ChromeDriver();
        //additional setup
     }

     @AfterMethod
     public void afterMethod(){
         driver.quit();
         //additional tear down 
     }

     public ChromeDriver getDriver (){
         return driver;
     }
}

Test Classes

public class UiTest extends ChromeTest {
    @Test
    public void test1(){
        KnowledgeBase kb = new KnowledgeBase(getDriver());
        //Rest of your test code
    }
}

Refactor your page and KnowledgeBase classes to use the passed in driver instance.

public class KnowledgeBase{
    private WebDriver driver;

    public KnowledgeBase( WebDriver webDriver ) {
        driver = webDriver;
    }
    //rest of your methods
}

By refactoring your classes and methods as noted above it will vastly simplify your code which will make the logical errors easier to find if not fix it outright.

0

The problem is this:

  1. TestNG must finish instantiating a KnowledgeBase object before it calls any of the configuration methods (annotated with @BeforeTest and @BeforeMethod).
  2. Instantiating a KnowledgeBase includes initializing all of its members.
  3. One of the members it must initialize is featOption, on line 22.
  4. In order to initialize featOption, the initialization tries to call driver.findElement(...).
  5. Because the chrome_extension() method in Lib hasn't been called yet, driver is still null.
  6. Kaboom

To fix this, either:

  • Initialize driver in a constructor (probably in Lib), and only then initialize featOption (probably in KnowledgeBase's constructor). This means you'll have a single driver instance for all of your tests. Given that you're currently launching a new driver for each TestNG test (confusingly, in TestNG a "test" is not at all the same thing as a test method, even though test methods are annotated with @Test), that may or may not be what you want.
  • Initialize driver at the point where you declare it in Lib. This is more or less like initializing it in a constructor. So again, this may or may not be what you want.
  • Initialize featOption in a configuration method (annotated as @BeforeTest or @BeforeMethod) in KnowledgeBase. This will be called after the chrome_extension() method in Lib, so the driver will have have been constructed and launched. So when you call driver.findElement(...), driver will be valid.
0

Can you change:

protected static WebDriver driver = null;

to

 public static WebDriver driver;

Maybe that works. Just a try.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.