Stack Exchange
"Parameter 'browser' is required by BeforeClass on method beforeClass but has not been marked @Optional or defined" error in maven project
I have a maven project where in I am running testng.xml from pom.xml file.
My testng.xml file looks like below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests">
  <test name="FirefoxTest">
  <parameter name="browser" value="firefox"/>
    <classes>
      <class name="tests.PM_User_Test"/>
    </classes>
  </test> <!-- Test -->

  <test name="ChromeTest">
    <parameter name="browser" value="chrome"/>
    <classes>
      <class name="tests.PM_User_Test"/>
      <class name="tests.PM_Extension_Test"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

and below is my class:
    package base;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;

import utilities.ExcelReadAndWrite;
import utilities.Take_Screenshot;

public class ConfigClass
{
    public WebDriver driver = null;
    public static String excelPath = null;
    public static ExcelReadAndWrite loginData;
    public static ExcelReadAndWrite pmTests;
    public static ExcelReadAndWrite snmTests;
    public static ExcelReadAndWrite ipData;


    @BeforeSuite
    public void beforeSuite()
    {
        excelPath = "C://Users//mallikar//git//PM//PM//src//main//java//myTestData//TestData.xlsx";
        loginData = new ExcelReadAndWrite("logindata", excelPath);
        pmTests = new ExcelReadAndWrite("PMTestData", excelPath);
        snmTests = new ExcelReadAndWrite("SNMTestData", excelPath);
        ipData = new ExcelReadAndWrite("IP", excelPath);
    }

    @AfterSuite
    public void afterSuite() 
    {

    }

    @Parameters({"browser"})
    @BeforeClass
    public void beforeClass(String browser)
    {
        DesiredCapabilities dc = new DesiredCapabilities();
        dc.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
        if(browser.equalsIgnoreCase("firefox"))
        {
            driver = new FirefoxDriver(dc);
        }
        else if(browser.equalsIgnoreCase("chrome"))
        {
            driver = new ChromeDriver();
        }

    }

    /*@Parameters("browser")
    @BeforeClass
    public void beforeClass()
    {
        DesiredCapabilities dc = new DesiredCapabilities();
        dc.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
        driver = new FirefoxDriver(dc);
    }*/

    @AfterClass
    public void afterClass()
    {
        driver.close();
    }

    @BeforeMethod
    public void beforeMethod()
    {
//      driver.get("https://sqa.stackexchange.com/questions/36253/taking-screenshot-on-test-failure-selenium-webdriver-testng");
//      System.out.println(driver);
        driver.manage().window().maximize();
        driver.manage().deleteAllCookies();
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    }

    @AfterMethod
    public void afterMethod(ITestResult result) throws IOException
    {
        if(result.getStatus() == 2)
        {
            String methodName = result.getMethod().getMethodName();
            new Take_Screenshot().get_Screenshot(driver, methodName);
        }
    }
}


But I am getting the "Parameter 'browser' is required by BeforeClass on method beforeClass but has not been marked @Optional or defined" error in maven project.

However when I run only testng.xml file it is absolutely working fine. The pro

blem comes when I run testng.xml from pom.xml file.
Below is the content of POM.xml file where I have defined testng.xml:
<profiles>
    <profile>
        <id>Regression</id>
        <build>
    <plugins>
    <plugin>
        <inherited>true</inherited>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
           <encoding>UTF-8</encoding>
        </configuration>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12.2</version>
        <configuration>                        
          <suiteXmlFiles>
               <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>              
          </suiteXmlFiles>         
        </configuration>       
      </plugin>   
    </plugins>
  </build>
    </profile>
  </profiles>

