I have a bunch of JUnit 3 classes which extend TestCase and would like to automatically migrate them to be JUnit4 tests with annotations such as @Before
, @After
, @Test
, etc.
Any tool out there to do this in a big batch run?
Only one test runner can execute tests at a time in JUnit 4 (e.g. SpringJUnit4ClassRunner or Parameterized ). JUnit 5 allows multiple runners to work simultaneously. JUnit 4 never advanced beyond Java 7, missing out on a lot of features from Java 8. JUnit 5 makes good use of the Java 8 features.
Use Find Action with ⌘⇧A (macOS), or Ctrl+Shift+A (Windows/Linux), and type Migrate, to see migration options for the code. IntelliJ IDEA offers the option to migrate the code from JUnit 4 to 5. This migration is similar to what we did with the individual test class, but for all test classes.
JDK required. JUnit 4 uses a lot from Java 5 annotations, generics, and static import features. Although the JUnit 3. x version can work with JDK 1.2+, this usage requires that the new version of JUnit be used with Java 5 or higher.
In my opinion, it cannot be that hard. So let's try it:
You need to import three annotations:
import org.junit.After; import org.junit.Before; import org.junit.Test;`
After you've made the next few changes, you won't need import junit.framework.TestCase;
.
test*
MethodsAll methods beginning with public void test
must be preceded by the @Test
annotation. This task is easy with a regex.
Eclipse generates following setUp()
method:
@Override protected void setUp() throws Exception { }
Must be replaced by:
@Before public void setUp() throws Exception { }
Same for tearDown()
:
@Override protected void tearDown() throws Exception { }
replaced by
@After public void tearDown() throws Exception { }
extends TestCase
Remove exactly one occurence per file of the string
" extends TestCase"
Probably it's necessary to remove/refactor existing main methods that will execute the test.
suite()
method to @RunWithClass
According to saua's comment, there must be a conversion of the suite()
method. Thanks, saua!
@RunWith(Suite.class) @Suite.SuiteClasses({ TestDog.class TestCat.class TestAardvark.class })
I think, it's done very easy via a set of regular expressions, even if it will kill my brain ;)
Here are the actual regular expressions I used to execute furtelwart's suggestions:
// Add @Test Replace: ^[ \t]+(public +void +test) With: @Test\n $1 Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove double @Test's on already @Test annotated files Replace: ^[ \t]+@Test\n[ \t]+@Test With: @Test Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove all empty setUp's Replace: ^[ \*]+((public|protected) +)?void +setUp\(\)[^\{]*\{\s*(super\.setUp\(\);)?\s*\}\n([ \t]*\n)? With nothing Regular Expression: on Case sensitive: on File name filter: *Test.java // Add @Before to all setUp's Replace: ^([ \t]+@Override\n)?[ \t]+((public|protected) +)?(void +setUp\(\)) With: @Before\n public void setUp() Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove double @Before's on already @Before annotated files Replace: ^[ \t]+@Before\n[ \t]+@Before With: @Before Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove all empty tearDown's Replace: ^[ \*]+((public|protected) +)?void +tearDown\(\)[^\{]*\{\s*(super\.tearDown\(\);)?\s*\}\n([ \t]*\n)? With nothing Regular Expression: on Case sensitive: on File name filter: *Test.java // Add @After to all tearDown's Replace: ^([ \t]+@Override\n)?[ \t]+((public|protected) +)?(void +tearDown\(\)) With: @After\n public void tearDown() Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove double @After's on already @After annotated files Replace: ^[ \t]+@After\n[ \t]+@After With: @After Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove old imports, add new imports Replace: ^([ \t]*import[ \t]+junit\.framework\.Assert;\n)?[ \t]*import[ \t]+junit\.framework\.TestCase; With: import org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport static org.junit.Assert.*; Regular Expression: on Case sensitive: on File name filter: *Test.java // Remove all extends TestCase Replace: [ \t]+extends[ \t]+TestCase[ \t]+\{ With: { Regular Expression: on Case sensitive: on File name filter: *Test.java // Look for import junit.framework; Find: import junit\.framework Manually fix Regular Expression: on Case sensitive: on // Look for ignored tests (FIXME, disabled, ...) Find: public[ \t]+void[ \t]+\w+test Manually fix Regular Expression: on Case sensitive: on // Look for dummy/empty tests Find: public[ \t]+void[ \t]+test[\w\d]*\(\s*\)\s*\{\s*(//[^\n]*)?\s*\} Manually fix Regular Expression: on Case sensitive: on
Note: it's important to do them in the order shown above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With