TestNg + ExtentReport: исключение нулевого указателя при выполнении 2 классов через testng.xml - когда я использую отчет Extent в @BeforeSuite - PullRequest
0 голосов
/ 09 сентября 2018

ExtentReports report;
ExtentTest logger;
Код работает правильно для 1 класса, но выдает исключение нулевого указателя для 2-го класса, когда я использую отчет Extent
1. Я инициализирован в @ BeforeSuite
2. Затем инициализирован в @BeforeMethod
3. В testng.xml существует 2 класса Class1 и Class2
4. При выполнении testng.xml - все @Test класса1 выполняется полностью, но Class2 выдает ошибку исключения нулевого указателя при чтении в BeforeMethod (инициализируется, как указано в шаге 2)

Отчет по экстентам был инициализирован в классе Testbase и создан для него getter , чтобы другой класс мог его прочитать
Примечание: Когда я изменяю BeforeSuite на BeforeClass, т.е. инициализация выполняется в BeforeClass, тогда он запускаетсяштраф , но выдает отчет о степени только class1.

Также я использую Aftermethod для очистки отчета и выхода из драйвера.Любое решение, чтобы избавиться от этого исключения нулевого указателя

Ниже приведен полный код
1.Класс TestBase

package sampletestproject;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import 
 org.openqa.selenium.chrome.ChromeDriver;
import 
org.openqa.selenium.firefox.FirefoxDriver;
import 
org.openqa.selenium.support.PageFactory;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeSuite;



public class TestBasee {
    private ExtentReports report;   
    public WebDriver driverObj;
    public Homepagee homeObj;

@BeforeSuite (alwaysRun = true)
public void beforeTest(){
    System.out.println("In @BeforeSuite");
    report = new ExtentReports("G:\\ExtentReport"+fn_GetTimeStamp()+".html");
    System.out.println("Out @BeforeSuite");
}



@AfterClass(alwaysRun = true)
public void tearDown(ITestContext context) throws IOException, InterruptedException{
    System.out.println("@AfterClass In tear down");
    ITestNGMethod[] tngMethods  = context.getAllTestMethods();
    int i=1;
    for(ITestNGMethod tng: tngMethods){         
        String methodName = "Method"+i+": "+ tng.getMethodName();
        i++;
        System.out.println(methodName);
    }
}
public static String fn_GetTimeStamp() {
    DateFormat DF = DateFormat.getDateTimeInstance();
    String DateVal = DF.format(new Date());
    DateVal = DateVal.replaceAll("/", "_");
    DateVal = DateVal.replaceAll(",", "_");
    DateVal = DateVal.replaceAll(":", "_");
    DateVal = DateVal.replaceAll(" ", "_");
    return DateVal;
}
                /******************** Open Site **************************/
public Homepagee gm_OpenApp(String BrowserName, String URL) throws Exception {
    System.out.println("In gm_OpenAp Method");
    System.out.println(BrowserName+" -- "+URL);     
    gm_LaunchBrowser(BrowserName);
    Thread.sleep(2000);
    gm_OpenURL(URL);
    Thread.sleep(2000);
    homeObj = PageFactory.initElements(driverObj, Homepagee.class);
    return homeObj;
}
public void gm_OpenURL(String URL) {
    driverObj.get(URL);
}   
public void gm_LaunchBrowser(String browserName) throws Exception{
    // Launch Chrome browser
     if (browserName.equalsIgnoreCase("CH") == true) {
         System.setProperty("webdriver.chrome.driver", "MasterFiles\\Drivers\\ChromeDriver\\Chromedriver_win32_v2.38\\chromedriver.exe");
        driverObj = new ChromeDriver();
     }
     // Launch Firefox browser
     else if (browserName.equalsIgnoreCase("FF") == true) {
         System.setProperty("webdriver.gecko.driver", "MasterFiles\\Drivers\\GeckoDriver\\64Bit\\v20\\geckodriver.exe");
         driverObj = new FirefoxDriver();
     }
     driverObj.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
     driverObj.manage().timeouts().pageLoadTimeout(250, TimeUnit.SECONDS);
     driverObj.manage().window().maximize();

}
                            /****************TAKE SCREENSHOT*****************/
public String gm_setScreenshotPath_forExtentReporting(String elementName, String resultStatus) {
    System.out.println("In gm_setScreenshotPath_forExtentReporting");
    System.out.println(elementName + "--" + resultStatus);
    String screenshotPath = "G:\\QA\\AutomationTools\\Selenium\\WorkspaceMars1\\1.2hp.com.automationprac\\TestReports\\ExtentReport\\Screenshots\\"+ resultStatus + "\\" + elementName + "_" + fn_GetTimeStamp() + ".png";
    return screenshotPath;
}
public void gm_TakeSnapshot(String destFilePath) throws IOException, InterruptedException {
    TakesScreenshot tss = (TakesScreenshot) driverObj;
    File srcfileobj = tss.getScreenshotAs(OutputType.FILE);
    File destFileObj = new File(destFilePath);
    FileUtils.copyFile(srcfileobj, destFileObj);

}
public ExtentReports getReport() {
    return report;
}


public void setReport(ExtentReports report) {
    this.report = report;
  }

  }

