logback / LOGBACK-1615 [Open]
Simplify Testing with ListAppender

==============================

Here's what changed in this issue in the last few minutes.
This issue has been created
This issue is now assigned to you.

View or comment on issue using this link
https://jira.qos.ch/browse/LOGBACK-1615

==============================
 Issue created
------------------------------

Taylor S Marks created this issue on 11/Feb/22 4:28 PM
Summary:              Simplify Testing with ListAppender
Issue Type:           Improvement
Assignee:             Logback dev list
Components:           logback-core
Created:              11/Feb/22 4:28 PM
Priority:             Major
Reporter:             Taylor S Marks
Description:
  My understanding is the main usage of ListAppender is for writing tests that 
verify expected logs are produced.
  
  Currently, setting this up involves a lot of boilerplate:
  {code:java}
  package com.mypackage;
  
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  import ch.qos.logback.classic.Logger;
  import ch.qos.logback.classic.spi.ILoggingEvent;
  import ch.qos.logback.core.read.ListAppender;
  import org.junit.jupiter.api.Test;
  import org.slf4j.LoggerFactory;
  
  
  public class TestMyClass {
      static ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
  
      static {
          listAppender.start();
          ((Logger) 
LoggerFactory.getLogger(MyClass.class)).addAppender(listAppender);
          ((Logger) 
LoggerFactory.getLogger(AnotherClass.class)).addAppender(listAppender);
      }
  
      @Test
      public void myTest() {
          MyClass.doThingThatLogs();
          int lastLogIndex = listAppender.list.size() - 1;
  
          // Note: When it fails, it unhelpfully says "False is not True".
          assertTrue(
              listAppender
                  .list
                  .get(lastLogIndex)
                  .getFormattedMessage()
                  .contains("My expected log"));
      }
  }{code}
  I believe this is a common use case for ListAppender, and the class should be 
improved to facilitate doing this kind of thing better and with a lot less code.
  
  Off the top of my head, the following improvements could be made:
   # Give ListAppender a constructor that takes in a vararg of classes or 
Strings to list itself to, and have it start itself.
   # Give ListAppender a size method that skips the need to go to the 
underlying list.
   # Give ListAppender a get method that skips asking the underlying list, and 
also support negative indexes to easily facilitate getting logs from the end 
rather than the start.
   # Give ListAppender an assertContains(int index, String... substrings) 
method that facilitates easily asserting that specific substrings showed up in 
the logs, and generates a good error message of what log was actually found vs 
which expected substrings were missing.
  
  With those proposals, the initial example test could be reduced down to just:
  {code:java}
  package com.mypackage;
  
  import ch.qos.logback.classic.spi.ILoggingEvent;
  import ch.qos.logback.core.read.ListAppender;
  import org.junit.jupiter.api.Test;
  
  
  public class TestMyClass {
      static ListAppender<ILoggingEvent> listAppender = new 
ListAppender<>(MyClass.class, AnotherClass.class);
  
      @Test
      public void myTest() {
          MyClass.doThingThatLogs();
  
          // Note: If the log is missing, the failure message says what it 
actually found.
          listAppender.assertContains(-1, "My expected log");
      }
  
  {code}
  I wasn't sure if people maybe thought this should go someplace different 
(maybe make a subclass of ListAppender?) or if it doesn't belong in Logback. 
I'm guessing the value:cost ratio is quite good here. Do others have 
suggestions to improve the proposed method signatures or have additional 
suggestions of what would be valuable here?
  
  Getting somewhat off-topic, it could utilize of try-with-resources to easily 
facilitate start/stop and making sure logs aren't leaked between tests.


==============================
 This message was sent by Atlassian Jira (v8.8.0#808000-sha1:e2c7e59)

_______________________________________________
logback-dev mailing list
[email protected]
http://mailman.qos.ch/mailman/listinfo/logback-dev

Reply via email to