EARS: cinco patrones para escribir requisitos

Enterate del próximo post
Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.

Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.
El post anterior dejó una prueba para decidir si un requisito se puede comprobar, pero ninguna receta para escribir la frase de modo que salga así cada vez. Este post presenta cinco plantillas que resuelven una parte de ese problema: el orden en que se dice cada cosa.
Un requisito en prosa libre admite muchas formas de decir lo mismo, y esa libertad tiene un costo. Cada autor ordena la frase a su manera, y quien la lee tiene que reconstruir cuál es la situación en la que aplica, cuál es el hecho que la dispara y qué debe hacer el sistema. EARS, sigla de Easy Approach to Requirements Syntax, fija ese orden de antemano. La propuso Alistair Mavin junto con colegas de Rolls-Royce a partir de analizar normativa aeronáutica, un terreno donde una frase ambigua se paga caro.
La plantilla original está en inglés, y es la forma que aparece en la documentación de las herramientas que adoptan EARS, como Kiro. Esta es la única vez que la serie la muestra:
When <trigger>, the system shall <response>.Es la plantilla del patrón de evento. Los otros cuatro cambian la palabra inicial o la omiten. De acá en adelante todo se escribe en español, con deberá en el lugar de shall.
| Patrón | Forma en español | Se usa cuando |
|---|---|---|
| Ubicuo | El sistema deberá <respuesta>. | La respuesta vale siempre, sin condición |
| De estado | Mientras <precondición>, el sistema deberá <respuesta>. | La respuesta vale durante todo un estado |
| De evento | Cuando <disparador>, el sistema deberá <respuesta>. | La respuesta ocurre cuando pasa algo puntual |
| De opción | Donde <la funcionalidad esté incluida>, el sistema deberá <respuesta>. | La respuesta existe solo si una funcionalidad opcional está presente |
| No deseado | Si <disparador>, entonces el sistema deberá <respuesta>. | Algo indeseado puede ocurrir y hay que decir qué se hace |
La palabra inicial cumple dos funciones. Dice de qué tipo de requisito se trata y deja siempre el cuándo antes del qué: quien lee empieza por la situación y llega a la respuesta sin tener que buscarla. Los patrones también se combinan cuando hace falta, en ese mismo orden: una precondición, después un disparador, después la respuesta.
Dos ejemplos ayudan a ver los patrones que la spec de guardar no usa. Son ilustraciones de otras funcionalidades de la Bitácora, no parte de ninguna spec escrita hasta ahora. De estado: Mientras un artículo esté marcado como leído, el sistema deberá excluirlo del resumen semanal. De opción: Donde el resumen semanal esté activado, el sistema deberá incluir en él los artículos guardados en los últimos siete días.
Hay una razón práctica por la que esta forma le sirve a un agente, y también a quien revisa: cada patrón se corresponde casi uno a uno con un caso de prueba. La precondición o el disparador arman la situación, la respuesta es lo que se comprueba. Con una frase libre, ese armado hay que adivinarlo.
Los cuatro requisitos de guardar-articulo.md son hoy cuatro viñetas en prosa. Cada una admite un patrón, y elegir cuál es el ejercicio de este post.
El primero, guardar un artículo a partir de su URL, ocurre cuando alguien lo pide: es un patrón de evento. El segundo, avisar que la URL ya existe, es una situación que puede darse y que conviene tratar de forma explícita: es el patrón de comportamiento no deseado. El tercero, guardar el título y la fecha junto con la URL, no depende de ninguna condición: es ubicuo. El cuarto es el que el post anterior agregó, y ya tenía la forma de condición más respuesta: es de evento, con la condición de los dos segundos dentro del disparador. La spec cubre así tres de los cinco patrones, y los otros dos quedan para funcionalidades que todavía no tienen su documento.
Con la reescritura, los requisitos pasan a llevar número, de R1 a R4. Hasta acá las viñetas iban sin numerar. La numeración importa a partir de ahora porque el próximo tema, los criterios de aceptación, necesita poder decir a qué requisito responde cada uno.
La spec con los cuatro requisitos reescritos. Solo cambia ## Requisitos; el resto del documento queda igual que en el post anterior.
# Guardar un artículo
## Contexto y objetivo
Quien usa la Bitácora encuentra artículos que quiere leer más tarde y no
tiene tiempo de leer en el momento. Necesita guardarlos sin perder el
título ni la referencia de dónde los encontró, y sin terminar con el
mismo artículo guardado dos veces por error.
## Alcance
Dentro: guardar un artículo a partir de su URL.
Fuera: etiquetar artículos, marcarlos como leídos, borrarlos, ver la
lista de artículos guardados y armar el resumen semanal. Cada una es
una funcionalidad distinta, con su propia especificación.
## Requisitos
- R1. Cuando se pide guardar una URL que no estaba guardada, el sistema
deberá guardar un artículo a partir de ella.
- R2. Si se pide guardar una URL que ya fue guardada antes, entonces el
sistema deberá avisar que ya existe, sin guardar un artículo nuevo.
- R3. El sistema deberá guardar, con cada artículo, además de la URL, el
título de la página y la fecha en la que se guardó.
- R4. Cuando se pide guardar una URL y la página responde en menos de 2
segundos, el sistema deberá entregar el resultado (artículo guardado o
aviso de que ya existe) en menos de 3 segundos desde que se pide.
## Criterios de aceptación
Vacía a propósito: se completa cuando la serie llegue a este tema.
## Supuestos
- Quien guarda es una única persona por instalación: no hay cuentas ni
artículos de otras personas.
- La URL apunta a una página pública, que se abre sin iniciar sesión.
## Preguntas abiertas
- ¿Dos URL que difieren solo en mayúsculas o en una barra final cuentan
como la misma?
- ¿Qué se guarda como título si la página no responde o no tiene título?
## Contrato
Precondición
La URL que llega es un texto no vacío.
Poscondición
Si la URL no estaba guardada antes de esta llamada, existe un artículo
nuevo con esa URL, su título y la fecha de guardado.
Si la URL ya estaba guardada, no se crea ningún artículo nuevo y el
sistema avisa que ya existe.La decisión menos obvia está en R1. Reescrito con el patrón de evento y sin más, habría quedado como "Cuando se pide guardar una URL, el sistema deberá guardar un artículo", y esa frase contradice a R2: dice que siempre se guarda, y R2 dice que a veces no. En prosa las dos viñetas se leían bien juntas porque quien lee completa la excepción sin darse cuenta. El patrón no lo permite, porque un disparador tiene que decir exactamente cuándo aplica. Por eso R1 quedó acotado a la URL que no estaba guardada, y R1 y R2 pasaron a cubrir, entre las dos, todos los casos posibles de un pedido.
R3 dejó otra marca. Como requisito ubicuo dice que el título se guarda siempre, y eso pone en evidencia la segunda pregunta abierta: qué pasa con un artículo cuya página no tiene título. La pregunta sigue sin responderse, a propósito, pero ahora se ve con más claridad de qué requisito depende.
Con las cuatro viñetas en prosa, un agente que implementa la spec tiene que decidir en silencio varias cosas que el texto no dice. La primera viñeta afirma que un artículo se guarda a partir de su URL y la segunda dice que una URL repetida no se guarda de nuevo. Ninguna indica si la comprobación de duplicados va antes o después de guardar, ni cuál de las dos frases manda cuando parecen chocar. Las dos lecturas son compatibles con el texto y producen sistemas que se comportan distinto.
Lo mismo ocurre al derivar pruebas. Para la viñeta sobre el título y la fecha, quien escribe los casos de prueba tiene que preguntarse en qué momento se guardan: en cada pedido, solo cuando el artículo es nuevo, también cuando se avisa que ya existe. Con la forma EARS, la palabra inicial ya contestó: El sistema deberá sin condición equivale a un caso de prueba que se cumple en cualquier situación.
EARS tiene límites que conviene tener presentes. Es una sintaxis y no un control de calidad: Cuando se pide guardar una URL, el sistema deberá responder rápido respeta el patrón de evento por completo y sigue sin pasar la prueba del post anterior. La forma también puede producir frases rígidas, y hay requisitos que no tienen un disparador natural, como los de cualidad general, que el patrón obliga a torcer. Nació para dominios donde la ambigüedad cuesta mucho, y en un proyecto chico la ganancia real es una sola: que el cuándo quede siempre antes del qué. Si esa ganancia no se necesita, la plantilla es formalidad.
Un requisito escrito con una plantilla fija dice cuándo aplica antes de decir qué hace el sistema. Elegir el patrón obliga a decidir de qué tipo de requisito se trata, y ahí aparecen las contradicciones y las condiciones que la prosa dejaba implícitas.
El patrón ordena la frase, pero la spec todavía no dice cómo se comprueba que el sistema hace lo que cada requisito pide. El próximo post trata los criterios de aceptación, la sección que sigue vacía en el documento.