2017-12-21 7 views
0

Lets sagen, ich habe zwei Klassentestng-failed.xml keine Methoden enthalten, die mit immer laufen = true

Class A 
{ 
    @BeforeClass 
    public void abc() 
    { 
     ---- 
    } 
    @Test(alwaysRun = true) 
    public void def() 
    { 
     ----- 
    } 
} 

Und eine andere Klasse

Class B 
{ 
    @Test 
    public void xyz() 
    { 
     SoftAssert sa = new SoftAssert(); 
     ----- 
     sa.fail(); 
     sa.assertAll(); 
    } 
} 

Say Klasse B Ermöglicht hat Dann scheiterte testng- failed.xml wird wie folgt craeted

Ich habe immer run = true für die Methode def als wahr, dann muss diese Methode auch in testng-failed.xml enthalten sein.

Warum war das in der Datei testng-failed.xml nicht vorhanden?

+0

Vielleicht läuft es richtig? –

Antwort

0

Per Definition alwaysRun Attribut auf einem @Test Verfahren zeigt folgende (unter Angabe der javadocs)

Wenn auf true gesetzt ist, wird diese Testmethode immer noch ausgeführt werden, wenn es auf ein Verfahren abhängt, ist fehlgeschlagen.

Nach Verhalten enthält TestNG nur die Methoden, die in testng-failed.xml fehlgeschlagen sind. Also, wenn Ihre def() Methode nicht fehlgeschlagen ist, dann wird es nicht in Ihrem testng-failed.xml enthalten sein.

Wenn Sie möchten, dass die def()-Methode die ganze Zeit enthalten ist (was dann raten, es ist keine @Test Methode, aber scheint eher eine Konfigurationsmethode zu sein), dann haben Sie die folgenden Optionen.

  1. Move it aus einer @Test Methode (weil es aussieht wie es wirklich ist kein Test-Verfahren, sondern eine Art eines bedingten Setup, die nur für bestimmte Methoden getan werden muss) und in einen TestNG Zuhörer [ B. org.testng.IInvokedMethodListener] und innerhalb des Listeners wird dies basierend auf einer benutzerdefinierten Annotation ausgeführt. Daher würden alle Methoden, die dieses spezielle Code-Snippet benötigen, eine benutzerdefinierte Annotation hinzufügen [Siehe here für ein Beispiel] und in diesem Listener beforeInvocation() würden Sie nach der benutzerdefinierten Annotation suchen, und wenn sie gefunden würde, würden Sie sie ausführen.

  2. Die andere Option wäre im Grunde, diesen Teil einer Basisklasse zu haben, die org.testng.IHookable Schnittstelle implementiert. Alle Ihre Testmethoden würden diese Basisklasse erweitern und innerhalb der run() Implementierung der Basisklasse [run() Methode über IHookable Schnittstelle] würden Sie die gleiche benutzerdefinierte Anmerkung Logik hinzufügen, die ich oben erwähnt.

Hier ist ein Beispiel, das all das in Aktion zeigt.

Beispiel für (1)

Der Marker Annotation.

import java.lang.annotation.Retention; 
import java.lang.annotation.Target; 

import static java.lang.annotation.ElementType.METHOD; 

/** 
* A marker annotation that indicates a special setup is needed. 
*/ 
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) 
@Target({METHOD}) 
public @interface NeedSpecialSetup {} 
/** 
* This interface which when implemented by test classes (classes that hold one or more {@link org.testng.annotations.Test} 
* annotated methods lets you perform special actions. But the methods should also be annotated using {@link NeedSpecialSetup} 
* annotation for this implementation to be invoked. 
*/ 
public interface PerformSpecialSetup { 
    void perform(); 
} 

Der Zuhörer

import org.testng.IInvokedMethod; 
import org.testng.IInvokedMethodListener; 
import org.testng.ITestResult; 

public class SimpleMethodListener implements IInvokedMethodListener { 
    @Override 
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { 
     //Did the method have our custom annotation which indicates that special setup is needed ? 
     NeedSpecialSetup specialsetup = method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(NeedSpecialSetup.class); 
     if (specialsetup != null) { 
      //Now lets check if the Object to which the method belongs to, has the capability to do the special setup 
      //and if it does, just delegate the call back to the respective test class instance. This way, we are not 
      //hard wiring any logic to our listener, but letting the respective test classes do whatever custom 
      //setup it requires. 
      Object instance = testResult.getInstance(); 
      if (instance instanceof PerformSpecialSetup) { 
       ((PerformSpecialSetup) instance).perform(); 
      } 
     } 
    } 

    @Override 
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) { } 
} 

Die Testklasse

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

@Listeners(SimpleMethodListener.class) 
public class MyTestClass implements PerformSpecialSetup { 

    @Test 
    public void method1() { 
     System.err.println("method1() invoked"); 
    } 

    @Test 
    @NeedSpecialSetup 
    public void method2() { 
     System.err.println("method2() invoked"); 
    } 

    @Override 
    public void perform() { 
     System.err.println("Special setup completed"); 
    } 
} 

Beispiel für (2)

import org.testng.IHookCallBack; 
import org.testng.IHookable; 
import org.testng.ITestResult; 
import org.testng.annotations.Test; 

public class AnotherTestClass implements IHookable { 
    @Override 
    public void run(IHookCallBack callBack, ITestResult testResult) { 
     NeedSpecialSetup specialsetup = testResult.getMethod().getConstructorOrMethod().getMethod().getAnnotation(NeedSpecialSetup.class); 
     if (specialsetup != null) { 
      perform(); 
     } 
     callBack.runTestMethod(testResult); 
    } 

    @Test 
    public void method1() { 
     System.err.println("method1() invoked"); 
    } 

    @Test 
    @NeedSpecialSetup 
    public void method2() { 
     System.err.println("method2() invoked"); 
    } 

    public void perform() { 
     System.err.println("Special setup completed"); 
    } 
} 
Verwandte Themen