Ir al contenido
wannacode

Códigos promocionales: de la solicitud al lanzamiento

En resumen: Una solicitud, «quiero códigos promocionales para el otoño», pasa por todo el curso. Las preguntas encuentran la necesidad y a las personas a las que nadie pregunta. La historia se divide por sus reglas, el plazo de vigencia pasa por Example Mapping. Las reglas del código se convierten en escenarios contra un sistema con errores, y como el cambio toca el total, también se protege el envío de la regresión. El error atrapado se convierte en un informe, dos escenarios se convierten en código, y la matriz dice qué se toca cuando cambia el requisito.

Problema

La solicitud

El dueño de la tienda escribe un lunes por la mañana:

«Quiero códigos promocionales para el otoño. 10 % de descuento, hasta finales de noviembre. Lanzamos en dos semanas».

Tres frases. Contienen al menos cinco reglas que nadie ha enunciado todavía, un tema abierto con dinero de por medio, y una persona que se enterará del cambio solo cuando no pueda hacer su trabajo. En este proyecto recorres todo el camino: de las tres frases al cambio lanzado y comprobado.

La idea

El camino

Cada paso viene de un módulo del curso:

  1. las preguntas: la necesidad detrás de la solicitud y las personas a las que hay que preguntar;
  2. la historia y la división: la solicitud es grande; se corta por sus reglas;
  3. Example Mapping: las reglas, los ejemplos y las preguntas sobre el plazo de vigencia del código;
  4. los escenarios y las pruebas: las reglas del código se convierten en escenarios; el cambio toca además el total, y el envío depende de él, así que se protege de la regresión;
  5. el informe: el error que trajo el cambio, descrito para que se corrija a la primera;
  6. la automatización: dos escenarios del código promocional se convierten en código en los cuatro lenguajes;
  7. la matriz y el cambio: qué cubren las pruebas y qué se toca cuando cambia el requisito.
Más precisamente, para curiosos

En el navegador, los escenarios se ejecutan contra un sistema con errores. Para el código promocional conoce tres de las reglas: el 10 %, los productos en oferta y qué descuento vale con la fidelidad. El plazo de vigencia y «El código ya se usó» no están en él: están en el mapa, en la matriz y en la automatización, donde los escenarios se ejecutan con las herramientas reales. La regresión, la tabla y el informe son sobre el envío: el cambio del código altera el total del que depende el envío, y el envío tiene que seguir siendo correcto.

Pruébalo

Las preguntas

1. ¿Cuál es la primera pregunta al dueño?
2. ¿A quién más tienes que preguntar, además del dueño?
3. ¿El umbral del envío gratis se cuenta antes del descuento o después? El dueño dice: «No lo he pensado».
4. ¿Qué pregunta es tendenciosa?

La idea

Las respuestas

Después de hablar con el dueño, marketing y contabilidad, la solicitud queda así:

  • la necesidad: más clientes nuevos en otoño. Métrica: primeros pedidos de clientes nuevos al mes, comparados con el otoño pasado; se mide a finales de noviembre;
  • las reglas: el código da un 10 % de descuento; no vale en productos en oferta; se usa en un pedido pagado («El código ya se usó»); vale hasta su último día inclusive («El código ha caducado»); no se suma con la fidelidad, vale el mayor;
  • contabilidad: quiere ver qué código dio cada descuento;
  • pregunta abierta: si el umbral de 50 € del envío gratis se cuenta antes del descuento o después. Lo decide el dueño; hasta entonces no lo decide nadie más.

Cinco reglas en una historia son muchas. El siguiente paso es la división.

Ejercicio

La historia y el mapa

1. La división. La historia con todas las reglas del código es demasiado grande para una iteración.

Elige el patrón por el que se corta la historia, luego construye la división en el orden en que se hace.

Historia

Como cliente quiero introducir un código promocional y obtener un descuento, para comprar más barato.

Paso 1: ¿Con qué patrón se divide?

