Las pruebas unitarias son programas que comprueban que tu código hace lo que debe, y que avisan en cuanto algo se rompe. En Java el estándar es JUnit, que llegó a la versión 6 en 2025. Aquí probamos una función que calcula el IVA, con pruebas normales, parametrizadas y de excepciones, y las ejecutamos desde la terminal, sin Maven ni Gradle.
También te puede interesar
El código que vamos a probar
package mx.ejemplo;
public class Iva {
public static final double TASA = 0.16;
public static long totalEnCentavos(long subtotalCentavos) {
if (subtotalCentavos < 0) throw new IllegalArgumentException("subtotal negativo");
return Math.round(subtotalCentavos * (1 + TASA));
}
}Trabajar con centavos en un long evita los errores de redondeo de double con el dinero (lo explicamos en dinero con BigDecimal).
Las pruebas
package mx.ejemplo;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.*;
class IvaTest {
@Test
@DisplayName("100 pesos con IVA son 116")
void cienPesos() {
assertEquals(11_600, Iva.totalEnCentavos(10_000));
}
@ParameterizedTest(name = "{0} centavos -> {1}")
@CsvSource({"0, 0", "1, 1", "99, 115", "125000, 145000"})
void variosSubtotales(long subtotal, long esperado) {
assertEquals(esperado, Iva.totalEnCentavos(subtotal));
}
@Test
void rechazaNegativos() {
var e = assertThrows(IllegalArgumentException.class, () -> Iva.totalEnCentavos(-1));
assertEquals("subtotal negativo", e.getMessage());
}
}@Testmarca cada método de prueba. No tiene que ser público ni devolver nada.assertEquals(esperado, real)falla si no coinciden. El orden importa para que el mensaje de error se entienda.@ParameterizedTestcon@CsvSourceejecuta la misma prueba con varios datos: cuatro casos en una sola función, incluido el redondeo (99 centavos con IVA son 114.84, que se redondean a 115).assertThrowscomprueba que se lanza la excepción esperada, y devuelve la excepción para revisar su mensaje.
Compilar y ejecutar desde la terminal
cd junit JUNIT=../lib/junit-platform-console-standalone-6.1.3.jar javac -d out -cp $JUNIT src/mx/ejemplo/Iva.java test/mx/ejemplo/IvaTest.java java -jar $JUNIT execute --class-path out --scan-class-path --disable-banner --disable-ansi-colors --details=tree
salida╷ ├─ JUnit Platform Suite ✔ ├─ JUnit Jupiter ✔ │ └─ IvaTest ✔ │ ├─ 100 pesos con IVA son 116 ✔ │ ├─ rechazaNegativos() ✔ │ └─ variosSubtotales(long, long) ✔ │ ├─ "0" centavos -> "0" ✔ │ ├─ "1" centavos -> "1" ✔ │ ├─ "99" centavos -> "115" ✔ │ └─ "125000" centavos -> "145000" ✔ └─ JUnit Vintage ✔ Test run finished after 129 ms
El archivo junit-platform-console-standalone trae todo JUnit en un solo .jar: se descarga de Maven Central. En un proyecto real las pruebas las ejecuta Maven (mvn test) o Gradle (gradle test), que además bajan JUnit solos; las pruebas se escriben exactamente igual.
Cuando una prueba falla
Si alguien cambia la tasa a 0.15 por error, la primera prueba falla con un mensaje que dice exactamente qué esperaba y qué obtuvo, por ejemplo expected: <11600> but was: <11500>, y el resumen termina en rojo. Para eso sirven: el error aparece en tu computadora, no en la factura de un cliente.
Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.