not getting SoftAssert.assertAll() functionality

402 views
Skip to first unread message

garvitag...@gmail.com

unread,
Nov 29, 2017, 4:09:20 AM11/29/17
to testng-users
Hi, 

I am using soft assertion as :

In base class i have declared object of SoftAssert class :

Class Base
{
SoftAssert softassert = new SoftAssert();
}

Class Util
{

 createchart(parameter1)
     { 
       // chart is created
       verifyLabels();
       verifyTooltips();
//   softassert.assertAll(); ----- if i use here, test does not go to next createchart();
      }
    
public void verifyLabels()
     {
       softassert.AssertTrue("actual","expected","message");
     }
}

Class PieChart
{
@Test
    public void makePieChart()
      {
        Util util = new Util();
        util.createchart("comapny");
        util.createchart("year");
// softassert.assertAll()   ------ it does not report failure
      }
}

Now i tried using softassert.assetAll() at 2 places :
1. Last line in createchart() method, it works fine. If verifyLabels() fail, still verifyTooltip() executes. But In PieChart class, if 1st craetechart() fails , next is not executed.

2. Last line in PieChart class as i want chart is created for all parameters , then it should report failure. It doe snot report any failure.


Am i using it incorrectly or this is how it should work ?

Thanks!!



⇜Krishnan Mahadevan⇝

unread,
Nov 29, 2017, 4:12:42 AM11/29/17
to testng...@googlegroups.com
The basic idea is : Every @Test method has its own SoftAssert variable. Please donot share the SoftAssert variable across multiple @Test methods by defining it as a data member of the class.

SoftAssert tends to remember all the assertions done so far, so if you had assertion failures in method1 and if you used the same SoftAssertion object in method2, then method2() will also fail, even though it didn't have any failures.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to testng...@googlegroups.com.
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

garvitag...@gmail.com

unread,
Nov 29, 2017, 4:33:07 AM11/29/17
to testng-users
Thank you for explaining !!

I tried implementing again, made a new object in Util class where actually assertion is done in verifyLabels() method. Created new object in pie chart class where i want to use assertAll();

I intentionally failed assertion in VerifyLabels() method. In this case, both createchart() are executed in PieChart class but assertion failure is not reported. Test case is passed. 

Is there a way, so that i can report all failures in end of PieChart class?

Thanks !! 
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.

oleksandr...@gmail.com

unread,
Dec 1, 2017, 3:18:24 PM12/1/17
to testng-users
It seems you created 2 different instances of softassert - first in PieChart  class and second in VerifyLabels. Each of those instances collects own errors. That's why you assertion failure is not reported. To fix this you need to use SAME instance for verifications and for assertAll(). To do this you need to pass it into every method which make verifications:

Class Util{
 
    static void createchart(SoftAssert sa, String parameter1){ 
       //chart is created
       verifyLabels(sa);
       verifyTooltips(sa);
    }
    
static void verifyLabels(SoftAssert sa){
        sa.AssertTrue("actual","expected","message");
    }
}

Class PieChart{

    @Test
    public void makePieChart(){
    SoftAssert sa = new SoftAssert();
        Util.createchart(sa, "comapny");
        Util.createchart(sa, "year");
sa.assertAll();
    }
}

BTW good practice is to use asserts only in @Test - methods.

If you don't like to pass softAsserts everywhere you can write something like this:


public class AssertsListener implements IInvokedMethodListener {

@Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
Asserts.clear();
}


@Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
try {
Asserts.assertAll();
} catch (AssertionError ae) {
Throwable error = testResult.getThrowable();
if (error == null)
testResult.setThrowable(ae);
else
testResult.setThrowable(new RuntimeException(
String.format("%s. \nOther errors: %s", error, ae)));

if (error instanceof SkipException)
testResult.setStatus(ITestResult.SKIP);
else
testResult.setStatus(ITestResult.FAILURE);
}
}
}

import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;

class Asserts {

private final static ThreadLocal<SoftAssert> SA_CONTAINER =
new ThreadLocal<>();

public static void clear() { SA_CONTAINER.set(new SoftAssert());}

public static SoftAssert save() { return SA_CONTAINER.get();}

public static void assertAll() {
try {
SA_CONTAINER.get().assertAll();
} finally {
clear();
}
}
}


@Listeners(AssertsListener.class)
public class MyTests {

@Test()
void myTest() {
Asserts.clear(); // optional with AssertsListener
String actual = "222";
Asserts.save().assertEquals(actual, "111");
Asserts.save().assertEquals(actual, "222");
Asserts.save().assertEquals(actual, "333");
//Asserts.assertAll(); // optional with AssertsListener
}
}



среда, 29 ноября 2017 г., 11:33:07 UTC+2 пользователь garvitag...@gmail.com написал:

garvitag...@gmail.com

unread,
Dec 6, 2017, 5:54:13 AM12/6/17
to testng-users
Thanks, using same object worked to collect assertion. Will try implementing using listeners.
Reply all
Reply to author
Forward
0 new messages