Extent report shows only last test case result - java

Extent report version - 3.0
Language - Java and TestNG classes
I have a class - ExtentManager.java
package framewrk;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
public class ExtentManager {
private static ExtentReports extent;
private static ExtentTest test;
private static ExtentHtmlReporter htmlReporter;
private static String filePath = "./extentreport.html";
public static ExtentReports GetExtent(){
extent = new ExtentReports();
htmlReporter = new ExtentHtmlReporter(filePath);
// make the charts visible on report open
htmlReporter.config().setChartVisibilityOnOpen(true);
// report title
String documentTitle = prop.getProperty("documentTitle", "aventstack - Extent");
htmlReporter.config().setDocumentTitle(documentTitle);
}
public static ExtentTest createTest(String name, String description){
test = extent.createTest(name, description);
return test;
}
public static ExtentTest createTest(String name){
test = extent.createTest(name, "");
return test;
}
}
and 2 testNG classes as follows
TC1.java
package framewrk;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
public class TC1 {
static ExtentReports extent;
static ExtentTest test;
#BeforeClass
public void setup(){
extent = ExtentManager.GetExtent();
}
#Test
public void OpenUT(){
test = extent.createTest("Testing how fail works");
test.log(Status.INFO, "fail check started");
test.fail("Test fail");
}
#AfterClass
public void tear()
{
extent.flush();
}
}
TC2.java
package framewrk;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
public class TC2 {
static ExtentReports extent;
static ExtentTest test;
#BeforeClass
public void setup(){
extent = ExtentManager.GetExtent();
}
#Test
public void OpenUT(){
test = extent.createTest("Testing how pass works");
test.log(Status.INFO, "pass check started");
test.pass("Passed");
}
#AfterClass
public void tear()
{
extent.flush();
}
}
If run these 2 test cases, I am getting only last testcase result, for the 1st testcase result, it's not displayed on the extent report.
Note that there is not append parameter for extent report 3.0.
How to get all test case results on extent report?

In the above approach, you are creating a new extent report in each Class. That is why you are getting only the latest executed test result.
You can create a common superclass for both TC1 and TC2 classes. In the superclass you can create #AfterClass and #BeforeClass functions. Then it should work.
Hope it helps!

I got one approach that works well, 1st check if the extent object is already created? if yes then return the object without reinitialising the extent object, here is how it looks
Under the ExtentManager class [as shown in the question], add this code block
public static ExtentReports getInstance() {
if(extent == null) {
GetExtent();
}
return extent;
}
Now under your testNG tests, before class annotation, call the above method
#BeforeClass
public void setup(){
extent = ExtentManager.getInstance();
}

In your case ExtentManager.GetExtent() this method overrides the previously created report hence only the last test result shows up in report. Make sure this method is only called during the whole set of your test start, best way is to do it by implementing ITestListener

