51 votes

Meilleur moyen de migrer automatiquement les tests de JUnit 3 vers JUnit 4 ?

J'ai un tas de classes JUnit 3 qui étendent TestCase et je voudrais les migrer automatiquement vers des tests JUnit4 avec des annotations telles que @Before , @After , @Test etc.
Existe-t-il un outil permettant de faire cela dans un grand lot ?

1 votes

Je ne réponds pas à la question, mais vous réalisez que vous pouvez exécuter des tests JUnit3 sous JUnit4 sans modification, oui ?

2 votes

A moins que vous n'utilisiez Junit3 TestSuite dans ce cas, vous êtes fichu.

6 votes

Si vous conservez ces tests JUnit 3, les autres développeurs (selon la taille de votre équipe) continueront à les copier dans de nouveaux tests. Et s'ils ont besoin de désactiver temporairement un test (oui, ils ne devraient pas, mais parfois ils en auront besoin), ils continueront à le renommer de testX en FIMXEtestX au lieu de l'annoter avec @Ignore. Vous n'aurez donc aucune idée du nombre de tests qui sont actuellement ignorés (et donc de l'inquiétude que vous devriez avoir). Prenez n'importe quel gros projet et cherchez la regex "public void \w +test"

60voto

guerda Points 7417

À mon avis, cela ne doit pas être si difficile. Alors essayons :

0. Importations

Vous devez importer trois annotations :

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

Après avoir fait les quelques changements suivants, vous n'aurez plus besoin import junit.framework.TestCase; .

1. Annotez test* Méthodes

Toutes les méthodes commençant par public void test doit être précédé de la mention @Test annotation. Cette tâche est facile avec une regex.

2. Annoter les méthodes SetUp et TearDown

Eclipse génère ce qui suit setUp() méthode :

@Override
protected void setUp() throws Exception { }

Doit être remplacé par :

@Before
public void setUp() throws Exception { }

Idem pour tearDown() :

@Override
protected void tearDown() throws Exception { }

remplacé par

@After
public void tearDown() throws Exception { }

3. Se débarrasser de extends TestCase

Supprimer exactement une occurence par fichier de la chaîne de caractères

" extends TestCase"

4. Supprimer les méthodes principales ?

Il est probablement nécessaire de supprimer/refaire les méthodes principales existantes qui exécuteront le test.

5. Convertir suite() pour @RunWithClass

Selon le commentaire de saua, il doit y avoir une conversion de la suite() méthode. Merci, saua !

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

Conclusion

Je pense que cela se fait très facilement via un jeu d'expressions régulières, même si cela va me tuer le cerveau ;)

0 votes

Les importations peuvent être nettoyées automatiquement par Eclipse (Ctrl + Shift + O).

0 votes

Je ne pense pas qu'il veuille faire ça avec un tas de fichiers. Et ils devraient être exécutables.

2 votes

J'ajouterais la conversion des méthodes suite() à @RunWith(Suite.class) @SuiteCkasses()

39voto

Geoffrey De Smet Points 6032

Voici les expressions régulières réelles que j'ai utilisées pour exécuter les suggestions de 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

Remarque : il est important de les faire dans l'ordre indiqué ci-dessus.

0 votes

Y a-t-il un moyen d'exécuter ceci ?

0 votes

Oui. Dans IntelliJ, faites "Remplacer dans le chemin" (ctrl-shift-r) et remplissez cette boîte de dialogue pour chacun d'entre eux. Pour ceux qui doivent être faits manuellement, utilisez "Find in path" (ctrl-shift-f).

0 votes

6voto

Francisco Points 1538

Nous sommes au milieu de la migration d'une base de code assez importante vers JUnit4. Comme c'est la deuxième fois que je fais une migration de ce type, j'ai décidé de sauvegarder le code quelque part :

https://github.com/FranciscoBorges/junit3ToJunit4

Il traite d'autres cas de figure que ceux énumérés dans les réponses ci-dessus. Par exemple :

  • appels à TestCase.setUp() et TestCase.tearDown()
  • appels à TestCase(String) dans le constructeur d'une sous-classe
  • appels à TestCase.assert* qui sont passés à Assert .
  • Correction des noms de paquets junit.framework à org.junit
  • etc.

3voto

Gary Rowe Points 4220

Je ne connais pas d'outil qui puisse faire cela pour le moment - je m'attends à ce qu'Eclipse fournisse un plugin assez rapidement - mais vous pourriez créer une classe Java simple d'exploration de l'arbre source qui le ferait pour vous si vous voulez seulement faire une conversion de base. J'ai dû écrire quelque chose de similaire pour générer automatiquement des cas de test squelettiques pour une ancienne application, j'ai donc déjà une bonne partie du code de support. Vous êtes le bienvenu pour l'utiliser.

2 votes

Utilisez-vous la fonction AST de java6 ou celle d'eclipse ? Quoi qu'il en soit, je suis également intéressé : peut-être pourriez-vous envisager de faire de cette question un "code-challenge" et de publier votre code anonymisé sur DZones ? (voir stackoverflow.com/questions/190007 pour un exemple de "code-chalenge")

3voto

akuhn Points 12241

Il n'existe pas (encore), à ma connaissance, d'outils de migration disponibles. Ce que je sais, c'est ceci :

  • L'année dernière, à l'OOPSLA de Nashville, il y a eu un article sur la migration des API mais, hélas, leurs outils ne semblent pas être ouvertement disponibles. Je vais fournir le lien vers le document (même si je pense qu'il ne vous sera pas d'une grande utilité car il est plutôt théorique) : "Annotation Refactoring : Inférer les transformations de mise à niveau pour les applications patrimoniales". .

  • Ci-dessus, j'ai écrit "aucun outil disponible (pour le moment)" parce que mon étudiante Lea Hänsenberger travaille actuellement sur une migration API auotmée de, non seulement, JUnit 4 a à JExample, mais aussi de JUnit 3 à JUnit 4. S'il vous plaît suivez JExample sur Twitter pour être prévenu quand elle publiera une première version bêta.

J'espère que ces informations vous ont été utiles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X