Search code examples
javajunit4

how to create a test description with junit4 runListner


following is my JsonListner that i have extended from the junit RunListner. I am using it get a json report after the test run

package org.junit.runner;

import org.junit.runner.notification.RunListener;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

import java.io.FileWriter;
import java.io.IOException;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

class JsonListener extends RunListener {

  private JSONObject _tests_passed = new JSONObject();
  private JSONObject _tests_started = new JSONObject();
  private JSONObject _tests_finished = new JSONObject();
  private JSONObject _tests_failures = new JSONObject();
  private JSONObject _tests_ignored = new JSONObject();

  public void testRunStarted(Description description) throws Exception {

  }

  public void testRunFinished(Result result) throws Exception {
    System.out.println(_tests_passed);
  }

  public void testStarted(Description description) throws Exception {
    String key = description.getDisplayName();
    long value = System.currentTimeMillis();

    _tests_started.put(key, value);
  }

  public void testFinished(Description description) throws Exception {
    // trying to prit the description of the test running
    System.out.println(palindromeStringTest.desc);
  }

  public void testFailure(Failure failure) throws Exception {
    String key = failure.getDescription().getDisplayName();
    long value = System.currentTimeMillis();

    _tests_failures.put(key, value);
  }

  public void testAssumptionFailure(Failure failure) {
    String key = failure.getDescription().getDisplayName();
    long value = System.currentTimeMillis();

    _tests_failures.put(key, value);
  }

  public void testIgnored(Description description) throws Exception {
    String key = description.getMethodName();
    long value = System.currentTimeMillis();

    _tests_ignored.put(key, value);
  }

}

this is one of the test class that i am running through the runner.

import java.io.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class palindromeStringTest {

  ByteArrayOutputStream outContent = new ByteArrayOutputStream();
  static String desc;

  @Before
  public void setUpStream() {
    System.setOut(new PrintStream(outContent));
  }

  @After
  public void cleanUpStream() {
    System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
  }

  @Test
  public void revTest() {
    palindromeStringTest.desc = "this should reverse the string";
    String a = "Madam";
    palindromeString obj = new palindromeString();
    String b = obj.rev(a);
    assertEquals("madaM", b);
  }
}

my question is how do i get the this.desc value in the testFinished method of the runListner? this is an alternative that i have thought of using to get the description field value after each test run is complete. With the above implementation, i am failing to compile the runner

Buildfile: /home/bonnie/WorkStation/JUnit-Json-Runner/build.xml

clean:
   [delete] Deleting directory /home/bonnie/WorkStation/JUnit-Json-Runner/build
   [delete] Deleting directory /home/bonnie/WorkStation/JUnit-Json-Runner/dist

mkdir:
    [mkdir] Created dir: /home/bonnie/WorkStation/JUnit-Json-Runner/build/classes
    [mkdir] Created dir: /home/bonnie/WorkStation/JUnit-Json-Runner/dist

compile:
    [javac] Compiling 2 source files to /home/bonnie/WorkStation/JUnit-Json-Runner/build/classes
    [javac] /home/bonnie/WorkStation/JUnit-Json-Runner/src/JsonListner.java:39: error: cannot find symbol
    [javac] System.out.println(palindromeStringTest.desc);
    [javac]                    ^
    [javac]   symbol:   variable palindromeStringTest
    [javac]   location: class JsonListener
    [javac] Note: /home/bonnie/WorkStation/JUnit-Json-Runner/src/JsonListner.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
    [javac] 1 error

BUILD FAILED
/home/bonnie/WorkStation/JUnit-Json-Runner/build.xml:22: Compile failed; see the compiler error output for details.

Total time: 1 second

What are the ways, this can be acomplished? is there an already existing way to create and get a test description in the runner?


Solution

  • you have to use java.lang.reflect.* in the JsonListner in order to access the description variable.

    create a method getDescrition in the palindromeStringTest class, and return description.

    import java.io.*;
    import org.junit.After;
    import org.junit.AfterClass;
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import static org.junit.Assert.*;
    
    public class palindromeStringTest {
    
      ByteArrayOutputStream outContent = new ByteArrayOutputStream();
      static String desc;
    
      //public method to get the value of desc
      public function getDescription(){
        return desc;
      }
    
      @Before
      public void setUpStream() {
        System.setOut(new PrintStream(outContent));
      }
    
      @After
      public void cleanUpStream() {
        System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
      }
    
      @Test
      public void revTest() {
        palindromeStringTest.desc = "this should reverse the string";
        String a = "Madam";
        palindromeString obj = new palindromeString();
        String b = obj.rev(a);
        assertEquals("madaM", b);
      }
    }
    

    now you can access the description in the testFinished method with the help of java reflection class

       public void testFinished(Description description) throws Exception {
        Class<?> testClass = description.getTestClass();
        Method m = testClass.getDeclaredMethod("getDescription");
        Object o = m.invoke(null);
        System.out.println(o.toString());   
      }