web-dev-qa-db-ja.com

テストをJUnit3からJUnit4に自動的に移行する最良の方法は?

TestCaseを拡張するJUnit3クラスがたくさんあり、それらを@Before@After@Testなどのアノテーション付きのJUnit4テストに自動的に移行したいと考えています。
大規模なバッチ実行でこれを行うためのツールはありますか?

45
Epaga

私の意見では、それはそれほど難しいことではありません。それでは、試してみましょう。

0.輸入

3つの注釈をインポートする必要があります。

_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_を取り除きます

文字列のファイルごとに1つのオカレンスを削除します

_" extends TestCase"
_

4.メインメソッドを削除しますか?

おそらく、テストを実行する既存のメインメソッドを削除/リファクタリングする必要があります。

5. suite()メソッドを_@RunWithClass_に変換します

Sauaのコメントによると、suite()メソッドの変換が必要です。ありがとう、サウア!

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

結論

たとえそれが私の脳を殺すとしても、それは一連の正規表現を介して非常に簡単に行われると思います;)

54
guerda

これが、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

注:上記の順序で実行することが重要です。

35

適度に大きなコードベースをJUnit4に移行している最中です。このような移行を行うのはこれが2回目なので、コードをどこかに保存することにしました。

https://github.com/FranciscoBorges/junit3ToJunit4

上記の回答に列挙されているものよりも多くのコーナーケースを扱います。といった:

  • TestCase.setUp()およびTestCase.tearDown()の呼び出し
  • サブクラスコンストラクター内のTestCase(String)コンストラクターの呼び出し
  • Assertに移動したTestCase.assert*メソッドの呼び出し。
  • パッケージ名をjunit.frameworkからorg.junitに修正
4
Francisco

現時点でこれを行うツールはわかりません-Eclipseがすぐにプラグインを提供することを期待しています-しかし、Java classthatを探索する単純なソースツリーをノックアップすることができます基本的な変換のみを行いたい場合は、それを行います。レガシーアプリケーションのスケルトンテストケースを自動的に生成するようなものを作成する必要があったため、かなりの量のサポートコードがすでに用意されています。これを使って。

3
Gary Rowe

私の知る限り、利用可能な移行ツールは(まだ)ありません。私が知っているのはこれです:

  • 昨年、ナッシュビルのOOPSLAで、API移行に関する論文がありましたが、残念ながら、彼らのツールは公開されていないようです。論文へのリンクを提供します(理論的にはかなり重いので、あえてほとんど役に立たないのですが): "アノテーションリファクタリング:レガシーアプリケーションのアップグレード変換の推測"

  • 上記では、学生のLeaHänsenbergerが現在、onylではなくJUnit 4 aからJExampleへの、またJUnit3からJUnit4への自動API移行に取り組んでいるため、「利用可能なツールは(まだ)ありません」と書きました。お願いします Twitter でJExampleをフォローして、彼女が最初のベータ版をリリースしたときに通知を受け取ります。

この情報がお役に立てば幸いです。

3
akuhn

素敵な投稿。次の正規表現文字列を使用してNetbeansを使用してアップグレードを行いました:(最初の行の検索文字列、2番目の行の置換文字列)

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

正規表現チェックボックスにフラグを立てることを忘れないでください!

1
Designpattern