package org.testng;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.util.Strings;

This class is used for test methods to log messages that will be included in the HTML reports generated by TestNG.

Implementation details

The reporter keeps a combined output of strings (in m_output) and also a record of which method output which line. In order to do this, callers specify what the current method is with setCurrentTestResult() and the Reporter maintains a mapping of each test result with a list of integers. These integers are indices in the combined output (avoids duplicating the output).

Created on Nov 2, 2005

Author:cbeust
/** * This class is used for test methods to log messages that will be included in the HTML reports * generated by TestNG. <br> * <br> * <b>Implementation details</b> <br> * <br> * The reporter keeps a combined output of strings (in m_output) and also a record of which method * output which line. In order to do this, callers specify what the current method is with * setCurrentTestResult() and the Reporter maintains a mapping of each test result with a list of * integers. These integers are indices in the combined output (avoids duplicating the output). * * <p>Created on Nov 2, 2005 * * @author cbeust */
public class Reporter { // When tests are run in parallel, each thread may be working with different // 'current test result'. Also, this value should be inherited if the test code // spawns its own thread. private static ThreadLocal<ITestResult> m_currentTestResult = new InheritableThreadLocal<>();
All output logged in a sequential order.
/** All output logged in a sequential order. */
private static List<String> m_output = new Vector<>();
The key is the hashCode of the ITestResult.
/** The key is the hashCode of the ITestResult. */
private static Map<Integer, List<Integer>> m_methodOutputMap = Maps.newHashMap(); private static boolean m_escapeHtml = false; // This variable is responsible for persisting all output that is yet to be associated with any // valid TestResult objects. private static ThreadLocal<List<String>> m_orphanedOutput = new InheritableThreadLocal<>(); public static void setCurrentTestResult(ITestResult m) { m_currentTestResult.set(m); } public static List<String> getOutput() { return m_output; }
Erase the content of all the output generated so far.
/** Erase the content of all the output generated so far. */
public static void clear() { m_methodOutputMap.clear(); m_output.clear(); }
Returns:If true, use HTML entities for special HTML characters (<, >, &, ...).
/** @return If true, use HTML entities for special HTML characters (&lt;, &gt;, &amp;, ...). */
public static boolean getEscapeHtml() { return m_escapeHtml; }
Params:
  • escapeHtml – If true, use HTML entities for special HTML characters (<, >, &, ...).
/** @param escapeHtml If true, use HTML entities for special HTML characters (&lt;, &gt;, &amp;, ...). */
public static void setEscapeHtml(boolean escapeHtml) { m_escapeHtml = escapeHtml; } private static synchronized void log(String s, ITestResult m) { // Escape for the HTML reports. if (m_escapeHtml) { s = Strings.escapeHtml(s); } if (m == null) { // Persist the output temporarily into a Threadlocal String list. if (m_orphanedOutput.get() == null) { m_orphanedOutput.set(new ArrayList<>()); } m_orphanedOutput.get().add(s); return; } // Synchronization needed to ensure the line number and m_output are updated atomically. int n = getOutput().size(); List<Integer> lines = m_methodOutputMap.computeIfAbsent(m.hashCode(), k -> Lists.newArrayList()); // Check if there was already some orphaned output for the current thread. if (m_orphanedOutput.get() != null) { n = n + m_orphanedOutput.get().size(); getOutput().addAll(m_orphanedOutput.get()); // Since we have already added all of the orphaned output to the current // TestResult, let's clear it off. m_orphanedOutput.remove(); } lines.add(n); getOutput().add(s); }
Log the passed string to the HTML reports.
Params:
  • s – The message to log
/** * Log the passed string to the HTML reports. * * @param s The message to log */
public static void log(String s) { log(s, getCurrentTestResult()); }
Log the passed string to the HTML reports if the current verbosity is equal to or greater than the one passed as a parameter. If logToStandardOut is true, the string will also be printed on standard out.
Params:
  • s – The message to log
  • level – The verbosity of this message
  • logToStandardOut – Whether to print this string on standard out too
/** * Log the passed string to the HTML reports if the current verbosity is equal to or greater than the * one passed as a parameter. If logToStandardOut is true, the string will also be printed on * standard out. * * @param s The message to log * @param level The verbosity of this message * @param logToStandardOut Whether to print this string on standard out too */
public static void log(String s, int level, boolean logToStandardOut) { if (TestRunner.getVerbose() >= level) { log(s, getCurrentTestResult()); if (logToStandardOut) { System.out.println(s); } } }
Log the passed string to the HTML reports. If logToStandardOut is true, the string will also be printed on standard out.
Params:
  • s – The message to log
  • logToStandardOut – Whether to print this string on standard out too
/** * Log the passed string to the HTML reports. If logToStandardOut is true, the string will also be * printed on standard out. * * @param s The message to log * @param logToStandardOut Whether to print this string on standard out too */
public static void log(String s, boolean logToStandardOut) { log(s, getCurrentTestResult()); if (logToStandardOut) { System.out.println(s); } }
Log the passed string to the HTML reports if the current verbosity is equal to or greater than the one passed as a parameter.
Params:
  • s – The message to log
  • level – The verbosity of this message
/** * Log the passed string to the HTML reports if the current verbosity is equal to or greater than the * one passed as a parameter. * * @param s The message to log * @param level The verbosity of this message */
public static void log(String s, int level) { if (TestRunner.getVerbose() >= level) { log(s, getCurrentTestResult()); } }
Returns:the current test result.
/** @return the current test result. */
public static ITestResult getCurrentTestResult() { return m_currentTestResult.get(); } public static synchronized List<String> getOutput(ITestResult tr) { List<String> result = Lists.newArrayList(); if (tr == null) { // Guard against a possible NPE in scenarios wherein the test result object itself could be a // null value. return result; } List<Integer> lines = m_methodOutputMap.get(tr.hashCode()); if (lines != null) { for (Integer n : lines) { result.add(getOutput().get(n)); } } return result; } }