Palíndromo en Java + Junit

Turco

La actividad dice así:

El objetivo de esta actividad es diseñar las pruebas a realizar sobre una clase con JUnit.
a. Desarrolla en Java una clase que crea un palíndromo a partir de una cadena dada. Por
ejemplo, si la entrada fuera “Vacaciones”, debería retornarse “VacacionessenoicacaV”
b. Escribe el código de la clase Test para el código anterior, de manera que se incluyan los
siguientes casos de prueba:

  1. TestVacío, para una string de entrada vacía.
  2. TestBlancoInicio, para una string que comienza con un espacio en blanco.
  3. TestBlancoFin, para una string que finaliza con un espacio en blanco.
  4. TestUno, para una string de un solo carácter.
  5. TestTamaños, para una string de diferentes tamaños: de 4 caracteres, de 10
    caracteres y de 50 caracteres.
  6. TestMayus, para una string con todos sus caracteres en mayúsculas
  7. TestPali, que se integra como AFTER para comprobar que una vez generado el
    resultado se compruebe que efectivamente es palíndromo.

Ya lo tengo todo hecho, a excepción de lo del AFTER, que no tengo ni idea de lo que hay que hacer.

El código del la clase que crea el palíndromo es:

package Actividad3;

import java.util.Scanner;

public class Palindromo {

  public static String verPalindromo (String frase) {
		
  String reves = "";
  String resuelta = "";
  
  Scanner teclado = new Scanner(System.in);
 
  int tamaño = frase.length();
 
  for ( int i = tamaño - 1; i >= 0; i-- )
     reves = reves + frase.charAt(i);
  
  resuelta = frase + reves;
  
  teclado.close();
  
  return resuelta;
  }
}

y el del Junit es:

package Actividad3;

import static org.junit.Assert.*;

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

public class PalindromoTest {

@Before
public void antestest(){
	
}

@Test
public void testVacío(){
	String frase = "";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals(""));
}
@Test
public void testBlancoInicio(){
	String frase = " Vacaciones";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals(" VacacionessenoicacaV "));
}
@Test
public void testBlancoFin(){
	String frase = "Vacaciones ";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("Vacaciones  senoicacaV"));
}
@Test
public void testUno(){
	String frase = "V";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("VV"));
}
@Test
public void testTamañoscuatro(){
	String frase = "abcd";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("abcddcba"));
}
@Test
public void testTamañosdiez(){
	String frase = "abcdefghij";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("abcdefghijjihgfedcba"));
}
@Test
public void testTamañoscincuenta(){
	String frase = "abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6g";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6gg6f5e4d3c2b1a0987654321zyxwvutsrqpoñnmlkjihgfedcba"));
}
@Test
public void testMayus(){
	String frase = "VACACIONES";
	String palindromo=Palindromo.verPalindromo(frase);
	assertTrue(palindromo.equals("VACACIONESSENOICACAV"));
}

@After  
    public void testPali() { 
	
}
}

Se supone que si en los Tests estoy pasando las pruebas, es porque efectivamente es un palíndromo, así que no me entero muy bien de lo que he de poner en el After y como tendría que hacerlo.

ReloaD1010

#1 a. Desarrolla en Java una clase que crea un palíndromo a partir de una cadena dada. Por
ejemplo, si la entrada fuera “Vacaciones”, debería retornarse “VacacionessenoicacaV”

Ahi solo te esta diciendo que en ese caso deberia devolver lo que te dice.
Para el ejercicio te han dado los constructores ya hechos? Porque se me ocurre alguna solucion, pero sin poner parametros a los metodos no se me ocurre nada. Por ejemplo:

@After  
public boolean testPali(String frase) { boolean palindromo=true; for(int i=0; i<frase.length()/2;i++) { if(!frase.charAt(i).equals(frase.charAt(frase.length()-i))) { palindromo=false; break; } } return palindromo; }

para comprobar si es palindomo en el resto de metodos solo tendrias que cambiar el assert

assertTrue(testPali(palindromo));

Y ahora que estoy releyendo todo el codigo, creo que se puede plantear de otra manera. Si reusas el mismo metodo es mucho mas sencillo:

public class PalindromoTest {

    @Before
    public void antestest(){
            String testVacio = test("");
            String testBlancoInicio = test(" Vacaciones");
            String testBlancoFin = test("Vacaciones ");
            String testUno = test("V");
            String testTamanosCuatro = test("abcd");
            String testTamanosDiez = test("abcdefghij");
            String testTamanosCincuenta = test("abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6g");
            String testMayus = test("VACACIONES");
    }


    @Test
    public String test(String frase){
            String palindromo=Palindromo.verPalindromo(frase);
            assertTrue(testPali(palindromo));
    }

