2011-12-21 101 views
12

我可以像在JUnit中那樣檢索當前運行的測試名稱(使用getName()rules)嗎?在TestNG上檢索測試名稱

@Test 
public void fooBar(){ 
    System.out.println(magic()); //should print "fooBar" 
} 

P.S.我不想使用一些基於堆棧跟蹤的自行編寫的工具。

回答

5

根據TestNG文檔:http://testng.org/doc/documentation-main.html 您可以實現可能能夠幫助您處理問題的偵聽器。

查看5.16節TestNG監聽器,特別是IInvokedMethodListener(javadoc:http://testng.org/javadocs/org/testng/IInvokedMethodListener.html)。您可以掛入beforeInvocation來獲取方法名稱,將其保存在某處,然後在測試中使用它。你當然可以在聽衆實現中立即使用細節。

+0

這個答案很舊。德米特里的答案是最簡單的答案,需要最少的努力。 – gorbysbm 2017-11-04 00:31:26

7

在你的方法中聲明參數ITestContext並從中獲取你需要的任何信息。

+0

其實我在這個接口上下文中找不到它/ suite/currentXmlTest名稱不包含這個信息。 – 2011-12-22 14:02:03

+1

你的問題比TestNG更多的是Java問題,因爲你不想使用我知道的唯一方法來做它(走棧跟蹤),我不知道還有什麼要說的... – 2011-12-23 16:27:38

32

我發現@BeforeMethod註解更好的解決方案:

import java.lang.reflect.Method; 

public class Test 
{ 

    @BeforeMethod 
    public void handleTestMethodName(Method method) 
    { 
     String testName = method.getName(); 
     ... 
    } 

    ... 
} 

(基於解決方案from this thread

10

當您使用TestNG的,你可以使用@BeforeTest註釋

嘗試在TestNG的設置測試name。 xml文件測試標籤:

<test name="Check name test" > 

,並使用此梅託德:

@BeforeTest 
public void startTest(final ITestContext testContext) { 
    System.out.println(testContext.getName()); // it prints "Check name test" 
} 
1

持有到傳遞到像IInvokedMethodListener作爲一個天真的實現(包括那些在現有的答案)聽衆的值時,你必須要小心不會是線程安全的。由於TestNG可以同時運行測試,因此可以從不同測試的偵聽器中查看存儲值。這裏有兩個測試,testA()testB()一個例子:

  1. beforeInvocation(testA)testA
  2. beforeInvocation(testB)testB覆蓋testA
  3. testA()檢索testB(!!)
  4. testB()檢索testB

下面的TestMethodCapture類正確地處理了這個競爭條件,通過關聯偵聽器和它的測試通過ThreadLocal,確保同時運行的測試不會相互覆蓋。

更妙的是,它不僅限於檢索測試的名字,它擁有既符合當前的測試相關的ITestNGMethodITestResult實例的引用,所以你也可以檢查方法的classtest groupsparameters

您可以使用它像這樣:

@Listeners(TestMethodCapture.class) 
public class TestMethodCaptureTest { 
    @Test 
    public void fooBar() { 
    // will print "fooBar" 
    System.out.println(TestMethodCapture.getTestMethod().getMethodName()); 
    } 
} 

而這裏的類本身:

/** 
* Captures the currently executing test method so it can be accessed by the test, 
* e.g. to retrieve the test method's name. This class is thread-safe. 
* 
* <p>Register this class as a 
* <a href="http://testng.org/doc/documentation-main.html#testng-listeners">TestNG 
* listener</a>, then access the method and result from test code with the static 
* {@link #getTestMethod} and {@link #getTestResult} methods. 
* 
* <p>Annotating a test class with {@code @Listeners(TestMethodCapture.class)} is the 
* suggested way to enable capturing if your test's correctness will depend on this 
* listener being enabled. 
*/ 
public class TestMethodCapture implements IInvokedMethodListener { 
    private static ThreadLocal<ITestNGMethod> currentMethods = new ThreadLocal<>(); 
    private static ThreadLocal<ITestResult> currentResults = new ThreadLocal<>(); 

    @Override 
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { 
    currentMethods.set(method.getTestMethod()); 
    currentResults.set(testResult); 
    } 

    @Override 
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) { 
    currentMethods.remove(); 
    currentResults.remove(); 
    } 

    public static ITestNGMethod getTestMethod() { 
    return checkNotNull(currentMethods.get(), 
     "Did you forget to register the %s listener?", TestMethodCapture.class.getName()); 
    } 

    /** 
    * Parameters passed from a data provider are accessible in the test result. 
    */ 
    public static ITestResult getTestResult() { 
    return checkNotNull(currentResults.get(), 
     "Did you forget to register the %s listener?", TestMethodCapture.class.getName()); 
    } 
} 

如果你不使用Guava(爲什麼不呢?),你可以添加一個checkNotNUll()這樣的方法來編譯:

private static <T> T checkNotNull(T o, String msg, Object param) { 
    if (o == null) { 
    throw new NullPointerException(String.format(msg, param)); 
    } 
    return o; 
} 
+0

你能解釋一下正在返回的checkNotNull方法嗎?我們應該定義方法嗎?它顯示這個方法沒有定義的錯誤。 – nivasan89 2016-07-25 10:04:14

+1

@ nivasan89對不起,我錯過了你的評論。 ['checkNotNull()'](https://github.com/google/guava/wiki/PreconditionsExplained)來自[Guava](https://github.com/google/guava)。我強烈建議在任何Java項目中使用這個庫,但是這個方法本質上是一個很好的包裝,它包含'if(foo == null)throw NullPointerException();'所以你可以用一個相似的條件來替換這些調用。 – dimo414 2016-12-27 18:02:30

+1

這應該是被接受的答案。 – Bass 2016-12-28 11:11:54