I am using Selenium, Java and TestNG to write tests. Sometimes I use many soft assertions in my unit tests and when they fail the TestNG reporter does not show the line of the code that they happened. Is there any way to make it show that? actually when I click on the report at Failure Exception
it takes me to s_assert.assertAll();
but I need to be taken to the specific lines, such as: s_assert.assertEquals(Alert_text, "Hi.. is alert message!", "Alert Is InCorrect");
Asked
Active
Viewed 5,160 times
3

LoveLovelyJava one
- 343
- 1
- 3
- 16
-
I think, you shouldn't "spare" your work in this way(it is a very bad style), but to create a good messages instead. If your asserts are really too dull and similar to write sensible messages, create an Integer dullAssertNum at start of method and include "assert"+(dullAssertNum++).toString into every dull assert. – Gangnus Nov 22 '17 at 21:17
-
You'll ask why is it a bad style? Because you can need pointing the line number only if you have MANY lines in one test method. And it is not a bad style only in the case of generated file. And in the generated file you can generate the line number and insert it into the message. – Gangnus Nov 22 '17 at 21:21
3 Answers
4
The below implementation of a custom Soft Assertion (I have named it Verifier) should do what you are asking for.
import org.testng.annotations.Test;
import org.testng.asserts.Assertion;
import org.testng.asserts.IAssert;
import org.testng.collections.Maps;
import java.util.Arrays;
import java.util.Map;
public class SoftAssertExample {
private Verifier verifier = new Verifier();
@Test
public void testMethod() {
verifier.assertEquals(false, true);
verifier.assertTrue(true);
verifier.assertAll();
}
/**
* A simple soft assertion mechanism that also captures the stacktrace to help pin point the source
* of failure.
*/
public static class Verifier extends Assertion {
private final Map<AssertionError, IAssert<?>> m_errors = Maps.newLinkedHashMap();
@Override
protected void doAssert(IAssert<?> a) {
onBeforeAssert(a);
try {
a.doAssert();
onAssertSuccess(a);
} catch (AssertionError ex) {
onAssertFailure(a, ex);
m_errors.put(ex, a);
} finally {
onAfterAssert(a);
}
}
public void assertAll() {
if (! m_errors.isEmpty()) {
StringBuilder sb = new StringBuilder("The following asserts failed:");
boolean first = true;
for (Map.Entry<AssertionError, IAssert<?>> ae : m_errors.entrySet()) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append("\n\t");
sb.append(ae.getKey().getMessage());
sb.append("\nStack Trace :");
sb.append(Arrays.toString(ae.getKey().getStackTrace()).replaceAll(",", "\n"));
}
throw new AssertionError(sb.toString());
}
}
}
}

Krishnan Mahadevan
- 14,121
- 6
- 34
- 66
-
It would be nice to have this as a feature of testng, rather than creating custom class for it. – MasterJoe Feb 22 '19 at 05:52
-
Getting issue with IAssert> a-- org.testng.assert.IAssert does not have type parameter. Please correct me.. – Ajeet Yadawa Mar 19 '20 at 04:59
2
This is a delayed answer but figured I would share my solution since I was having the same issue.
The following prints out where the line failure was for the soft assertion. It shows the line failure inside of the method for the class being used as shown below:
1)
Error: Custom error message goes here
[Class -> path.to.class.shows.here.ExampleClassName]
[Method -> exampleMethod]
[Line -> 342]
Example Code for this solution:
public void assertIsTrueSoftly(String errorMsg, boolean condition) {
String trace = null;
if (!condition) {
Throwable throwable = new Throwable();
trace =
String.format(
"[Class -> %s]%n[Method -> %s]%n[Line -> %d]",
throwable.getStackTrace()[1].getClassName(),
throwable.getStackTrace()[1].getMethodName(),
throwable.getStackTrace()[1].getLineNumber());
}
soft.assertThat(condition).withFailMessage(format("%nError: %s%n%s", errorMsg, trace)).isTrue();
}

Sean F
- 128
- 7
0
Example code:
s_assert.assertEquals(Alert_text, "Hi.. is alert message!", "Alert Is InCorrect1");
s_assert.assertEquals(Alert_text, "Hi.. is alert message!", "Alert Is InCorrect2");
s_assert.assertEquals(Alert_text, "Hi.. is alert message!", "Alert Is InCorrect3");
s_assert.assertEquals(Alert_text, "Hi.. is alert message!", "Alert Is InCorrect4");
s_assert.assertall();
After execution fails it points to (s_assert.assertall();)
line, mean time it shows message which soft assert is failed....
Alert Is InCorrect2
Alert Is InCorrect3
Please check output.

Uwe Allner
- 3,399
- 9
- 35
- 49

Manjunatha.N
- 45
- 5
-
-
it shows which soft assert failed and its message "Alert Is InCorrect2" ; – Manjunatha.N May 17 '16 at 06:55