2. El plazo de vigencia. El primer trozo después del 10 % es el plazo de vigencia. Los tres amigos (three amigos) se sentaron con las tarjetas.

Pon cada tarjeta en su lugar, luego decide qué es la historia.

Historia

Como cliente quiero saber hasta cuándo vale el código, para usarlo a tiempo.

En cada tarjeta pulsa «Poner como…» y elige: regla (se convierte en columna), ejemplo de una regla o pregunta. Las flechas cambian de opción, Esc cierra. También se puede con el ratón: arrastra la tarjeta a su sitio.

Reglas

Todavía no hay reglas. Pon una tarjeta como regla y se convierte en columna.

Preguntas

  • Todavía no hay preguntas.

Tarjetas sin colocar

  • Un código caducado se rechaza con «El código ha caducado», y el total queda sin descuento

  • Pedido el 30 de noviembre con OTONO10: una camiseta de 20,00 € cuesta 18,00 €

  • El código se introdujo el 30 de noviembre a las 23:50, y el pedido se pagó el 1 de diciembre a las 00:10. ¿Vale?

  • ¿El último día termina a medianoche según el reloj de quién: el de la tienda o el del cliente?

  • El código vale hasta su último día inclusive

  • Pedido el 1 de diciembre con OTONO10: «El código ha caducado», la camiseta sigue en 20,00 €

  • OTONO10 vale hasta el 30 de noviembre. Pedido el 15 de noviembre: una camiseta de 20,00 € cuesta 18,00 €

Ejercicio

Los escenarios del código

Tres de las reglas de la división se ejecutan aquí mismo: el 10 %, los productos en oferta y el cliente fiel con código. Un escenario por ejemplo, en el lenguaje del dueño.

Escribe los escenarios del código promocional de modo que se atrapen los seis errores en torno a los descuentos.

GherkinDescuentos

La idea

El cambio toca el envío

El código promocional cambia el total del carrito. El envío depende del total: gratis desde 50,00 € inclusive, si no 4,90 €. El programador del código tocará justo el cálculo del total.

Decida lo que decida el dueño sobre el umbral antes o después del descuento, la regla del envío a partir del total tiene que seguir siendo correcta. Por eso, antes del cambio, el envío se protege de la regresión: escenarios para los ejemplos acordados y pruebas para los casos técnicos, que fallan si algo se rompe en torno al límite.

Ejercicio

La regresión del envío

1. Los escenarios. Pocos escenarios, uno por cada ejemplo acordado.

Escribe los escenarios del envío de modo que atrapen los cinco errores en torno al límite y el carrito vacío.

GherkinEnvío gratis

2. Los casos técnicos. La tabla es para la prueba del nivel de componente: los casos que el negocio no quiere leer.

Escribe los casos que atrapan los seis errores, incluido el resto de la tarifa vieja para los pedidos grandes.

La regla: El envío es gratis en un pedido desde 50 € (incluidos), si no, cuesta 4,90 €. Un carrito vacío no se puede pedir.

EntradaEsperadoEl sistema correcto
#Total del carritoRechazadoEnvío

Una celda de resultado vacía no se comprueba. Los importes se escriben como 49,99.

Ejercicio

El error atrapado

1. El informe. El programador del código promocional calcula el total con números fraccionarios y lo redondea a euros enteros. El escenario de 49,99 € falla.

Encuentra un total donde se vea el error, y escribe el informe.

El error que has atrapado: Envío gratis

con importes con céntimos justo por debajo de 50 €

La regla: El envío es gratis en un pedido desde 50 € (incluidos), si no, cuesta 4,90 €. Un carrito vacío no se puede pedir.

Pasos para reproducirlo

  1. Todavía no hay pasos. Añádelos desde el vocabulario de abajo.

Los pasos vienen del vocabulario de la funcionalidad, como en los escenarios. Los valores se escriben en el propio paso: el importe como 50,00.

