Everything with the @Test annotation throws null pointer exception, regardless of the method called. I tried calling driver.findElement() and executing js script with JavascriptExecutor. Both methods ended up with a null pointer. If I run through the IDE everything works like a charm. Otherwise, only the Before and After annotations are executed adequately Here's my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<parallel>methods</parallel>
<threadCount>1</threadCount>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache-extras.beanshell</groupId>
<artifactId>bsh</artifactId>
<version>2.0b6</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
and testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Practice Suite">
<test name="Test Basics 1">
<method-selectors>
<method-selector>
<script language="beanshell">
<![CDATA[
String testGroup = System.getProperty("env");
groups.containsKey(testGroup);
]]>
</script>
</method-selector>
</method-selectors>
<classes>
<class name="tests.SignUpTest"/>
</classes>
</test>
</suite>
and finally the two manners I am using to run the test:
mvn -Dwebdriver=chrome -Denv=qa install
mvn -Dwebdriver=chrome -Denv=qa test
EDIT:
BeforeTest and Test:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
public class BaseTest {
protected WebDriver driver;
private WebDriver selectDriver(String driver)
switch (driverString) {
case "chrome":
return new ChromeDriver();
case "firefox":
return new FirefoxDriver();
case "edge":
return new EdgeDriver();
case "safari":
return new SafariDriver();
default:
return new ChromeDriver();
}
}
@BeforeTest(alwaysRun = true)
public void testInit() {
driver = selectDriver(System.getProperty("webdriver"));
}
}
import additions.BaseTest;
import org.testng.Assert;
import org.testng.annotations.Test;
import pages.DashBoardPage;
import pages.LoginPage;
public class LoginTest extends BaseTest {
@Test
public void successfulLogin(){
LoginPage loginPage = new LoginPage(driver);
loginPage
.populateUserName("somename")
.populatePassword("somepassowrd")
.clickLoginButton();
}
}
CodePudding user response:
Since still there is some uncertainty in the question, I'll try to share my thoughts around this.
If I run through the IDE everything works like a charm.
There are several ways how to run this in IDE:
Run the test class.
In this case IDE generates own
testng.xmlwhich not match the example (from the question), so it will not contain anymethod-selectoritems.Run the testng.xml
In
testng.xmlthere ismethod-selectorwhich expectsSystem.getProperty("env")provided. If you run testng.xml from IDE, you have to provide somehow
System.getProperty("env")via IDE settings, otherwise you'll seeorg.testng.TestNGException: javax.script.ScriptExceptionerror.
If I look at testng.xml, I see method-selector, which filter tests by System.getProperty("env").
And If I look at the test:
@Test
public void successfulLogin(){
LoginPage loginPage = new LoginPage(driver);
I see no any group defined for it. So this test cannot be executed with maven command. And it's unclear how it might throw any exception.
If I look at maven command
mvn -Dwebdriver=chrome -Denv=qa test
I cannot see the arg defining which testng xml suite to execute.
I expect the command like:
mvn test -Dwebdriver=chrome -Denv=qa -Dsurefire.suiteXmlFiles="src/test/resources/tests.xml"
Expected behavior
When we execute the maven command:
mvn test -Dwebdriver=chrome -Denv=qa -Dsurefire.suiteXmlFiles="src/test/resources/tests.xml"
method-selector in testng.xml looks for methods matching the qa group.
and there are no any methods, matched this group.
But there are some configuration methods with alwaysRun = true, and they will be executed anyway.
So
@BeforeTest(alwaysRun = true)
public void testInit() {
is invoked without any tests,
and the output will be:
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.345 s - in TestSuite
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.867 s
And the test will be executed if we'll add the group:
@Test(groups= {"qa"})
public void successfulLogin(){
CodePudding user response:
I've solved it. It turns out that initialising the driver with the @BeforeTest annotation is not a good idea, especially if your teardown method is marked with @AfterTest. The driver is initialised and used correctly in the first @Test method, but on the second one, the teardown method is already called and the driver becomes null. So I used @BeforeClass and @AfterClass (I might reconsider and use @Before/AfterSuite). Then I added the following configuration to the pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
Then I added the package with the tests I wanted to execute, in the testng.xml file, like this:
<packages>
<package name="path.to.tests.*"></package>
</packages>
Finally I called the mvn command using the following syntax:
mvn test -Dsurefire.suiteXmlFiles=testng.xml -Dwebdriver="chrome" -Denv="qa"
This way you don't have to call the path to the testng.xml file, but rather call it out of the pom.xml. As a side note to the last sentence, my testng.xml file is located in the project directory, along with the src folder. If you put it in another folder, I guess it will be good to set the path to this folder in the pom.xml
I hope this is understandable and it will be helpful for anyone who gets stuck with such issue.
Thank again to the others for the clues.