Use this method extent.flush() in #aftersuite. because this statement generates the result
{
public class TC1
{
static ExtentReports extent;
static ExtentTest test;
#BeforeClass
public void setup(){
extent = ExtentManager.GetExtent();
}
#Test
public void OpenUT(){
test = extent.createTest("Testing how fail works");
test.log(Status.INFO, "fail check started");
test.fail("Test fail");
}
#Test
public void OpenUT1(){
test = extent.createTest("Testing how pass works");
test.log(Status.INFO, "pass check started");
test.pass("Passed");
}
#aftersuite
public void tear()
{
extent.flush();
}
}

Related

How to keep cucumber Scenario object alive?

How can I create Scenario object in cucumber framework and keep alive through all test run?
First Class:
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import io.cucumber.java.en.Given;
public class TestStepDefinitionOne {
Scenario scenario;
#Before
public void keepScenario(Scenario scenario) {
this.scenario = scenario;
}
Given("First step")
public void first_step() {
// Some code
scenario.log("Some text");
}
Given("Second step")
public void second_step() {
// Some code
scenario.log("Some text");
}
}
Second Class:
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import io.cucumber.java.en.Given;
public class TestStepDefinitionTwo {
Scenario scenario;
#Before
public void keepScenario(Scenario scenario) {
this.scenario = scenario;
}
Given("First step")
public void first_step() {
// Some code
scenario.log("Some text");
}
Given("Second step")
public void second_step() {
// Some code
scenario.log("Some text");
}
}
If I create #Before method in each step definition class everything works fine.
My question: Is there any way to create Scenario object in one place (like Hooks class) and keep it alive through all test run?

Mokito/Java - Static Methods Mock

For example I have the following classes below:
public class TesteEstatico {
public static String teste(){
return "FOO";
}
}
And I have a class that uses her method:
public class UsaTesteEstatico {
public String metodoParaTeste1 (){
return TesteEstatico.teste() + " BAR ";
}
public String metodoParaTeste2 (){
return "FOO "+TesteEstatico.teste() + " BAR ";
}
}
Test class:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
#ExtendWith(MockitoExtension.class) public class UsaTesteEstaticoTest {
#InjectMocks
UsaTesteEstatico usaTesteEstatico;
#Test
void teste1(){
Mockito.mockStatic(TesteEstatico.class);
Mockito.when(TesteEstatico.teste())
.thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
#Test
void teste2(){
Mockito.mockStatic(TesteEstatico.class);
Mockito.when(TesteEstatico.teste())
.thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
Error I get when trying to run the tests:
org.mockito.exceptions.base.MockitoException:
For TesteEstatico, static mocking is already registered in the current thread
To create a new mock, the existing static mock registration must be deregistered
Versions of the libs that are in the project:
junit-jupiter 5.5.2
mockito-junit-jupiter 3.2.14
mockito-inline 3.2.14
Any idea how to solve this, i've tried a few things but nothing successful.
NOTE: I cannot change or add any new libraries as it is a restricted project.
You should use try-with-resources block in each of the tests to close the mockStatic.
public class UsaTesteEstaticoTest {
UsaTesteEstatico usaTesteEstatico = new UsaTesteEstatico();
#Test
void teste1(){
try (var ms = Mockito.mockStatic(TesteEstatico.class)) {
Mockito.when(TesteEstatico.teste()).thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
}
#Test
void teste2(){
try (var ms = Mockito.mockStatic(TesteEstatico.class)) {
Mockito.when(TesteEstatico.teste()).thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
}
Note on mockStatic in #BeforeAll
Using #BeforeAll is a trap and bad advice.
You should strive for independent tests that don't affect each other.
This is not the case for mockStatic called in #BeforeAll, as stubbing from test methods outlive the test methods.
For example
// BAD CODE DONT USE
public class UsaTesteEstaticoTest {
UsaTesteEstatico usaTesteEstatico = new UsaTesteEstatico();
static MockedStatic<TesteEstatico> ms;
#BeforeAll
public static void init() {
ms = Mockito.mockStatic(TesteEstatico.class);
}
#AfterAll
public static void close() {
ms.close();
}
#Test
void teste1() {
Mockito.when(TesteEstatico.teste()).thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
#Test
void teste2() {
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
teste2 prints:
FOO BANANA BAR if run after teste1
FOO null BAR if run separately
This is precisely what you want to avoid.
you need to use static block to mock it.
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
#ExtendWith(MockitoExtension.class)
public class UsaTesteEstaticoTest {
#InjectMocks
UsaTesteEstatico usaTesteEstatico;
#BeforeAll
public static void init(){
Mockito.mockStatic(TesteEstatico.class);
}
#Test
void teste1(){
Mockito.when(TesteEstatico.teste())
.thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
#Test
void teste2(){
Mockito.when(TesteEstatico.teste())
.thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}

junit error: initiallization error: coused an error: no rannable method

I am having this error while all my methods in this test are successful - all of them return true. Also tried to make boolean for each method call and use only one call for assertTrue(a && b && c && d && e).
I run the junit test in java - netbeans.
My junit code (first time using junit) is:
package redis_fast_algo;
import data_sets.FastSortAlgoData;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class FastSortAlgoStudyTest {
private DataMaker dataMake;
private final static boolean BEFORE_DELETE = false;
public FastSortAlgoStudyTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
dataMake = new DataMaker();
}
#After
public void tearDown() {
}
/**
* Test of study method, of class FastSortAlgoStudy.
*/
#Test
public void testStudy() throws Exception {
System.out.println("study");
FastSortAlgoData data = dataMake.getData(5);
FastSortAlgoStudy instance = new FastSortAlgoStudy(data);
FastSortAlgoTest testStudy = new FastSortAlgoTest(data);
testStudy.prepareForTest();
instance.study();
assertTrue(testStudy.testCheckFolderStudyCounter(BEFORE_DELETE));
assertTrue(testStudy.testCheckBodyPart(BEFORE_DELETE));
assertTrue(testStudy.testCheckTitlePart(BEFORE_DELETE));
assertTrue(testStudy.testCheckFoldersHistoryWithData(BEFORE_DELETE));
assertTrue(testStudy.testRemoveFolderHistory());
}
}

calling multiple methods within a method - selenium webdriver cross browser testing

I have a question with regards to calling multiple method using JUNIT. This is my test
package com.example.tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.testng.annotations.Test;
public class test {
private WebDriver _driver;
#Test
public void FFconfiguration() throws Exception {
System.out.println("Running FF");
_driver = new FirefoxDriver();
_driver.get("URL");
login();
setup();
_driver.quit();
}
public void login1()
{
}
public void setup()
{
}
}
My question is: Can I call both login() and setup() within the method FFConfiguration? If not what's the alternate solution...............
Yes, absolutely, you can do it. You can have tests like this:
#Test
public void testBuyingProcess(){
ShoppingUI shoppingPage = new ShoppingUI();
shoppingPage.login();
Assert.assertEquals(shoppingPage.getTitle(),"Welcome");
//....
}
And fill in the methods elsewhere even in different class. Few examples of methods used above:
public class ShoppingUI{
private WebDriver driver
public ShoppingUI(){
driver = new FirefoxDriver();
driver.get("http://my-test-site.com/buy-buy-buy.html");
}
public String getTitle(){
return driver.getTitle();
}
}

PowerMock: How to unmock a method?

I have a static method that is mocked using PowerMock to throw an exception. (It deletes files.) Unfortunately, during my #After (after-each-test) method, I need to call this method without the mocks. How can I umock a method?
I don't see an equivalent to Mockito.reset(). [ Ref: mockito : how to unmock a method? ]
Example:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PathUtils.class) // Important: This class has a static method we want to mock.
public class CleaningServiceImplTest2 extends TestBase {
public static final File testDirPath = new File(CleaningServiceImplTest2.class.getSimpleName());
#BeforeClass
public static void beforeAllTests() throws PathException {
recursiveDeleteDirectory(testDirPath);
}
#AfterClass
public static void afterAllTests() throws PathException {
recursiveDeleteDirectory(testDirPath);
}
private File randomParentDirPath;
private CleaningServiceImpl classUnderTest;
#Before
public void beforeEachTest() {
randomParentDirPath = new File(testDirPath, UUID.randomUUID().toString()).getAbsoluteFile();
classUnderTest = new CleaningServiceImpl(randomParentDirPath);
}
#After
public void afterEachTest() throws PathException {
recursiveDeleteDirectory(randomParentDirPath);
}
public static void recursiveDeleteDirectory(File dirPath) throws PathException {
// calls PathUtils.removeFile(...)
}
#Test
public void run_FailWhenCannotRemoveFile() throws IOException {
// We only want to mock one method. Use spy() and not mockStatic().
PowerMockito.spy(PathUtils.class);
// These two statements are tightly bound.
PowerMockito.doThrow(new PathException(PathException.PathExceptionReason.UNKNOWN, randomParentDirPath, null, "message"))
.when(PathUtils.class);
PathUtils.removeFile(Mockito.any(File.class));
classUnderTest.run();
}
}
This took me a while to figure out, so I am answering my own question.
AFAIK, you need to "undo" each mock. Mockito.reset() will not work with Class<?> references. At the end of the test method, add:
// Undo the mock above because we need to call PathUtils.removeFile() within #After.
PowerMockito.doCallRealMethod().when(PathUtils.class);
PathUtils.removeFile(Mockito.any(File.class));
The only way you can undo mocking of a static method with PowerMock is when you mock a class at the beginning of a test and then undo the mock at the end of a test. It doesn't matter if you use SPY or a regular mocking.
Tested with:
"org.powermock" % "powermock" % "1.5" % Test,
"org.powermock" % "powermock-api-mockito" % "1.6.1" % Test,
Test class
package mytests;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.fest.assertions.Assertions.assertThat;
#RunWith(PowerMockRunner.class)
#PrepareForTest({StaticTest.class})
public class TestTest {
#Before
public void checkIfOriginalMethodGetsCalled() {
// PowerMockito.mockStatic(StaticTest.class); if you do this in #Before you are not going to be able to undo it
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
}
#Test
public void test1() {
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
}
#Test
public void test3_mocking() {
mock(); // mock or spy static methods in a test, not in #Before
Mockito.when(StaticTest.staticMethod()).thenReturn("MOCKED VALUE");
assertThat(StaticTest.staticMethod()).isEqualTo("MOCKED VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
undoMock(); // undo the mock at the end of each test, not in #After
}
private void mock() {
// PowerMockito.mockStatic(StaticTest.class); both, spy and mockStatic work ok
PowerMockito.spy(StaticTest.class);
}
private void undoMock() {
PowerMockito.doCallRealMethod().when(StaticTest.class);
assertThat(StaticTest.staticMethod()).isNull(); // the undo is going to work in the next test, not here yet.
}
#Test
public void test2() {
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
}
#After
public void checkIfOriginalMethodGetsCalled_AfterMockUndo() {
// undoMock(); in #After doesn't work with static methods
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
}
}
class StaticTest {
public static String staticMethod() {
return "ORIGINAL VALUE";
}
public static String otherStaticMethod() {
return "SPY TEST ORIGINAL";
}
}

Categories