2.Объект входа в систему

package sampletestproject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class SignInPagee extends TestBasee{
@FindBy(xpath = "//div[@id = 'center_column']/h1")
 public static WebElement PageHeading_SignIn_txt;

 @FindBy(xpath = "//h3[contains(text(), 'Already registered?')]")
 public static WebElement SectionHeading_SignIn_txt;


    public SignInPagee(WebDriver driverObj){
        this.driverObj = driverObj;      
    }

  }

3.Домашняя страница - PageObject

package sampletestproject;
import java.io.IOException;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit; 
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import 
org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import 
org.openqa.selenium.support.PageFactory;
import 
org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import 
import com.google.common.base.Function;

public class Homepagee extends TestBasee {


public Homepagee(WebDriver driverObj){
      this.driverObj = driverObj;
  }

 public SignInPagee navigateToSignInPage(){
     System.out.println("In navigateToSignInPage"); 
     driverObj.navigate().to("http://automationpractice.com/index.php?controller=authentication&back=my-account");
     SignInPagee signInPageObj = PageFactory.initElements(driverObj, SignInPagee.class);
     return signInPageObj;
   }


}

4.HomepageTest -Testpage

package sampletestproject;
import java.lang.reflect.Method;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;

public class HomepageeTest extends TestBasee {
    //ExtentReports report;
    ExtentTest logger;
    String elementName;
    String Comment;
    String actualResult;
    String expectedResult;



    @BeforeMethod(alwaysRun = true)
    @Parameters({ "Browser", "URL"})
    public void getBrowser(Method method, String Browser, String URL) throws Exception{
        logger = getReport().startTest((this.getClass().getSimpleName()+"::"+method.getName()), method.getName());
        logger.assignAuthor("VK");
        logger.assignCategory("HomePage - Smoketesting and TextTesting--Live");
        homeObj = gm_OpenApp(Browser, URL);             

    }
     @AfterMethod (alwaysRun = true)
        public void publishReport_SIP(ITestResult result) throws Exception{
            System.out.println("publishReport_SIP");
            String resultStatus = null;         
            if(result.getStatus() == ITestResult.FAILURE){              
                resultStatus = "FAILED"; 
                String screenshot_Path = gm_setScreenshotPath_forExtentReporting(elementName, resultStatus);            
                gm_TakeSnapshot(screenshot_Path);               
                String image = logger.addScreenCapture(screenshot_Path);
                logger.log(LogStatus.FAIL, Comment, image);
            }else{              
                resultStatus = "PASSED";                
                String screenshot_Path = gm_setScreenshotPath_forExtentReporting(elementName, resultStatus);
                gm_TakeSnapshot(screenshot_Path);
                System.out.println("screenshot_Path: "+screenshot_Path);
                String image = logger.addScreenCapture(screenshot_Path);
                logger.log(LogStatus.PASS, Comment, image);
            }
            getReport().endTest(logger);
            getReport().flush();
            System.out.println("closing now_SIP.");
            driverObj.quit();
        }       

//"********Validation of SignIn Link********");
@Test(priority=0, groups = {"Smoke"})   
public  void validateHeaderSignInLink_HP() throws Exception{        
    System.out.println("In validateHeaderSignInLink Method_HP"); 
    elementName = "SignInLink";
    Comment = "validateHeaderSignInLink";
    actualResult = "http://automationpractice.com/index.php?controller=authentication&back=my-account";
    expectedResult = "http://automationpractice.com/index.php?controller=authentication&back=my-account";
    Assert.assertEquals(actualResult, expectedResult);
    System.out.println("Out  of validateHeaderSignInLink method_HP");
}       

//"********Validation of GetSavingNow Button********");
@Test (priority = 1, groups = {"Smoke"})
public  void validateGetSavingNowButton_HP() throws Exception{
    System.out.println("In validateGetSavingNowButton Method_HP");
    elementName = "GETSAVINGSNOWButton";        
    Comment = "validateGetSavingNowButton"; 
    expectedResult = "http://automationpractice.com/index.php";
    actualResult = "http://automationpractice.com/index.php";
    Assert.assertEquals(actualResult, expectedResult);      
    System.out.println("Out  of validateGetSavingNowButton method_HP");
}   

@Test (priority = 2, groups = {"UITest"})
//"********Validation of SearchBox********");
public  void validateSearchField_HP() throws Exception{
    System.out.println("In validateSearchField Method_HP");     
    elementName = "FadedShortSleeveTshirts_lnktxt";     
    Comment = "validateSearchField";        
    actualResult = "Faded Short Sleeve T-shirtss";  //Just to produce a failed result
    expectedResult = "Faded Short Sleeve T-shirts";
    Assert.assertEquals(actualResult, expectedResult);
    System.out.println("Out  of validateSearchField method_HP");
}


