java - test - junit software
¿La mejor manera de migrar automágicamente las pruebas de JUnit 3 a JUnit 4? (6)
No sé de una herramienta que pueda hacer esto en este momento (esperaría que Eclipse proporcione algún plugin en breve), pero podrías crear un simple árbol fuente explorando la clase Java que lo haría por ti si solo quieres hacer una conversión básica Tuve que escribir algo similar para generar automáticamente casos de prueba de esqueleto para una aplicación heredada, por lo que ya tengo una buena cantidad del código de soporte. Eres bienvenido para usarlo.
Tengo un montón de clases JUnit 3 que extienden TestCase y me gustaría migrarlas automáticamente para que sean pruebas JUnit4 con anotaciones como @Before
, @Test
, @Test
, etc.
¿Alguna herramienta para hacer esto en una gran tanda de lotes?
Hay, para mi mejor conocimiento, ninguna herramienta de migración disponible (todavía). Lo que sé es esto:
El año pasado, en OOPSLA en Nashville, había un documento sobre la migración API, pero lamentablemente sus herramientas no parecen estar disponibles abiertamente. Proporcionaré el enlace al documento (aunque me atrevo a utilizarlo poco, ya que es bastante teórico): "Refactorización de anotaciones: Inferir transformaciones de actualización para aplicaciones heredadas" .
Arriba, escribí "no hay herramienta disponible (todavía)" porque mi estudiante Lea Hänsenberger está trabajando actualmente en una migración de API auotmated de, no onyl, JUnit 4 a JExample, sino también de JUnit 3 a JUnit 4. Siga JExample en Twitter para recibir una notificación cuando lanza una primera versión beta.
Espero que esta información haya sido de ayuda para ti.
Buen post. Hice la actualización usando Netbeans con las siguientes cadenas de RegEx: (Primera línea de búsqueda de cadena, segunda de reemplazo de cadena)
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
¡No olvide marcar la casilla de verificación Expresión regular!
Aquí están las expresiones regulares reales que utilicé para ejecutar las sugerencias 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
Nota: es importante hacerlo en el orden que se muestra arriba.
Estamos en el medio de migrar una base de código razonablemente grande para JUnit4. Como esta es la segunda vez que realizo una migración como esta, decidí guardar el código en alguna parte:
https://github.com/FranciscoBorges/junit3ToJunit4
Trata con más casos de esquina que los enumerados en las respuestas anteriores. Como:
- llamadas a
TestCase.setUp()
yTestCase.tearDown()
- llama al
TestCase(String)
dentro de un constructor de subclase - llamadas a métodos
TestCase.assert*
que se movieron aAssert
. - arreglando nombres de paquetes
junit.framework
toorg.junit
- etc
En mi opinión, no puede ser tan difícil. Así que probemos:
0. Importaciones
Necesitas importar tres anotaciones:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;`
Después de realizar los siguientes cambios, no necesitará import junit.framework.TestCase;
.
1. test*
anotación test*
Métodos
Todos los métodos que comienzan con public void test
deben ir precedidos por la anotación @Test
. Esta tarea es fácil con una expresión regular.
2. Anotar los métodos SetUp y TearDown
Eclipse genera el siguiente método setUp()
:
@Override
protected void setUp() throws Exception { }
Debe ser reemplazado por:
@Before
public void setUp() throws Exception { }
Lo mismo para tearDown()
:
@Override
protected void tearDown() throws Exception { }
reemplazado por
@After
public void tearDown() throws Exception { }
3. Deshacerse de extends TestCase
Eliminar exactamente una ocurrencia por archivo de la cadena
" extends TestCase"
4. Eliminar los métodos principales?
Probablemente sea necesario eliminar / refactorizar los principales métodos existentes que ejecutarán la prueba.
5. Convierte el método suite()
en @RunWithClass
Según el comentario de saua, debe haber una conversión del método suite()
. Gracias, saua!
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestDog.class
TestCat.class
TestAardvark.class
})
Conclusión
Creo que se hace muy fácil mediante un conjunto de expresiones regulares, incluso si eso mata mi cerebro;)