I’m using Eclipse Kepler and Maven 3.2.3. I have imported my projects using the M2Eclipse plugin. Normally, when I run a JUnit test on the command line, like

mvn clean test -Dtest=MyJunitTest

there are some things that run in the “process-resources” and “process-classes” phases before my test is executed. In Eclipse, when I open the JUnit test file in an editor, right click the class name (e.g. “MyJUnitTest”) and right click on “Run As” and “JUnit Test”, those phases do not seem to be getting run. So my question is, how can I make right-clicking on my Junit Test and selecting “Run As” -> “JUnit Test” behave as if I had typed “mvn clean test -Dtest=MyJunitTest” on the command line?

2

There are 2 answers

1
SiKing On

Maven and JUnit are two completely different tools, each with a different build - run path and each with different requirements. Just because Maven can utilize JUnit as part of it's toolchain, does not mean they are the same!

You apparently made your project dependent on the Maven build path. It would be extremely difficult, or maybe outright not possible, to make JUnit follow that path.

In Eclipse, with the m2e plugin, it is trivial to create custom runs, using the Run As > Maven build. Documentation is available if you need it.

This "Maven build" option is available only from top level of your project, where your pom is located. You will then have to specify all your options, such as -Dtest=MyJunitTest.

2
Gerold Broser On

I prepared the following (inspired by user3254289's answer):

Extended the projects POM SO-30767338/pom.xml

<dependency>
  <groupId>org.apache.maven.shared</groupId>
  <artifactId>maven-invoker</artifactId>
  <version>2.2</version>
</dependency>

Implemented SO-30767338/src/test/java/MavenTestRunner.java

import static java.lang.System.out;

import java.io.File;
import java.util.Collections;
import java.util.Properties;

import org.apache.maven.shared.invoker.*;
import org.junit.Test;

public class MavenTestRunner
    {
    @Test
    public void testUnit()
        {
        String thisClassName = this.getClass().getSimpleName();
        if ( System.getProperty( "unit" ).contains( thisClassName ) )
            {
            throw new IllegalArgumentException(
                String.format( "%s cannot be tested with %1$s.", thisClassName ) );
            }

        Properties properties = new Properties();
        properties.put( "test", System.getProperty( "unit" ) );

        out.printf( "Testing %s in project %s.\n",
            properties.getProperty( "test" ), System.getProperty( "pom" ) );

        InvocationRequest request = new DefaultInvocationRequest();
        request.setPomFile( new File( System.getProperty( "pom" ) ) );
        request.setGoals( Collections.singletonList( "test" ) );
        request.setProperties( properties );

        try
            {
            Invoker invoker = new DefaultInvoker();
            InvocationResult result = invoker.execute( request );

            if ( result.getExitCode() != 0 )
                {
                throw new IllegalStateException(
                    String.format( "Test build of %s failed.", System.getProperty( "unit" ) ) );
                }
            }
        catch ( MavenInvocationException e )
            {
            e.printStackTrace();
            }
        } // testUnit()
    } // MavenTestRunner

Created a Run Configuration according to {workspace}/.metadata/.plugins/org.eclipse.debug.core/.launches/Test selected test unit with Maven.launch

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/SO-30767338/src/test/java/MavenTestRunner.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value="testUnit"/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="MavenTestRunner"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="SO-30767338"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dpom=${project_loc}/pom.xml -Dunit=${selected_resource_name}"/>
</launchConfiguration>

Note the essential part in VM arguments:

-Dpom=${project_loc}/pom.xml -Dunit=${selected_resource_name}

After I had all this set up I selected a JUnit class (not MavenTestRunner, of course :-) and invoked the run configuration created above via the Run icon's () dropdown list. Voilà! Like a charm!

The only shortcoming is that it can't be invoked via a resource's context menu. Anyone keen to write an Eclipse plugin?