【问题标题】:How can i see my test logs in the console log of jenkins我如何在詹金斯的控制台日志中看到我的测试日志
【发布时间】:2016-06-21 08:28:50
【问题描述】:

我正在为我的 android 应用 throw jenkins 运行 junit 测试。如果测试失败,我只能看到堆栈跟踪,这有时无法帮助我理解为什么我的测试失败了。我在我的代码中添加了一些日志,这样当我在本地机器上运行它们时我可以调试我的测试,但我希望能够在 Jenkins 控制台输出中看到这些日志,这样我就可以在我的测试失败时意识到出了什么问题。

【问题讨论】:

  • 在本地环境中运行测试时是否看到日志?(您的 IDE 控制台或终端)
  • 是的。我可以在我的 android studio 的 Android Monitor 控制台上看到它。
  • 很难判断是什么问题,但作为一种变通方法,您可以将登录信息打印到日志文件中,然后只需“cat/type”此文件即可。
  • 我想过这个解决方案。我会试一试。谢谢

标签: android jenkins automated-tests


【解决方案1】:

这是一个老问题,但我找到了解决方案。 我将Log 类包装成一个自定义类(Logger)。

然后我将 Log 方法包装起来:

public static void d(String tag, String message) {
    log(LOG.DEBUG, tag, message);
}

那么日志看起来像:

private static void log(LOG logLevel, Object message) {
        LOG_LINES.add(new LogLine(logLevel, tag, content));

        switch (logLevel) {
            case ERROR:
                Log.e(tag, content);
                break;
            case WARNING:
                Log.w(tag, content);
                break;
            case INFO:
                Log.i(tag, content);
                break;
            case DEBUG:
                Log.d(tag, content);
                break;
            case VERBOSE:
                Log.v(tag, content);
                break;
       }
    }

使用 LOG_LINES 一个 CopyOnWriteArrayList 和LogLine 日志数据的持有者。

最后,使用自定义测试Runner 将日志显示在 Jenkins 中(在 HTML 报告中)。只需将注解 @RunWith(MyLoggingTestRunner.class) 添加到测试类中:

public class MyLoggingTestRunner extends BlockJUnit4ClassRunner {

    public MyLoggingTestRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }


    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
        //override to override errors with logs
        Description description = describeChild(method);
        if (method.getAnnotation(Ignore.class) != null) {
            notifier.fireTestIgnored(description);
        } else {
            run(methodBlock(method), description, notifier);
        }
    }

    protected void run(Statement statement, Description description, RunNotifier notifier) {
        EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
        eachNotifier.fireTestStarted();
        try {
            statement.evaluate();
        } catch (AssumptionViolatedException e) {
            eachNotifier.addFailedAssumption(e);
        } catch (Throwable e) {
            String throwableMessage = e.getMessage();
            String message = "\nLast logs :\n" + logsToString() + "\n\nStackTrace :\n" + e.getClass() + (TextUtils.isEmpty(throwableMessage) ? "" : ":" + throwableMessage);

            try {
                Field detailMessage = Throwable.class.getDeclaredField("detailMessage");
                detailMessage.setAccessible(true);
                detailMessage.set(e, message);
            } catch (Exception e1) {
            }
            eachNotifier.addFailure(e);
        } finally {
            eachNotifier.fireTestFinished();
        }
    }


    private static String logsToString() {
        List<LogLine> logs = Logger.getLogs();
        StringBuilder logBuilder = new StringBuilder();
        String sep = "";
        for (LogLine logLine : logs) {
            logBuilder.append(sep).append(logLine.toString());
            sep = "\n";
        }
        return logBuilder.toString();
    }
}

我希望它有效,因为我修改了我的代码,试图以简单的方式解释它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2018-10-28
    相关资源
    最近更新 更多