Java 自动将测试从JUnit3迁移到JUnit4的最佳方法?

Java 自动将测试从JUnit3迁移到JUnit4的最佳方法?,java,junit,migration,Java,Junit,Migration,我有一大堆JUnit 3类,它们扩展了TestCase,并希望自动将它们迁移为JUnit4测试,带有注释,如@Before,@Before,@Test,等等。 有任何工具可以在大批量运行中实现这一点吗?目前我不知道有哪种工具可以实现这一点-我希望Eclipse很快会提供一些插件-但是如果您只想进行基本转换,您可以创建一个简单的源代码树来探索Java类。我必须编写一些类似于为遗留应用程序自动生成框架测试用例的东西,所以我已经有了大量的支持代码。欢迎你使用它 据我所知,目前还没有可用的迁移工具。我知

我有一大堆JUnit 3类,它们扩展了TestCase,并希望自动将它们迁移为JUnit4测试,带有注释,如
@Before
@Before
@Test
,等等。

有任何工具可以在大批量运行中实现这一点吗?

目前我不知道有哪种工具可以实现这一点-我希望Eclipse很快会提供一些插件-但是如果您只想进行基本转换,您可以创建一个简单的源代码树来探索Java类。我必须编写一些类似于为遗留应用程序自动生成框架测试用例的东西,所以我已经有了大量的支持代码。欢迎你使用它

据我所知,目前还没有可用的迁移工具。我知道的是:

  • 去年,在纳什维尔的OOPSLA上,有一篇关于API迁移的论文,但遗憾的是,他们的工具似乎没有公开提供。我会提供这篇论文的链接(尽管我敢说它对你没有什么用处,因为它理论性很强):

  • 在上面,我写了“还没有可用的工具”,因为我的学生Lea Hänsenberger目前正在进行一个从JUnit 4 a到JExample的辅助API迁移,而不是onyl,而是从JUnit 3到JUnit 4的迁移。请在她发布第一个测试版时得到通知


我希望这些信息能对你有所帮助。

在我看来,不会那么难。那么,让我们试试:

0进口 您需要导入三个注释:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;`
在完成接下来的几项更改后,您将不需要
import junit.framework.TestCase

1.注释
测试*
方法 所有以
public void test
开头的方法前面必须有
@test
注释。 使用正则表达式可以轻松完成此任务

2.注释设置和拆卸方法 Eclipse生成以下
setUp()
方法:

@Override
protected void setUp() throws Exception { }
必须替换为:

@Before
public void setUp() throws Exception { }
与拆卸()相同。

取代

@After
public void tearDown() throws Exception { }
3.摆脱
扩展测试用例
每个字符串文件只删除一次

" extends TestCase"
4.删除主要方法? 可能有必要删除/重构将执行测试的现有主要方法

5.将
suite()
方法转换为
@RunWithClass
根据saua的评论,必须对
suite()
方法进行转换。谢谢,saua

@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestDog.class
  TestCat.class
  TestAardvark.class
})
结论
我认为,通过一组正则表达式可以很容易地完成,即使它会杀死我的大脑;)

不错的帖子。我使用具有以下正则表达式字符串的Netbeans进行了升级: (第一行搜索字符串,第二行替换字符串)


别忘了标记正则表达式复选框

以下是我用来执行furtelwart建议的实际正则表达式:

// 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

注意:按上面的顺序执行它们是很重要的。

< P>我们正在迁移一个相当大的代码库到JunIT4。由于这是我第二次进行这样的迁移,我决定将代码保存到某个地方:

它处理的角落案例比上述答案中列举的案例要多。例如:

  • 调用
    TestCase.setUp()
    TestCase.tearDown()
  • 调用子类构造函数中的
    TestCase(String)
    构造函数
  • 调用移动到
    assert
    TestCase.assert*
    方法
  • 正在将包名
    junit.framework
    修复为
    org.junit
如果您想自动将Junit3测试转换为Junit4,可以使用Vogella的Codemodify工具,该工具位于以下地址:

TL;DR按如下方式安装和使用它:

  • 如果您还没有使用Eclipse,请获取它(它是开源的)
  • 从菜单:帮助>安装新软件,然后将更新站点粘贴到“使用”字段中
  • 完成安装,必要时重新启动
然后,您可以右键单击任何Junit3测试类,并选择源代码>转换为JUnit4菜单项以将类转换为JUnit4


该工具将自动删除测试用例父项、过时的导入、添加@Before、@After、@Test注释等。

您使用的是java6 AST功能还是eclipse AST?无论如何,我也很感兴趣:你可以考虑把这个问题变成“代码挑战”,然后在DZALE上发布你的匿名代码吗?(参见“CodeChalenge”示例)Eclipse(Ctrl+Shift+O)可以自动清理导入。我不认为他想用一堆文件来完成这项工作。我会添加suite()方法到@RunWith(suite.class)@SuiteCkasses()的转换setUp(),tearDown()方法必须在JUnit4中是公共的。我需要的另一个步骤是将@RunWith(JUnit4.class)添加到我的类中并导入这些东西:import org.junit.runner.RunWith;导入org.junit.runners.JUnit4;没有回答这个问题,但您确实意识到您可以在JUnit4下运行JUnit3测试,而无需修改,是吗?除非您使用JUnit3
TestSuite
,否则您会被填满。如果您保留这些JUnit3测试,其他开发人员(取决于您的团队规模)会继续将它们复制到新的测试中。如果他们需要临时禁用一个测试(是的,不应该,但有时他们需要),他们将继续将它从testX重命名为FIMXEtestX,而不是用@Ignore注释它。所以你不会知道目前有多少测试被忽略了(所以你应该有多担心)。就拿任何一个大项目来说,看看regex“public void\w+test”有没有办法运行它?是的。在IntelliJ中,执行“替换路径”(ctrl-shift-r)并为每个路径填充该对话框。对于那些需要手动完成的操作,请使用“在路径中查找”(ctrl-shift-f)。
public void test
@Test\n    public void test

@Override\n.*protected void onSetUp
@Before\n    protected void onSetUp

@Override\n.*protected void onTearDown
@After\n    protected void onTearDown
// 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