  @After  
    public boolean testPali(String frase) { 
            boolean palindromo=true;
            for(int i=0; i<frase.length()/2;i++)
           {
               if(frase.charAt(i)!=frase.charAt(frase.length()-i-1))
               {
                    palindromo=false;
                    break;
                }
            }
            return palindromo;
    }

Nunca he trabajado con JUnit asi que no se si el testPali es para usarse despues de haber acabado la ejecucion de los otros metodos, en ese caso imagino que habria que cambiarlo para que testeara todos los casos del tiron.

No se si es lo que necesitabas, pero espero haberte guiado un poco

1 respuesta
Turco

#2 Guiarme no se, pero hacerme ver las cosas de otra manera si, y se agradece. Al parecer hay errores en el Before (al declarar la String, debe ir todo entre comillas) y en el If del After, ya que no se puede utilizar .equals con charAt(i).

Para el ejercicio no me han dado nada, lo que pone es lo que es. Más o menos me he guiado por un ejercicio que hicimos con anterioridad en el que el ejercicio era crear una clase que buscar el mayor de todos los números dados, y luego crear una test para probar diferentes combinaciones.

Respecto a lo del After, salvo por el error del if, tiene buena pinta. Preguntaré en clase a ver si es así.

Gracias por la ayuda ^.

1 respuesta
ReloaD1010

#3 se me habia olvidado cambiar la salida de la funcion test, seguia como void
no pongas entre comillas todo lo del before, dejalo como lo he puesto, sino lo tomara como string tal cual esta y ninguna llamara al metodo test!
y lo del equals se me ha pasado, con los datos primitivos se pueden usar comparadores normales
he cambiado el codigo, echale un ojo ahora a ver que tal

Te explico lo que hace el for de testPali en cada iteracion, que antes se me ha pasado
Simplemente compara posiciones simetricas en la string: para "vacaciones", cuando i=0, comparara las posiciones 0 y 9 (longitud de la frase - 0 - 1 = 9), la siguiente iteracion compararan las posiciones 1 y 8 (10-1-1=8), despues 2 y 7 (10-2-1) y asi sucesivamente.
Esto se tiene que repetir hasta que se hayan comparado todos los caracteres, por lo que se ejecutara 10/2=5 veces en este caso.
Con la formulita que he usado, la ultima iteracion de las frases con numero impar sera inutil, pero asi es mas facil de ver.
Si en alguna de las comparaciones que hace resulta que los caracteres son distintos, cambiara el valor de una variable local previamente creada a falso.
Esa variable se inicializa como true, ya que si no hay ningun caso de que los caracteres sean distintos significa que sera palindromo

Si tienes alguna duda mas, pregunta ;)

1 respuesta
Turco

#4
Al final amoldé el código al ejemplo que tenía y se me quedó tal que así:

package Actividad3;

public class Palindromo {
	private String frase = "";
    
public Palindromo (String frase){ this.frase = frase; } public String verPalindromo() { String reves = ""; String resuelta = ""; int tamaño = frase.length(); for ( int i = tamaño - 1; i >= 0; i-- ) reves = reves + frase.charAt(i); resuelta = frase + reves; return resuelta; } }
package Actividad3;

import static org.junit.Assert.*;

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

public class PalindromoTestt {
	static Palindromo testVacio;
	static Palindromo testBlancoInicio;
	static Palindromo testBlancoFin;
	static Palindromo testUno;
	static Palindromo testTamañosCuatro;
	static Palindromo testTamañosDiez;
	static Palindromo testTamañosCincuenta;
	static Palindromo testMayus;

    @Before
    public void antestest(){
    	testVacio = new Palindromo ("");
    	testBlancoInicio = new Palindromo (" Vacaciones");
    	testBlancoFin = new Palindromo ("Vacaciones ");
    	testUno = new Palindromo ("V");
    	testTamañosCuatro = new Palindromo ("abcd");
    	testTamañosDiez = new Palindromo ("abcdefghij");
    	testTamañosCincuenta = new Palindromo ("abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6g");
    	testMayus = new Palindromo ("VACACIONES");	
    }