 @Test (priority = 3, enabled = true, groups = {"Smoke", "UITest"})
//"********Validation of Slider1********");  
public  void validateHomepageSlider1_HP() throws Exception{
    System.out.println("In validateHomepageSlider1 Method_HP"); 
    elementName = "Homepage Slider1";
    Comment = "validateHomepageSlider1";
    actualResult =  "https://www.prestashop.com/en?utm_source=v16_homeslider";
    expectedResult = "https://www.prestashop.com/en?utm_source=v16_homeslider";
    Assert.assertEquals(actualResult, expectedResult);  
    System.out.println("Out  of validateHomepageSlider1 method_HP");

    }   

  }

5.SignIntest Class- Testpage
package sampletestproject;

import java.lang.reflect.Method;

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import 
com.relevantcodes.extentreports.ExtentTest;
import 
com.relevantcodes.extentreports.LogStatus;

public class SignInnTest extends TestBasee{



SignInPagee lognObj;    
ExtentTest logger;
String elementName;
String Comment;
String expectedResult;
String actualResult;

@BeforeMethod(alwaysRun = true)
@Parameters({ "Browser", "URL"})
public void getBrowser(Method method, String Browser, String URL) throws Exception{
    logger = getReport().startTest((this.getClass().getSimpleName()+"::"+method.getName()), method.getName());
    logger.assignAuthor("VK");
    logger.assignCategory("SignInpage - Smoketesting and TextTesting--Live");
    homeObj = gm_OpenApp(Browser, URL);             
    lognObj = homeObj.navigateToSignInPage();           
}

