tags:

views:

299

answers:

2

I want to group the common methods in one file and use it. For example, login to a page using selenium may be used in multiple times. Define that in class A and call it in class B. However, it throws null pointer exception.

class A has

public void test_Login() throws Exception
    {
        try{
        selenium.setTimeout("60000");
        selenium.open("http://localhost");
        selenium.windowFocus();
        selenium.windowMaximize();
        selenium.windowFocus();
        selenium.type("userName", "admin");
        selenium.type("password", "admin");
        Result=selenium.isElementPresent("//input[@type='image']");
        selenium.click("//input[@type='image']");
        selenium.waitForPageToLoad(Timeout);
        }
        catch(Exception ex)
        {   
            System.out.println(ex);
            ex.printStackTrace();
        }
    }

with all other java syntax

in class B

public void test_kk() throws Exception
    {

        try
        {
            a.test_Login();
        }
        catch(Exception ex)
        {
            System.out.println(ex);
            ex.printStackTrace();
        }
    }

with all syntax.

When I execute class B, I got this error,

java.lang.NullPointerException
        at A.test_Login(A.java:32)
        at B.test_kk(savefile.java:58)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at com.thoughtworks.selenium.SeleneseTestCase.runBare(SeleneseTestCase.j
ava:212)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:232)
        at junit.framework.TestSuite.run(TestSuite.java:227)
        at junit.textui.TestRunner.doRun(TestRunner.java:116)
        at junit.textui.TestRunner.doRun(TestRunner.java:109)
        at junit.textui.TestRunner.run(TestRunner.java:77)
        at B.main(B.java:77)

I hope someone must have tried this before. I may miss something here.

+1  A: 

How is the selenium object initialized in class A? Do you remember to pass it in from where it gets created in class B? If that is the way it works, that is it's hard to see when that part of the code is not included...

AHM
I dont want to initialize anything in class A. Just the part of code is there to call from class B. Is that incorrect?
Rajasankar
I don't know, I can't see the scopes in the code you posted, but it seems that if you intialize the selenium object in class B, then you have to pass it to class A somehow (like through the constructor, maybe).
AHM
Sorry, maybe that was unclear - I mean apparently some magic happens the initializes the selenium property of an object that extends SeleneseTestCase when the test is run. When you try to call another class from inside the test, that property is not initialized, and therefore you have to pass in the value of the selenium property from the outer class.So add an argument to your class A constructor an use that to initalize the selenium property in A. From B you would then create a new A by doing new A(selenium) or something.If this is the problem at all :-)
AHM
I will check this initialization thing.
Rajasankar
+1  A: 

The way we do it is, we have helper classes with static methods on them. In the actual test cases we set up our selenium object and pass the object into the static method so it can operate on it.

public BaseHelper
{
    public static login( final String username, final String password, final DefaultSelenium selenium )
    {
     selenium.type("userName", username);
     selenium.type("password", password);
     selenium.click("loginbutton");
    }
}


public LoginTest
{
    DefaultSelenium selenium;

    onSetup()
    {
      selenium = new DefaultSelenium(...);
    }  

    public testLogin()
    {
      BaseHelper.login( "admin", "admin", selenium);
      // assert that this passed
      BaseHelper.login( "foo", "bar", selenium);
      // assert this failed because no user 'foo'
      BaseHelper.login( "admin", "bar", selenium);
      // assert this failed because admin's password was incorrect
    }
}

Hope this illustrates the point.

Besides the better readability and easier maintenance, you are also able to test multiuser behavior by creating two (or more) selenium objects and pass those around in the tests.

c_maker