Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to automagically migrate tests from JUnit 3 to JUnit 4?

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?

like image 279
Epaga Avatar asked Nov 05 '08 09:11

Epaga


People also ask

Is junit5 better than junit4?

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.

How do I migrate from JUnit 4 to JUnit 5 in IntelliJ?

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.

What is difference between JUnit 3 and JUnit 4?

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.


2 Answers

In my opinion, it cannot be that hard. So let's try it:

0. Imports

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;.

1. Annotate test* Methods

All methods beginning with public void test must be preceded by the @Test annotation. This task is easy with a regex.

2. Annotate SetUp and TearDown methods

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 { } 

3. Get rid of extends TestCase

Remove exactly one occurence per file of the string

" extends TestCase" 

4. Remove main methods?

Probably it's necessary to remove/refactor existing main methods that will execute the test.

5. Convert 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 }) 

Conclusion

I think, it's done very easy via a set of regular expressions, even if it will kill my brain ;)

like image 154
guerda Avatar answered Oct 21 '22 20:10

guerda


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.

like image 28
Geoffrey De Smet Avatar answered Oct 21 '22 20:10

Geoffrey De Smet