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

发布于 2024-07-07 16:50:03 字数 152 浏览 6 评论 0 原文

我有一堆 JUnit 3 类,它们扩展了 TestCase,并希望自动将它们迁移为带有注释的 JUnit4 测试,例如 @Before@After@测试
有什么工具可以在大批量运行中执行此操作吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

逐鹿 2024-07-14 16:50:04

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

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.

以可爱出名 2024-07-14 16:50:04

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

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

  • 上面,我写了“尚无可用工具”,因为我的学生 Lea Hänsenberger 目前正在致力于自动 API 迁移,不仅从 JUnit 4 a 迁移到 JExample,而且还从 JUnit 3 迁移到 JUnit 4。请< a href="http://twitter.com/jexample" rel="nofollow noreferrer">在 Twitter 上关注 JExample,以便在她发布第一个测试版时收到通知。

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

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 Twitter to get notified when she releases a first beta.

I hope this information was of help for you.

何其悲哀 2024-07-14 16:50:04

好贴。 我使用 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

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

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

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!

稳稳的幸福 2024-07-14 16:50:04

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

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

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

输入图片此处描述

该工具将自动删除 TestCase 父级、过时的导入、添加 @Before@After @Test 注解等

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

TL;DR install and use it as follows:

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

enter image description here

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

梦罢 2024-07-14 16:50:03

在我看来,这并没有那么难。 那么让我们尝试一下:

0. 导入

您需要导入三个注释:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;`

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

1. 注解 test* 方法

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

2. 注释 SetUp 和 TearDown 方法

Eclipse 生成以下 setUp() 方法:

@Override
protected void setUp() throws Exception { }

必须替换为:

@Before
public void setUp() throws Exception { }

tearDown() 相同:

@Override
protected void tearDown() throws Exception { }

替换为

@After
public void tearDown() throws Exception { }

3. 去掉 extends TestCase

精确删除每个文件中出现的一次字符串

" extends TestCase"

4. 删除主要方法吗?

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

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

根据saua的注释,必须对suite()方法进行转换。 谢谢,萨阿!

@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestDog.class
  TestCat.class
  TestAardvark.class
})

结论

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

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

烂人 2024-07-14 16:50:03

以下是我用来执行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

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

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.

谎言 2024-07-14 16:50:03

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

https:// /github.com/FranciscoBorges/junit3ToJunit4

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

  • 调用TestCase.setUp()TestCase.tearDown()
  • 在子类构造函数中调用TestCase(String)构造函数
  • 对移至 AssertTestCase.assert* 方法的调用。
  • 将包名称 junit.framework 修复为 org.junit

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:

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.framework to org.junit
  • etc
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文