 @AfterMethod (alwaysRun = true)
    public void publishReport_SIP(ITestResult result) throws Exception{
        System.out.println("publishReport_SIP");
        String resultStatus = null;         
        if(result.getStatus() == ITestResult.FAILURE){              
            resultStatus = "FAILED"; 
            String screenshot_Path = gm_setScreenshotPath_forExtentReporting(elementName, resultStatus);            
            gm_TakeSnapshot(screenshot_Path);               
            String image = logger.addScreenCapture(screenshot_Path);
            logger.log(LogStatus.FAIL, Comment, image);
        }else{              
            resultStatus = "PASSED";                
            String screenshot_Path = gm_setScreenshotPath_forExtentReporting(elementName, resultStatus);
            gm_TakeSnapshot(screenshot_Path);
            System.out.println("screenshot_Path: "+screenshot_Path);
            String image = logger.addScreenCapture(screenshot_Path);
            logger.log(LogStatus.PASS, Comment, image);
        }
        getReport().endTest(logger);
        getReport().flush();
        System.out.println("closing now_SIP.");
        driverObj.quit();
    }        
@Test (priority = 0, groups = {"Smoke""})
public  void validateSignInPage_PageHeading_SIP() throws Exception{
    System.out.println("In validateSignInPage_PageHeading Method_SIP");                 
    elementName = "SignIn_PageHeading_txt";     
    Comment = "validatePageHeading_SignInpage";     
    actualResult =  "AUTHENTICATION";           
    expectedResult = "AUTHENTICATION";
    Assert.assertEquals(actualResult, expectedResult);  //Here test will pass
    System.out.println("Out  of validateSignInPageHeading method_SIP");
}   

@Test (groups = {"UITest"}, dependsOnMethods = { "validateSignInPage_PageHeading_SIP" })
public  void validateSignInPage_SignInSectionHeading_SIP() throws Exception{
    System.out.println("In validateSignInPage_SignInSectionHeading Method_SIP");        
    elementName = "SignInPage_SignInSectionHeading_txt";        
    Comment = "validateSectionHeading_SignInpage";      
    actualResult =  "ALREADY REGISTERED1?"; 
    expectedResult = "ALREADY REGISTERED?";
    Assert.assertEquals(actualResult, expectedResult); //Here Test will fail as actual not equal to expected
    System.out.println("Out  of validateSignInPage_SignInSectionHeading method_SIP");
     }  
 }

6.testng.xml suite name = "Test "rallel =" tests "thread-count =" 1">

<test name="CHTest"  >   
    <parameter name="Browser" value="CH" ></parameter>
    <parameter name="URL" value="http://automationpractice.com/index.php"></parameter>          
      <groups><run>         
            <include name="Smoke"/>
            <include name="UITest"/>                 
        </run></groups>             
    <classes>
        <class name= "sampletestproject.SignInnTest" /> 
        <class name= "sampletestproject.HomepageeTest"/>
    </classes></test></suite>

1 Ответ

0 голосов
/ 09 сентября 2018

Я бы сказал, что лучше использовать локальный поток или реализацию, аналогичную реализации для управления тестами, и аналогичную для ExtentReports:

https://github.com/anshooarora/extentreports-java/blob/master/src/test/java/com/aventstack/extentreports/common/ExtentTestManager.java

Кроме того, если вы видите раздел с примерами документов, у вас уже есть базовый пример ExtentTestNGReportBuilder, который вы можете использовать, не создавая никакого пользовательского кода, как здесь.

Проблема, с которой вы сталкиваетесь, связана с ценовыми принципами Java и управления экземплярами, а не ExtentReports. Если вам нужен один отчет для всех ваших классов, убедитесь, что всегда есть 1 экземпляр только для всего цикла. Предотвратите любое поведение, которое воссоздает экземпляры, которые происходят в вашем случае - каждый класс сбрасывает переменную отчета, таким образом сбрасывая экземпляр ExtentReports.

Более того, я бы порекомендовал использовать ITestListener в таких случаях, и пример этого показан ниже, чтобы отделить отчетность от вашего тестового кода:

public class ExtentITestListener
implements ITestListener {

private static final ExtentReports EXTENT = Extent.getInstance();

private static ThreadLocal<ExtentTest> methodTest = new ThreadLocal<ExtentTest>();
private static ThreadLocal<ExtentTest> dataProviderTest = new ThreadLocal<>();

@Override
public synchronized void onStart(ITestContext context) { }

@Override
public synchronized void onFinish(ITestContext context) {
    EXTENT.flush();
}

@Override
public synchronized void onTestStart(ITestResult result) {      
    String methodName = result.getMethod().getMethodName();
    if (result.getParameters().length>0) {
        if (methodTest.get() != null && methodTest.get().getModel().getName().equals(methodName)) { } 
        else {
            createTest(result);
        }
        String paramName = Arrays.asList(result.getParameters()).toString();
        ExtentTest paramTest = methodTest.get().createNode(paramName);
        dataProviderTest.set(paramTest);
    } else {
        createTest(result);
    }
}

private void createTest(ITestResult result) {
    String methodName = result.getMethod().getMethodName();
    ExtentTest test = EXTENT.createTest(methodName);
    methodTest.set(test);

    String[] groups = result.getMethod().getGroups();
    if (groups.length > 0) {
        Arrays.asList(groups)
            .forEach(x -> methodTest.get().assignCategory(x));
    }
}

@Override
public synchronized void onTestSuccess(ITestResult result) {
    getTest(result).pass("Test passed");
}

private ExtentTest getTest(ITestResult result) {
    ExtentTest t = result.getParameters() != null && result.getParameters().length>0
            ? dataProviderTest.get()
            : methodTest.get();
    return t;
}

@Override
public synchronized void onTestFailure(ITestResult result) {
    getTest(result).fail(result.getThrowable());
}

@Override
public synchronized void onTestSkipped(ITestResult result) {
    getTest(result).skip(result.getThrowable());
}

@Override
public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult result) { }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...