Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 327079 - [JUnit] Can't run single test with JUnit 4 launcher if there's a suite() method
Summary: [JUnit] Can't run single test with JUnit 4 launcher if there's a suite() method
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.7 M4   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-06 05:34 EDT by Dani Megert CLA
Modified: 2010-12-07 03:53 EST (History)
3 users (show)

See Also:


Attachments
Fix (8.14 KB, patch)
2010-12-06 17:17 EST, Markus Keller CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dani Megert CLA 2010-10-06 05:34:20 EDT
I20101005-0800.

Test Case:
Try to run test1 from the following source with the JUnit 4 launcher.

import junit.framework.Test;
import junit.framework.TestCase;

public class Sample extends TestCase {

	public void test1() {
		System.out.println("1");
	}

	public static Test suite() {
		return null;
	}

	public void test2() {
		System.out.println("2");
	}

}
Comment 1 Markus Keller CLA 2010-10-06 10:14:14 EDT
There are a bunch of slightly different problems when running single JUnit 3 tests with the JUnit 4 runner, depending on whether suite() and/or setUpTest(Test) methods exist and how they are implemented.

It looks like JUnit 4 does not support setUpTest(Test) at all and always runs the suite() method to collect the tests to run. This is a bug in the JUnit 4 Runner (it's not backwards compatible with JUnit 3). Furthermore, the single-method-filter only seems to work if the suite() method returns a simple TestSuite, but not if it uses a TestSetup.


Test case to play with:

import junit.extensions.TestSetup;

public class Sample extends TestCase {

    public void test1() {
        System.out.println("1");
    }

    public static Test suite() {
//    	return new MySetup(new TestSuite(Sample.class), "suite");
    	return new TestSuite(Sample.class);
    }

    public static Test setUpTest(Test test) {
    	return new MySetup(test, "setUpTest");
    }
    
    public void test2() {
        System.out.println("2");
    }

}

class MySetup extends TestSetup {
	private final String fName;

	public MySetup(Test test, String name) {
		super(test);
		fName = name;
	}

	@Override
	protected void setUp() throws Exception {
		System.out.println("MySetup: " + fName);
	}
}
Comment 2 Deepak Azad CLA 2010-10-29 11:50:45 EDT
Isn't this a critical/major bug? Currently it is very painful to run a single test from o.e.jdt.ui.tests and o.e.jdt.ui.refactoring.tests. 

I run a single test by selecting it in outline view and then invoking 'Run as > JUnit plug-in test' from the context menu. By default the  JUnit4 runner is chosen as these projects have execution env set to J2SE-1.5. Once the tests are started I stop them, open the launch config and select the JUnit 3 runner and start the test again. This is too many steps...

Or is there a workaround that I do not know ?
Comment 3 Markus Keller CLA 2010-10-29 12:09:50 EDT
I agree this is painful, but it's nothing new and I didn't have time to dig into it.

I'll have a look for M4. Most probably, the fix will have to go into JUnit 4.
Comment 4 Dani Megert CLA 2010-11-29 05:55:09 EST
(In reply to comment #3)
> I agree this is painful, but it's nothing new and I didn't have time to dig
> into it.
> 
> I'll have a look for M4. Most probably, the fix will have to go into JUnit 4.
See also bug 299844.
Comment 5 Dani Megert CLA 2010-11-29 05:55:31 EST
*** Bug 169222 has been marked as a duplicate of this bug. ***
Comment 6 Markus Keller CLA 2010-12-06 05:30:25 EST
The problem is that the "public static Test setUpTest(Test)" is an Eclipse-only functionality and is implemented in JUnit3TestLoader. We need to do something similar in JUnit4TestMethodReference, but that's not trivial because JUnit 4 has so many indirections everywhere and many interesting classes are not API.

I have something in the works that should solve the problem, but it needs polish and testing.
Comment 7 Markus Keller CLA 2010-12-06 17:17:17 EST
Created attachment 184667 [details]
Fix

I gave up adding special support for setUpTest in the JUnit 4 runner. Instead, I just fall back to the JUnit 3 runner when this situation is detected.

Testers: Note that the suite() method from comment 0 is invalid, and that it throws an NPE is a bug in org.junit.internal.runners.JUnit38ClassRunner.
Comment 8 Markus Keller CLA 2010-12-06 17:18:40 EST
Fixed in HEAD.
Comment 9 Deepak Azad CLA 2010-12-07 03:16:24 EST
(In reply to comment #7)
> Created an attachment (id=184667) [details] [diff]
> Fix
> 
> I gave up adding special support for setUpTest in the JUnit 4 runner. Instead,
> I just fall back to the JUnit 3 runner when this situation is detected.
Markus, the launch config still shows JUnit 4, is this deliberate ? I think it is misleading to use JUnit 3 runner internally but show JUnit 4 in the launch config.
Comment 10 Dani Megert CLA 2010-12-07 03:53:57 EST
(In reply to comment #8)
> Fixed in HEAD.
Thank you!!!
Verified in I20101206-1800.


> Markus, the launch config still shows JUnit 4, is this deliberate ? I think it
> is misleading to use JUnit 3 runner internally but show JUnit 4 in the launch
> config.
The behavior is correct as it uses the JUnit 4 launcher as indicated in the launch config. How the code is implemented internally (e.g. fall back to JUnit 1 launcher) doesn't matter.