为getStackTrace()获取不同的结果[2] .getMethodName()

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

为了进行日志记录,我创建了一个方法logTitle(),它输出了我们的testng测试的调用方法名。示例代码如下所示。

@Test
public void test1() throws Exception {
    method1();
}

public static void method1() throws Exception {
    Utils.logTitle(2);
}

...

public static void logTitle(Integer level) throws Exception {

    // Gets calling method name
    String method = Thread.currentThread().getStackTrace()[2].getMethodName();
    // This would get current method name
    switch (level) {
    case 1:
        logger.info("=======================================================");
        logger.info(method);
        logger.info("=======================================================");
        break;
    case 2:
        logger.info("------------------------------------");
        logger.info(method);
        logger.info("------------------------------------");
        break;
    case 3:
        logger.info("---------------------");
        logger.info(method);
        logger.info("---------------------");
        break;
    case 4:
        logger.info("--------- " + method + " ------------");
        break;
    default:
        logger.info(method);
    }
}

问题是,在两台不同的机器上,logTitle()得到了不同的结果。

每个人的笔记本电脑正确返回:

2016-06-20 14:22:06 INFO  - ------------------------------------
2016-06-20 14:22:06 INFO  - method1
2016-06-20 14:22:06 INFO  - ------------------------------------

我们的dev Unix框的返回方式不同:

2016-06-20 14:42:26 INFO  - ------------------------------------
2016-06-20 14:42:26 INFO  - logTitle
2016-06-20 14:42:26 INFO  - ------------------------------------

这在其他人的笔记本电脑上都能正常工作,只是不适合开发Unix框。我认为dev Unix框使用的是IBM的Java版本,而其他人都使用Oracle的Java版本,但不确定这是否是罪魁祸首。

有什么想法吗?

提问于
用户回答回答于

我认为是特定的深度导致了这个问题,在你的场景中是2。

所以,不要写

String method = Thread.currentThread().getStackTrace()[2].getMethodName();

如果你写

StackTraceElement[] ste = Thread.currentThread().getStackTrace();
String method = null;
boolean doNext = false;
for (StackTraceElement s : ste) {
       if (doNext) {
          method = s.getMethodName();
          return;
       }
       doNext = s.getMethodName().equals("getStackTrace");
   }

它只适用于jdk 1.5+。

另一种选择如下:

String method = new Object(){}.getClass().getEnclosingMethod().getName();

或者一个较慢的选择是:

String method = new Exception().getStackTrace()[0].getMethodName();

因为每次都会创建异常实例。

希望这能帮到你。

用户回答回答于

具有测试方法名称的更简单的方法是使用a @BeforeMethod并注入Method。请参阅此处的 TestNG文档。

只需将名称存储在某个地方并在日志中使用它(为什么不在@AfterMethod?中)?

扫码关注云+社区