如何在每个JVM上运行一次jul-to-slf4j桥接器?

时间:2016-05-19 20:09:00

标签: junit testng slf4j surefire

我想在并行模式(多个JVM)中运行Surefire,其中每个JVM必须运行:

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

在第一次测试前一次。怎么办呢?

1 个答案:

答案 0 :(得分:1)

有许多方法可以在测试套件的开头运行一些代码。

这是4(我相信还有更多):

  1. JUnit通过RunWith SuiteSuite.SuiteClassesBeforeClass(改编自SuiteTest中的示例):

    @RunWith(Suite.class)
    @SuiteClasses({FirstTest.class, SecondTest.class/*, ...*/, LastTest.class})
    public static class AllWithSLF4JBridgeHandler {
        @BeforeClass
        public static void registerRootLoggerHandlers() {
            SLF4JBridgeHandler.removeHandlersForRootLogger();
            SLF4JBridgeHandler.install();
        }
    }
    
  2. 带有BeforeSuite的TestNG:

    /**
     * Base class for each test class (i.e. every test class should extend this class).
     */
    public abstract class BaseTest {
        @BeforeSuite
        public void registerRootLoggerHandlers() {
            SLF4JBridgeHandler.removeHandlersForRootLogger();
            SLF4JBridgeHandler.install();
        }
    }
    
  3. 带有Guice的TestNG:

    /**
     * Test module. Each test class should be annotated with `@Guice(TestModule.class)`.
     */
    public class TestModule implements Module {
        @Override
        public void configure(Binder binder) {
            SLF4JBridgeHandler.removeHandlersForRootLogger();
            SLF4JBridgeHandler.install();
        }
    }
    
  4. Static initialization blocks(独立于测试框架):

    /**
     * Base class for each test class (i.e. every test class should extend this class).
     */
    public abstract class BaseTest {
        static {
            SLF4JBridgeHandler.removeHandlersForRootLogger();
            SLF4JBridgeHandler.install();
        }
    }
    
  5. 我不确定所有这些方法如何与Surefire的并行模式一起使用。方法1和2可能不适用,但我相信方法3和4应该。

    另一种选择是不使用SLF4JBridgeHandler的编程安装,而是使用java.util.logging.config文件或类(参见LogManager):

    1. “java.util.logging.config.file”:

      logging.properties文件:

      // register SLF4JBridgeHandler as handler for the j.u.l. root logger
      handlers = org.slf4j.bridge.SLF4JBridgeHandler
      

      系统属性赋值:

      java -Djava.util.logging.config.file=/path/to/logging.properties ...
      

      如果您事先知道日志文件的路径,那么这很有效。

    2. “java.util.logging.config.class”:

      如果您正在部署WAR并且不知道文件的位置等,则使用文件可能不是一个好的选择。因此,您可以创建一个日志配置类:

      public class SLF4JBridgeHandlerInitializer {
          public SLF4JBridgeHandlerInitializer() throws IOException {
              String loggingConfigurationString = "handlers = " + SLF4JBridgeHandler.class.getName();
              InputStream inputStream = new ByteArrayInputStream(loggingConfigurationString.getBytes());
              LogManager.getLogManager().readConfiguration(inputStream);
          }
      }
      

      系统属性赋值:

      java -Djava.util.logging.config.class=package.SLF4JBridgeHandlerInitializer ...
      

      我以前做过这件事并且对我来说效果很好(SLF4JBridgeHandler.Initializer by mfulton26 · Pull Request #57 · qos-ch/slf4j)。

    3. 只要设置了适当的系统属性,这两个最后两个选项就应该初始化每个JVM实例。