I have gone through lot of threads about this on internet but I haven't found any solution. Please somebody help me with this.
And below are the console logs when I run mvn clean install command
Running TestSuite
Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@ba4d54
Tests run: 10, Failures: 2, Errors: 0, Skipped: 8, Time elapsed: 2.368 sec <<< FAILURE!
beforeClass(tests.PM_Extension_Test)  Time elapsed: 2.098 sec  <<< FAILURE!
org.testng.TestNGException:
Parameter 'browser' is required by BeforeClass on method beforeClass but has not been marked @Optional or defined

        at org.testng.internal.Parameters.createParams(Parameters.java:289)
        at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:377)
        at org.testng.internal.Parameters.createParameters(Parameters.java:721)
        at org.testng.internal.Parameters.createConfigurationParameters(Parameters.java:164)
        at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:275)
        at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:176)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:122)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at org.testng.TestRunner.privateRun(TestRunner.java:770)
        at org.testng.TestRunner.run(TestRunner.java:591)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
        at org.testng.SuiteRunner.run(SuiteRunner.java:304)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
        at org.testng.TestNG.runSuites(TestNG.java:1032)
        at org.testng.TestNG.run(TestNG.java:1000)
        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:77)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:159)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:106)
        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:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

beforeClass(tests.PM_User_Test)  Time elapsed: 0.002 sec  <<< FAILURE!
org.testng.TestNGException:
Parameter 'browser' is required by BeforeClass on method beforeClass but has not been marked @Optional or defined

        at org.testng.internal.Parameters.createParams(Parameters.java:289)
        at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:377)
        at org.testng.internal.Parameters.createParameters(Parameters.java:721)
        at org.testng.internal.Parameters.createConfigurationParameters(Parameters.java:164)
        at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:275)
        at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:176)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:122)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at org.testng.TestRunner.privateRun(TestRunner.java:770)
        at org.testng.TestRunner.run(TestRunner.java:591)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
        at org.testng.SuiteRunner.run(SuiteRunner.java:304)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
        at org.testng.TestNG.runSuites(TestNG.java:1032)
        at org.testng.TestNG.run(TestNG.java:1000)
        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:77)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:159)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:106)
        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:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)


Results :

Failed tests:   beforeClass(tests.PM_Extension_Test): (..)
  beforeClass(tests.PM_User_Test): (..)

Tests run: 10, Failures: 2, Errors: 0, Skipped: 8

[WARNING] Could not delete temp direcotry C:\Users\mallikar\git\PM\PM\target\surefire because Directory C:\Users\mallikar\git\PM\PM\target\surefire unable to be deleted.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.374 s
[INFO] Finished at: 2019-09-26T16:39:22+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project PM: There are test failures.
[ERROR]
[ERROR] Please refer to C:\Users\mallikar\git\PM\PM\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException


Please try doing one of the following (which should fix your problem )

Make sure that the annotation @Parameters is imported from the package org.testng.annotations
Make sure you adhere to one of the following, when running the test:


If you are running from the IDE, by right clicking on the class and choosing run as TestNG test then make sure that you edit your run configuration and provide the JVM argument -Dbrowser=firefox
If you would like to run the entire suite, then you would need to make sure that you right click on the suite and then run it.
If you are running from the commandline using maven, then make sure that you are using mvn clean test -P Regression (This would ensure that the profile Regression gets activated and through that, the test execution happens via the suite file)



Tried everything but no luck.

Can you please edit your question and add the test sample (full code including imports), mention the TestNG version being used, details on how you are running your tests to trigger the problem (if its via IDE please include screenshots) and if its via maven command line, please include the complete console logs.

I have edited an included full class and I am running from command prompt using command mvn clean install.

@MallikarjunaB - You have included a maven profile in your pom file. so you would need to refer to that pom file, when you are running your tests. That is what I had mentioned in (3). Can you please run mvn clean install -P Regression and tell me what happens ? Please include the complete console output in https://gist.github.com, edit your question and share the link

@MallikarjunaB - Please use mvn clean install -P Regression

WOW!, it worked, is it mandatory to give "Regression" if we are executing testng.xml from pom.xml using sure-fire plugin?

@KrishnanMahadevan - Happy to upvote your answer. This indeed a good learning.

@MallikarjunaB - Because you have added maven profiles to your pom file <profiles> tag in your pom file, you would need to use -P. If you don't want to use it, then get rid of the <profiles> section from your pom file.

For me adding configuration for xml suite inside maven-surefire-plugin worked.
I have added the below configuration.
<plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.12.2</version>
          <configuration>
            <suiteXmlFiles>
              <suiteXmlFile>location-to-testng-xml-file</suiteXmlFile>
            </suiteXmlFiles>
          </configuration>
</plugin>

