top of page
maywritackmarofan

Unit test log4j2 log output with JUnit and Log4j2TestRule



A number of log4j2 unit tests use a FileAppender with immediateFlush=true, then read in the file and check that some expected Strings exist in the output. Others configure a (org.apache.logging.log4j.test.appender.) ListAppender (this class lives in the core test jar) and obtain the LogEvent objects directly from the list.


Maven can run unit and functional tests during the build cycle. By default, any files placed in src/test/resources are automatically copied to target/test-classes and are included in the classpath during execution of any tests. As such, placing a log4j2-test.xml into this directory will cause it to be used instead of a log4j2.xml or log4j2.json that might be present. Thus a different log configuration can be used during testing than what is used in production.




Unit test log4j2 log output




A second approach, which is extensively used by Log4j 2, is to set the log4j.configurationFile property in the method annotated with @BeforeClass in the junit test class. This will allow an arbitrarily named file to be used during the test.


When running unit tests, you may want to suppress expected or harmless log messages in order to keep your console output clean. There are two ways to suppress log messages, both having their own use cases:


When you expect some invocation in your unit test to log one or more messages, but don't want these messages to show up in the console in order to keep the output clean, you can suppress these log messages by using Log4jInterceptor. In the following example, assume that the invocation of componentManager.start() triggers an expected log message:


In the case where the code producing an expected, harmless log message is buried more deeply in your unit test, you may not be able to suppress that message using Log4jInterceptor. Instead, you may use StringMatchFilter, which is an org.apache.logging.log4j.core.Filter you can add to an Appender in your log4j2.xml configuration in order to suppress log messages. StringMatchFilter is configured through log4j-filters.txt based on a contains criterium.


You can use the junit.jupiter.displayname.generator.defaultconfiguration parameter to specify the fully qualifiedclass name of the DisplayNameGenerator you would like to use by default. Just like fordisplay name generators configured via the @DisplayNameGeneration annotation, thesupplied class has to implement the DisplayNameGenerator interface. The default displayname generator will be used for all tests unless the @DisplayNameGeneration annotationis present on an enclosing test class or test interface. Values provided via@DisplayName annotations always take precedence over display names generated by aDisplayNameGenerator.


For example, to use the ReplaceUnderscores display name generator by default, you shouldset the configuration parameter to the corresponding fully qualified class name (e.g., insrc/test/resources/junit-platform.properties):


The ExecutionCondition extension API in JUnit Jupiter allowsdevelopers to either enable or disable a container or test based on certainconditions programmatically. The simplest example of such a condition is the built-inDisabledCondition which supports the @Disabled annotation (seeDisabling Tests). In addition to @Disabled, JUnit Jupiter also supportsseveral other annotation-based conditions in the org.junit.jupiter.api.conditionpackage that allow developers to enable or disable containers and tests declaratively.When multiple ExecutionCondition extensions are registered, a container or test isdisabled as soon as one of the conditions returns disabled. If you wish to providedetails about why they might be disabled, every annotation associated with these built-inconditions has a disabledReason attribute available for that purpose.


Unless otherwise stated, each of the conditional annotations listed in the followingsections can only be declared once on a given test interface, test class, or test method.If a conditional annotation is directly present, indirectly present, or meta-presentmultiple times on a given element, only the first such annotation discovered by JUnit willbe used; any additional declarations will be silently ignored. Note, however, that eachconditional annotation may be used in conjunction with other conditional annotations inthe org.junit.jupiter.api.condition package.


You can use the junit.jupiter.testmethod.order.default configuration parameter to specify the fully qualified class name of theMethodOrderer you would like to use by default. Just like for the orderer configuredvia the @TestMethodOrder annotation, the supplied class has to implement theMethodOrderer interface. The default orderer will be used for all tests unless the@TestMethodOrder annotation is present on an enclosing test class or test interface.


For example, to use the MethodOrderer.OrderAnnotation method orderer by default, youshould set the configuration parameter to the corresponding fully qualified class name(e.g., in src/test/resources/junit-platform.properties):


To configure test class execution order globally for the entire test suite, use thejunit.jupiter.testclass.order.default configurationparameter to specify the fully qualified class name of the ClassOrderer you wouldlike to use. The supplied class must implement the ClassOrderer interface.


For example, for the @Order annotation to be honored on test classes, you shouldconfigure the ClassOrderer.OrderAnnotation class orderer using the configurationparameter with the corresponding fully qualified class name (e.g., insrc/test/resources/junit-platform.properties):


To configure test class execution order locally for @Nested test classes, declare the@TestClassOrder annotation on the enclosing class for the @Nested test classes youwant to order, and supply a class reference to the ClassOrderer implementation you wouldlike to use directly in the @TestClassOrder annotation. The configured ClassOrdererwill be applied recursively to @Nested test classes and their @Nested test classes.Note that a local @TestClassOrder declaration always overrides an inherited@TestClassOrder declaration or a ClassOrderer configured globally via thejunit.jupiter.testclass.order.default configuration parameter.


If a test class or test interface is not annotated with @TestInstance, JUnit Jupiterwill use a default lifecycle mode. The standard default mode is PER_METHOD;however, it is possible to change the default for the execution of an entire test plan.To change the default test instance lifecycle mode, set thejunit.jupiter.testinstance.lifecycle.default configuration parameter to the name ofan enum constant defined in TestInstance.Lifecycle, ignoring case. This can be suppliedas a JVM system property, as a configuration parameter in theLauncherDiscoveryRequest that is passed to the Launcher, or via the JUnit Platformconfiguration file (see Configuration Parameters for details).


To set the default test instance lifecycle mode to Lifecycle.PER_CLASS via the JUnitPlatform configuration file, create a file named junit-platform.properties in the rootof the class path (e.g., src/test/resources) with the following content.


In JUnit Jupiter you should use TestReporter where you used to print information tostdout or stderr in JUnit 4. Using @RunWith(JUnitPlatform.class) will output allreported entries to stdout. In addition, some IDEs print report entries to stdout ordisplay them in the user interface for test results.


Explicit argument converters are meant to be implemented by test and extension authors.Thus, junit-jupiter-params only provides a single explicit argument converter that mayalso serve as a reference implementation: JavaTimeArgumentConverter. It is used via thecomposed annotation JavaTimeConversionPattern.


The @Timeout annotation allows one to declare that a test, test factory, test template,or lifecycle method should fail if its execution time exceeds a given duration. The timeunit for the duration defaults to seconds but is configurable.


More specific configuration parameters override less specific ones. For example,junit.jupiter.execution.timeout.test.method.default overridesjunit.jupiter.execution.timeout.testable.method.default which overridesjunit.jupiter.execution.timeout.default.


By default, nodes in the test tree use the SAME_THREAD execution mode. You can changethe default by setting the junit.jupiter.execution.parallel.mode.default configurationparameter. Alternatively, you can use the @Execution annotation to change theexecution mode for the annotated element and its subelements (if any) which allows you toactivate parallel execution for individual test classes, one by one. 2ff7e9595c


2 views0 comments

Recent Posts

See All

Comments


bottom of page