Esperado (qué tiene que pasar según la regla)
Obtenido (qué pasa en el sistema con el error)
Gravedad (cuánto daño hace el defecto)
Prioridad (con qué urgencia hay que corregirlo)

La idea

Automatizar dos escenarios

Los dos escenarios del código promocional que el dueño leyó y aceptó:

promo.feature
# language: es
Característica: Código promocional
Un código promocional da un 10 % de descuento hasta su último día inclusive.
Escenario: El código da un 10 %
Dado un carrito de 20,00 €
Cuando aplico el código OTONO10
Entonces el total es de 18,00 €
Escenario: Un código caducado
Dado un carrito de 20,00 €
Y el código OTONO10 ha caducado
Cuando aplico el código OTONO10
Entonces veo que el código ha caducado
Y el total es de 20,00 €

La clase que aplica el código. El total está en céntimos, y el día es una entrada, no «hoy»: esta es la respuesta a la pregunta de la medianoche del mapa y a la lección sobre las pruebas en CI:

src/main/java/shop/PromoCode.java
package shop;
import java.time.LocalDate;
public class PromoCode {
private final String code;
private final LocalDate lastDay;
public PromoCode(String code, LocalDate lastDay) {
this.code = code;
this.lastDay = lastDay;
}
// 10 % del total en céntimos. Un código caducado se rechaza.
public int apply(int total, LocalDate day) {
if (day.isAfter(lastDay)) {
throw new IllegalArgumentException("El código ha caducado");
}
return total - total / 10;
}
}

El paso «Cuando» aplica el código, y el paso «Entonces» comprueba el mensaje:

src/test/java/shop/PromoSteps.java
@When("aplico el código {word}")
public void apply(String code) {
try {
total = new PromoCode(code, LAST_DAY).apply(total, today);
} catch (IllegalArgumentException e) {
refusal = e.getMessage();
}
}
src/test/java/shop/PromoSteps.java
@Then("veo que el código ha caducado")
public void toldExpired() {
assertEquals("El código ha caducado", refusal);
}

El archivo de pasos entero, ejecutado con la herramienta real. Los dos escenarios pasan:

src/test/java/shop/PromoSteps.java
package shop;
import io.cucumber.java.ParameterType;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import java.time.LocalDate;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PromoSteps {
// El último día del código en los escenarios.
private static final LocalDate LAST_DAY = LocalDate.of(2026, 11, 30);
private int total;
private LocalDate today = LocalDate.of(2026, 11, 15);
private String refusal;
@ParameterType(name = "importe", value = "\\d+,\\d{2}")
public int amount(String text) {
return Integer.parseInt(text.replace(",", ""));
}
@Given("un carrito de {importe} €")
public void cart(int cents) {
total = cents;
}
@Given("el código {word} ha caducado")
public void expired(String code) {
today = LAST_DAY.plusDays(1);
}
@When("aplico el código {word}")
public void apply(String code) {
try {
total = new PromoCode(code, LAST_DAY).apply(total, today);
} catch (IllegalArgumentException e) {
refusal = e.getMessage();
}
}
@Then("el total es de {importe} €")
public void totalIs(int cents) {
assertEquals(cents, total);
}
@Then("veo que el código ha caducado")
public void toldExpired() {
assertEquals("El código ha caducado", refusal);
}
}
Salida
OK El código da un 10 %
OK Un código caducado
Escenarios: 2, pasan: 2, fallan: 0

Y si el programador olvida el plazo de vigencia, el código caducado sigue dando un 10 % de descuento, y el escenario «Un código caducado» falla:

src/main/java/shop/PromoCode.java
package shop;
import java.time.LocalDate;
public class PromoCode {
private final String code;
private final LocalDate lastDay;
public PromoCode(String code, LocalDate lastDay) {
this.code = code;
this.lastDay = lastDay;
}
// 10 % del total en céntimos. Un código caducado se rechaza.
public int apply(int total, LocalDate day) {
return total - total / 10;
}
}
Salida
FALLA Un código caducado: expected: <El código ha caducado> but was: <null>
OK El código da un 10 %
Escenarios: 2, pasan: 1, fallan: 1
Más precisamente, para curiosos

