2011-12-21 31 views
12

Tôi có thể truy xuất tên thử hiện đang chạy như trong JUnit (sử dụng getName() hoặc rules) không?Truy xuất tên thử nghiệm trên TestNG

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

P.S. Tôi không muốn sử dụng một số công cụ tự viết dựa trên dấu vết ngăn xếp.

Trả lời

5

Theo tài liệu TestNG tại: http://testng.org/doc/documentation-main.html bạn có thể triển khai người nghe có thể giúp bạn giải quyết vấn đề của mình.

Xem phần 5.16 Trình nghe TestNG và đặc biệt là IInvokedMethodListener (javadoc: http://testng.org/javadocs/org/testng/IInvokedMethodListener.html). Bạn có thể móc vào beforeInvocation để lấy tên phương thức, giữ nó ở đâu đó, và sau đó sử dụng nó trong thử nghiệm của bạn. Bạn có thể tất nhiên, chỉ cần sử dụng các chi tiết ngay lập tức trong việc thực hiện lắng nghe của bạn.

+0

Câu trả lời này rất cũ. Câu trả lời của Dmitry là câu trả lời đơn giản nhất đòi hỏi ít nỗ lực nhất. – gorbysbm

7

Khai báo một tham số ITestContext trong phương thức của bạn và lấy bất kỳ thông tin nào bạn cần từ nó.

+0

Thực ra tôi không thể tìm thấy nó trong giao diện ngữ cảnh/suite/currentXmlTên này không chứa thông tin này. –

+1

Câu hỏi của bạn là một câu hỏi Java hơn một câu hỏi TestNG, và vì bạn không muốn sử dụng cách duy nhất mà tôi biết để làm điều đó (đi theo dấu vết ngăn xếp), tôi không chắc chắn những gì khác để nói ... –

32

tôi tìm thấy giải pháp tốt hơn với @BeforeMethod chú thích:

import java.lang.reflect.Method; 

public class Test 
{ 

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

    ... 
} 

(dựa trên giải pháp from this thread)

10

Khi bạn sử dụng TestNG bạn có thể sử dụng @BeforeTest chú thích

Cố gắng thiết lập thử nghiệm name trong testng. thẻ thử nghiệm tệp xml:

<test name="Check name test" > 
.210

và sử dụng metod này:

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

Bạn cần phải cẩn thận khi nắm giữ các giá trị truyền vào người nghe như IInvokedMethodListener như một thực hiện ngây thơ (kể cả những người trong câu trả lời hiện có) sẽ không được thread-safe. Vì TestNG có thể chạy thử nghiệm đồng thời, nên có thể xem giá trị được lưu trữ từ trình nghe của một thử nghiệm khác. Dưới đây là một ví dụ với hai bài kiểm tra, testA()testB():

  1. beforeInvocation(testA) cửa hàng testA
  2. beforeInvocation(testB) cửa hàng testB ghi đè testA
  3. testA() lấy testB (!!)
  4. testB() lấy testB

Lớp TestMethodCapture dưới đây xử lý tình trạng cuộc đua này một cách chính xác bằng cách liên kết người nghe và thử nghiệm của nó thông qua một ThreadLocal, đảm bảo rằng các thử nghiệm chạy đồng thời sẽ không ghi đè lên nhau.

Thậm chí tốt hơn, nó không giới hạn chỉ lấy tên của kiểm tra, nó giữ một tham chiếu đến cả ITestNGMethodITestResult trường hợp liên quan đến việc kiểm tra hiện hành, vì vậy bạn cũng có thể kiểm tra của phương pháp class, test groups, và parameters.

Bạn có thể sử dụng nó như vậy:

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

Và đây là chính lớp:

/** 
* 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()); 
    } 
} 

Nếu bạn không sử dụng Guava (tại sao không ??) bạn có thể thêm phương thức checkNotNUll() như thế này để biên dịch:

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

Bạn có thể giải thích phương thức checkNotNull đang được trả lại không? Chúng ta có nên định nghĩa phương pháp này không? Nó cho thấy một lỗi rằng phương pháp này không được xác định. – nivasan89

+1

@ nivasan89 xin lỗi tôi đã bỏ lỡ nhận xét của bạn. ['checkNotNull()'] (https://github.com/google/guava/wiki/PreconditionsExplained) đến từ [Guava] (https://github.com/google/guava). Tôi thực sự khuyến khích sử dụng thư viện này trong bất kỳ dự án Java nào, nhưng phương pháp này về cơ bản là một trình bao bọc đẹp xung quanh 'if (foo == null) ném NullPointerException();' – dimo414

+1

Đây phải là câu trả lời được chấp nhận. – Bass

Các vấn đề liên quan