Using softAssert and "hard" Asserts together, softAsserts are swallowed by the "hard" Asserts

Aperta
#12 14 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
20/100
Tipo di issue
Bug
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
java
Ambito
testing

Direzione di ricerca

La issue fornisce una riproduzione in Java che usa SoftAssert, MySoftAssert, MyHardAssert e SoftAssertListener, ma non indica file o test del repository. Inizia riproducendo il comportamento su TestNG 7.1.0 con un'asserzione hard prima di assertAll, quindi esamina la discussione di 14 commenti per determinare il ciclo di vita previsto delle asserzioni e se sia stato effettivamente concordato un cambiamento manutenibile al progetto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

TestNG Version

7.1.0, latest from the maven repo https://mvnrepository.com/artifact/org.testng/testng

Issue

This issue is (probably) not one with testng per se but rather an architectural problem I have using testng and softAssertions. I found a solution and my questions are if there is a better solution to this and if there is a reason why I should not use my solution to this problem.

Essentially what I am doing is this:

softAssert.fail("SoftAssert fail");
assert.fail("assert fail");
softAssert.assertAll();

What happens is that assert.fail("assert fail"); obviously fails and the exception is shown as java.lang.AssertionError: assert fail but the softAssertion is never evaluated because of the Exception. The softAssertions will never be shown until the normal assert does not fail. But I want the failed softAsserts to be shown as well.

So what I ended up doing is this:
Simply extend SoftAssert so I can use the "doAssert" method, because it is protected in the original class.

public class MySoftAssert extends SoftAssert {
    @Override
    protected void doAssert(IAssert<?> a) {
        super.doAssert(a);
    }
}

Then define a HardAssert class, which also passes all asserts to 'the' softAssert object used by the tests to do assertions, and when the hardAssert fails it automatically evaluates all the softAsserts, which also includes the just done hardAssertion.

public class MyHardAssert extends SoftAssert {
    private final MySoftAssert softAssert;

    public MyHardAssert(MySoftAssert softAssert){
        this.softAssert = softAssert;
    }

    @Override
    public void onAssertFailure(IAssert<?> assertCommand, AssertionError ex) {
        super.onAssertFailure(assertCommand, ex);
        softAssert.assertAll("Hard Assert failed, also showing all soft asserts that failed before:");
    }

    @Override
    protected void doAssert(IAssert<?> a) {
        softAssert.doAssert(a);
        super.doAssert(a);
    }
}

Now I can do this:

softAssert = new MySoftAssert();
hardAssert = new MyHardAssert(softAssert);
softAssert.fail("softAssert fail");
hardAssert.fail("hardAssert fail");
...

and it will show both asserts as being failed.

java.lang.AssertionError: The following asserts failed:
	softAssert fail
	hardAssert fail

What I am also using is a test wrapper/listener that automatically evaluates all softAsserts at the end, but it is not called when the tests fail because of a 'normal' assertion. That wrapper and the hardAssert is inspired by code I found here: https://github.com/cbeust/testng/issues/1038#issuecomment-217466619

public class SoftAssertListener implements IHookable {

    @Override
    public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {
        iHookCallBack.runTestMethod(iTestResult);
        Class<?> testClass = iTestResult.getTestClass().getRealClass();
        Field field = null;
        SoftAssert softAssert = null;
        try {
            field = testClass.getField("softAssert");
            field.setAccessible(true);
            softAssert = (SoftAssert) field.get(iTestResult.getInstance());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }

        if(softAssert != null) {
            softAssert.assertAll();
        }
    }
}
Is the issue reproductible on runner?
  • IntelliJ
Lingua principale
Java
Stelle
0
Fork
0
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di testng-team/testng-asserts

Tutte le issue di testng-team/testng-asserts

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.