Estos escenarios no están en el vocabulario del motor del curso, así que no se comprueban en el navegador contra un sistema con un error. Se ejecutan con Cucumber-JVM, Reqnroll, behave y cucumber-js, como en el módulo «Automatización», y su salida está verificada. El descuento se redondea hacia abajo a un céntimo entero (total / 10 con enteros); para totales como 20,00 € no hace diferencia, pero es una decisión que contabilidad tiene que confirmar.

Ejercicio

La matriz y el cambio

1. Cobertura e impacto. El otoño ha terminado. La métrica mostró que la mayoría de los códigos los usaron clientes que ya existían, y el dueño cambia la regla: el código vale solo para el primer pedido del cliente.

Marca los vínculos. Luego, en el segundo paso, elige qué pruebas hay que revisar por el cambio.

Tests

  • P-1: Cliente nuevo, una camiseta de 20,00 € con OTONO10: 18,00 €.
  • P-2: Cliente nuevo, unos jeans en oferta de 40,00 € con OTONO10: 40,00 €.
  • P-3: Cliente nuevo, una camiseta de 20,00 € y unos jeans en oferta de 40,00 € con OTONO10: 58,00 €.
  • P-4: El cliente ya pagó un pedido con OTONO10. En un pedido nuevo introduce OTONO10: «El código ya se usó».
  • P-5: Un cliente nuevo introduce OTONO10 el 1 de diciembre, después del último día: «El código ha caducado».
  • P-6: Cliente fiel con OTONO10, una camiseta de 20,00 €: 18,00 €, no 17,00 €.
  • P-7: Un cliente nuevo introduce OTONO10 el 30 de noviembre, el último día: una camiseta de 20,00 € cuesta 18,00 €.

Pulsa la celda donde el test comprueba el requisito; otra vez para quitar la relación. Las flechas se mueven entre las celdas, Espacio o Enter marca.

RequisitosP-1: Cliente nuevo, una camiseta de 20,00 € con OTONO10: 18,00 €.P-2: Cliente nuevo, unos jeans en oferta de 40,00 € con OTONO10: 40,00 €.P-3: Cliente nuevo, una camiseta de 20,00 € y unos jeans en oferta de 40,00 € con OTONO10: 58,00 €.P-4: El cliente ya pagó un pedido con OTONO10. En un pedido nuevo introduce OTONO10: «El código ya se usó».P-5: Un cliente nuevo introduce OTONO10 el 1 de diciembre, después del último día: «El código ha caducado».P-6: Cliente fiel con OTONO10, una camiseta de 20,00 €: 18,00 €, no 17,00 €.P-7: Un cliente nuevo introduce OTONO10 el 30 de noviembre, el último día: una camiseta de 20,00 € cuesta 18,00 €.Cubierto por
R-1 Un código promocional da un 10 % de descuento.0
R-2 Un código promocional no vale para productos en oferta.0
R-3 Un código se usa en un pedido pagado. Un segundo intento: «El código ya se usó».0
R-4 Un código vale hasta su último día inclusive. Después: «El código ha caducado».0
R-5 Los descuentos no se suman: vale el mayor.0
R-6 En el pedido se ve con qué código se dio el descuento.0
Comprueba0000000

Test

Ponte a prueba

1. La solicitud es sobre el código promocional. ¿Por qué el proyecto tiene también escenarios y pruebas para el envío?
2. ¿Qué hace útil la matriz de este proyecto cuando cambia el requisito?
3. ¿Cuál de estas es «hecho» para los códigos promocionales?
4. La pregunta «según la hora de quién termina el último día» del mapa resultó importar también en el código. ¿Dónde?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·