    @Test
    public void testVacio(){
    	 String palindromo=testVacio.verPalindromo();
         assertTrue(palindromo.equals(""));
    }
    @Test
	public void testBlancoInicio(){
		String palindromo=testBlancoInicio.verPalindromo();
		assertTrue(palindromo.equals(" VacacionessenoicacaV "));
	}
	@Test
	public void testBlancoFin(){
		String palindromo=testBlancoFin.verPalindromo();
		assertTrue(palindromo.equals("Vacaciones  senoicacaV"));
	}
	@Test
	public void testUno(){
		String palindromo=testUno.verPalindromo();
		assertTrue(palindromo.equals("VV"));
	}
	@Test
	public void testTamañosCuatro(){
		String palindromo=testTamañosCuatro.verPalindromo();
		assertTrue(palindromo.equals("abcddcba"));
	}
	@Test
	public void testTamañosDiez(){
		String palindromo=testTamañosDiez.verPalindromo();
		assertTrue(palindromo.equals(palindromo));
	}
	@Test
	public void testTamañosCincuenta(){
		String palindromo=testTamañosCincuenta.verPalindromo();
		assertTrue(palindromo.equals("abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6gg6f5e4d3c2b1a0987654321zyxwvutsrqpoñnmlkjihgfedcba"));
	}
	@Test
	public void testMayus(){
		String palindromo=testMayus.verPalindromo();
		assertTrue(palindromo.equals("VACACIONESSENOICACAV"));
	}
	
	@After
	public void testPali(){
		
	}
}

El caso es que no puedo implementar el @After que hiciste porque el @After debe ser void y sin parámetros.

Estoy casi seguro que lo que hay que hacer es lo que tú hiciste:

assertTrue(testPali(palindromo));

pero claro... como hacer eso sin meterle parámetros al @After y sin que de un return.

Tenía clase hoy, pero no pude ir, mañana tengo otras dos horas e intentaré resolver la duda, pero ahí queda xD.

1 respuesta
ReloaD1010

#5 como estas trabajando unicamente con Strings no hace falta crear objectos de la clase palindromo, esta clase puede usarse para tratar las Strings y ya (como lo tenias antes, vamos). Y no es necesario que sea static
He mirado un poco por encima el orden de ejecucion de JUnit y funciona asi:

@before
@test1()
@after

@before
@test2()
@after

En "teoria" el @before es una preparacion generica de los test, y el @after es para quitar las cosas innecesarias despues de hacer el test (esto es lo que me ha parecido entender), pero en el enunciado pone que el test tiene que estar en el @after
Asi que con crear una String a testear para la clase y un metodo que chequee si es palindromo creo que va a ser suficiente:

package Actividad3;

import static org.junit.Assert.*;

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

public class PalindromoTestt {

     private String frase;


    @Before
    public void antestest(){
             frase="";
    }


    @Test
    public void testVacio(){
             frase=Palindromo.verPalindromo("");
    }
    @Test
    public void testBlancoInicio(){
            frase=Palindromo.verPalindromo(" Vacaciones");
    }
    @Test
    public void testBlancoFin(){
            frase=Palindromo.verPalindromo("Vacaciones ");
    }
    @Test
    public void testUno(){
            frase=Palindromo.verPalindromo("V");
    }
    @Test
    public void testTamañosCuatro(){
            frase=Palindromo.verPalindromo("abcd");
    }
    @Test
    public void testTamañosDiez(){
           frase=Palindromo.verPalindromo("abcdefghij");
    }
    @Test
    public void testTamañosCincuenta(){
            frase=Palindromo.verPalindromo("abcdefghijklmnñopqrstuvwxyz1234567890a1b2c3d4e5f6g");
    }
    @Test
    public void testMayus(){
            frase=Palindromo.verPalindromo("VACACIONES");
    }
    
    @After
    public void testPali(){
            assertTrue(esPali());
    }

    public boolean esPali() { 
            boolean palindromo=true;
            for(int i=0; i<frase.length()/2;i++)
           {
               if(frase.charAt(i)!=frase.charAt(frase.length()-i-1))
               {
                    palindromo=false;
                    break;
                }
            }
            return palindromo;
    }
}

ya que estoy, te simplifico un poco el otro algoritmo

package Actividad3;

public class Palindromo {

  public String verPalindromo (String frase) {
                
for ( int i = frase.length() - 2; i >= 0; i-- ) frase += frase.charAt(i); return frase; } }

y como detalle: puedes hacer 2 palindromos distintos inicializando el indice del for a length()-1 ( "hola" pasaria a "holaaloh" ) o a length()-2 ( "hola" pasaria a "holaloh" ). Usa el que quieras, ambos son validos

Ya diras si esta es la estructura que buscan, que anda que menudas especificaciones mas escasas en el enunciado :mad:

1 respuesta
Turco

#6 Muchas gracias por la ayuda. Ya está todo resuelto y más o menos entendido.

Lo que comentaste sobre lo de que no era necesario crear objetos, simplemente fue porque lo volví a hacer fijándome en otro ejercicio que lo hacía así, ya que aún no entiendo mucho de objetos, de hecho, ayer empezamos con ellos en la asignatura de programación ^. Entre otras cosas, me he visto en un berenjenal con el public, static, private, etc porque son cosas que aún no hemos visto, al igual que con el this.

De nuevo, muchas gracias por todo.

Usuarios habituales

  • Turco
  • ReloaD1010