如何在jenkins的控制台日志中查看我的测试日志

时间:2016-06-21 08:28:51

标签: android jenkins automated-tests

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

1 个答案:

答案 0 :(得分:0)

这是一个老问题,但我找到了解决方案。 我将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();
    }
}

我希望它有效,因为我调整了我的代码,试图以一种简单的方式解释它。