Hot questions for Using AspectJ in junit

Question:

I want to get the result of a JUnit test. It is kept in TestResult class which is a return value of run method of TestCase class and also parameter of run method at TestCase class.

Please see this link for TestResult Class and TestCase class of JUnit.

http://junit.sourceforge.net/doc/cookstour/cookstour.htm

I can access the TestCase class when the test is run.

My question is : Is it possible to acccess the parameters of a method when its run is finished or can I get the return value of a method after it is executed ?

I am doing aspect programming for my thesis. There I have access to the TestCase class. There when a test case method is executed. I want to get its result whether test has passed or failed. So that I can use that information. How can I get the test result programmatically ?

Here is sample code :

    pointcut allMethodsRun() : execution(* *.*(..));
    pointcut testClasses() : within(junit.framework.TestCase+);


 after() :  testClasses() && allMethodsRun() {   
     System.out.println(((TestCase) thisJoinPoint.getThis()).run()  );        

Here I can access the TestCase class but how can I get the test result after test method executes. Any Idea or question ?

ilke


Answer:

Andrew is absolutely right, but for what it is worth, you want to see an AOP solution, so I prepared one for you in AspectJ. But I do not like the old JUnit style, so I prepared a JUnit 4 test case using @Test annotations rather than inheriting from TestCase. I think you should get acquainted with JUnit 4, because it has been around for long enough and is the standard nowadays.

Class under test (very trivial):

package de.scrum_master.app;

public class Calculator {
    public static int add(int summand1, int summand2) {
        return summand1 + summand2;
    }

    public static int subtract(int minuend, int subtrahend) {
        return minuend - subtrahend;
    }

    public static int multiply(int factor1, int factor2) {
        return factor1 * factor2;
    }

    public static int divide(int dividend, int divisor) {
        return dividend / divisor;
    }
}

JUnit 4 test with one failing assertion and one test producing an unplanned runtime error:

package de.scrum_master.app;

import static org.junit.Assert.*;
import org.junit.Test;

public class CalculatorTest {
    @Test
    public void testAdd() {
        assertEquals(33, Calculator.add(11, 22));
        assertEquals(12, Calculator.add( 4,  8));
        assertEquals(11, Calculator.add(11,  0));
    }

    @Test
    public void testSubtract() {
        assertEquals(33, Calculator.subtract(44, 11));
        assertEquals(12, Calculator.subtract(12,  0));
        assertEquals(11, Calculator.subtract(19,  8));
    }

    @Test
    public void testMultiply() {
        assertEquals(33, Calculator.multiply( 3, 11));
        assertEquals(12, Calculator.multiply( 4,  3));
        // This assertion should fail
        assertEquals(11, Calculator.subtract(10,  5));
    }

    @Test
    public void testDivide() {
        assertEquals(33, Calculator.divide(99, 3));
        assertEquals(12, Calculator.divide(51, 4));
        // This call should cause an exception
        assertEquals(11, Calculator.divide(11, 0));
    }
}

Aspect capturing successful and failing tests:

package de.scrum_master.aspect;

import org.junit.Test;

public aspect TestResultInterceptor {
    pointcut testMethods() :
        execution(@Test public void *(..));

    after() returning : testMethods() {
        System.out.println(
            "Test OK: " +
            thisJoinPointStaticPart.getSignature()
        );
    }

    after() throwing (Throwable throwable) : testMethods() {
        System.out.println(
            (throwable instanceof AssertionError ? "Test failed: " : "Error during test: ") +
            thisJoinPointStaticPart.getSignature()
        );
        System.out.println("  " + throwable);
    }
}

Console log when running the JUnit test:

Test OK: void de.scrum_master.app.CalculatorTest.testAdd()
Test OK: void de.scrum_master.app.CalculatorTest.testSubtract()
Error during test: void de.scrum_master.app.CalculatorTest.testDivide()
  java.lang.ArithmeticException: / by zero
Test failed: void de.scrum_master.app.CalculatorTest.testMultiply()
  java.lang.AssertionError: expected:<11> but was:<5>

Question:

I want to detect when a JUnit class finishes running its test methods.

How can I detect when a Junit class finishes its unit test methods ?

And how can I similary understand that a test suite made of Junit test classes finishes its call ?


Answer:

When a class finishes its unit tests, the method with annotation @AfterClass is executed. You may use that to know that your unit test methods have finished executing.