java 自动将测试从 JUnit 3 迁移到 JUnit 4 的最佳方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/264680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:41:31  来源:igfitidea点击:

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

javajunitmigration

提问by Epaga

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?

我有一帮其扩展TestCase,并希望自动迁移他们是JUnit4测试与注释如JUnit 3班的@Before@After@Test
任何工具都来在大批量运行做到这一点?

回答by guerda

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

在我看来,这不可能那么难。那么让我们试试看:

0. Imports

0. 进口

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

进行接下来的几项更改后,您将不需要import junit.framework.TestCase;.

1. Annotate test*Methods

1. 注释test*方法

All methods beginning with public void testmust be preceded by the @Testannotation. This task is easy with a regex.

所有以 开头的方法都public void test必须以@Test注解开头。使用正则表达式可以轻松完成此任务。

2. Annotate SetUp and TearDown methods

2.注释SetUp和TearDown方法

Eclipse generates following setUp()method:

Eclipse 生成以下setUp()方法:

@Override
protected void setUp() throws Exception { }

Must be replaced by:

必须替换为:

@Before
public void setUp() throws Exception { }

Same for tearDown():

同样适用于tearDown()

@Override
protected void tearDown() throws Exception { }

replaced by

取而代之

@After
public void tearDown() throws Exception { }

3. Get rid of extends TestCase

3.摆脱 extends TestCase

Remove exactly one occurence per file of the string

只删除字符串的每个文件一次

" extends TestCase"

4. Remove main methods?

4. 删除主要方法?

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

可能有必要删除/重构将执行测试的现有主要方法。

5. Convert suite()method to @RunWithClass

5. 转换suite()方法为@RunWithClass

According to saua's comment, there must be a conversion of the suite()method. Thanks, saua!

根据saua的评论,必须有suite()方法的转换。谢谢,莎阿!

@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 ;)

我认为,通过一组正则表达式可以很容易地完成,即使它会杀死我的大脑;)

回答by Geoffrey De Smet

Here are the actual regular expressions I used to execute furtelwart's suggestions:

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

// Add @Test
Replace:
^[ \t]+(public +void +test)
With:
    @Test\n    
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.

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

回答by Francisco

We are in the middle of migrating a reasonably large code base to JUnit4. Since this is the second time I'm doing a migration such as this, I decided to save the code somewhere:

我们正在将相当大的代码库迁移到 JUnit4。由于这是我第二次进行这样的迁移,我决定将代码保存在某处:

https://github.com/FranciscoBorges/junit3ToJunit4

https://github.com/FranciscoBorges/junit3ToJunit4

It deals with more corner cases than the ones enumerated in answers above. Such as:

它处理的极端情况比上述答案中列举的情况更多。如:

  • calls to TestCase.setUp()and TestCase.tearDown()
  • calls to TestCase(String)constructor within a sub-class constructor
  • calls to TestCase.assert*methods that moved to Assert.
  • fixing package names junit.frameworkto org.junit
  • etc
  • 调用TestCase.setUp()TestCase.tearDown()
  • TestCase(String)在子类构造函数中调用构造函数
  • TestCase.assert*移动到 的方法的调用Assert
  • 将包名称固定junit.frameworkorg.junit
  • 等等

回答by Gary Rowe

I don't know of a tool that would do this at the moment - I'd expect Eclipse to provide some plugin fairly shortly - but you could knock up a simple source tree exploring Java class that would do it for you if you only want to do a basic conversion. I had to write something similar to automatically generate skeleton test cases for a legacy application so I've got a fair amount of the support code already. You're welcome to use it.

我目前不知道有什么工具可以做到这一点——我希望 Eclipse 能够很快提供一些插件——但是你可以敲出一个简单的源代码树来探索 Java 类,如果你只需要它会为你做这件事做一个基本的转换。我必须编写类似的东西来为遗留应用程序自动生成框架测试用例,所以我已经有了相当数量的支持代码。欢迎您使用它。

回答by akuhn

There are, to my best knowledge, no available migration tools (yet). What I know is this:

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

  • Last year, at OOPSLA in Nashville, was a paper about API migration but alas their tools seems not be openly available. I'll provide the link to the paper, (even though I dare it is of little use for you since it is rather theory heavy): "Annotation Refactoring: Inferring Upgrade Transformations for Legacy Applications".

  • Above, I wrote "no available tool (yet)" because my student Lea H?nsenberger is currently working on an auotmated API migration from, not onyl, JUnit 4 a to JExample, but also from JUnit 3 to JUnit 4. Please follow JExample on Twitterto get notified when she releases a first beta.

  • 去年,在纳什维尔的 OOPSLA 上,有一篇关于 API 迁移的论文,但可惜他们的工具似乎没有公开可用。我将提供该论文的链接(尽管我认为它对您没有多大用处,因为它理论性很强):“注释重构:推断遗留应用程序的升级转换”

  • 上面,我写了“没有可用的工具(还)”,因为我的学生 Lea H?nsenberger 目前正在研究从 JUnit 4 a 到 JExample,以及从 JUnit 3 到 JUnit 4 的自动化 API 迁移。请关注 JExample在 Twitter 上发布第一个 Beta 版时收到通知。

I hope this information was of help for you.

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

回答by Designpattern

Nice post. I did the upgrade using Netbeans with the following RegEx strings: (First line search-string, second one replace-string)

好贴。我使用带有以下 RegEx 字符串的 Netbeans 进行了升级:(第一行搜索字符串,第二行替换字符串)

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

Don't forget to flag the Regular Expression checkbox!

不要忘记标记正则表达式复选框!

回答by psuzzi

If you want to automatically convertyour Junit3 tests to Junit4, you can use the Vogella's Codemodify tool, available at this address:

如果您想自动将您的 Junit3 测试转换为 Junit4,您可以使用 Vogella 的 Codemodify 工具,可在以下地址获得:

TL;DR install and use it as follows:

TL;DR 安装和使用如下:

Then, you can right-click any Junit3 test class, and select the Source > Convert to JUnit4menu entry to convert your class to JUnit4.

然后,您可以右键单击任何 Junit3 测试类,并选择Source > Convert to JUnit4菜单项将您的类转换为 JUnit4。

enter image description here

在此处输入图片说明

The tool will automagically remove TestCase parent, outdated imports, add @Before, @After, @Testannotations, etc.

该工具将自动删除 TestCase parent、过时的导入、添加@Before@After@Test注释等。