Evidencia base: Issue #16 – “Testing Bugs”
Se registran los hallazgos de testing (Ver: https://github.com/HanstoC/GRUPO10-2025-PROYINF/issues/16)
Alcance
- Endpoints seleccionados (2):
POST /preguntas
POST /ensayos/{id}/responder
Endpoint A - /preguntas
POST /preguntas — Caso 1: Creación válida (autenticado)
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}{{PREGUNTAS_PATH}} (ej. http://localhost:8000/preguntas) |
| Headers |
Content-Type: application/json + cookies de sesión (autenticado) |
| Body (JSON) |
Payload completo (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Válido |
| Criterios |
Payload completo; Campos obligatorios presentes; ≥2 alternativas; Exactamente 1 alternativa marcada como correcta |
| Valores frontera considerados |
Número mínimo de alternativas (2) vs. este caso con 4; longitud de texto dentro de rango normal |
| Salida esperada — Código HTTP |
200 o 201 |
| Salida esperada — Body |
JSON confirmando creación con id_pregunta y datos de la pregunta |
| Salida esperada — Efecto |
Registro persistente en BD; se devuelve id_pregunta; pregunta creada coincide con el payload |
| Contexto de ejecución |
Sesión autenticada con credenciales de profesor; id_asignatura y id_profesor válidos; servidor activo |
POST /preguntas — Caso 2: Validación — enunciado vacío
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}{{PREGUNTAS_PATH}} |
| Headers |
Content-Type: application/json + cookies de sesión (autenticado) |
| Body (JSON) |
Payload incompleto (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Inválido |
| Criterios |
Campo obligatorio enunciado vacío |
| Valores frontera considerados |
enunciado = "" (mínimo absoluto), borde cercano: 1 carácter |
| Salida esperada — Código HTTP |
400 o 422 |
| Salida esperada — Body |
JSON con mensaje de error indicando campos que fallaron |
| Salida esperada — Efecto |
No se crea registro en BD |
| Contexto de ejecución |
Sesión autenticada; servidor activo; API valida presencia/longitud de enunciado |
POST /preguntas — Caso 3: Intento de creación sin autenticación
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}{{PREGUNTAS_PATH}} |
| Headers |
Content-Type: application/json (sin cookie/token) |
| Body (JSON) |
Payload completo (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Inválido |
| Criterios |
Usuario no autenticado |
| Valores frontera considerados |
Sesión inexistente vs. sesión caducada / token inválido |
| Salida esperada — Código HTTP |
401 o 403 |
| Salida esperada — Body |
Mensaje JSON/texto indicando falta de autenticación |
| Salida esperada — Efecto |
No se crea pregunta; no se generan cookies/tokens nuevos |
| Contexto de ejecución |
Petición con requests.Session() sin login previo o token/cookie inválido; servidor activo con autenticación |
Los Payloads utilizados en las pruebas fueron los siguientes:
Payload completo(válido)
{
"id_asignatura": 4,
"id_profesor": 1,
"topico": "Geografía",
"pregunta": "¿Cuál es la capital de Francia?2",
"imagen": null,
"respuestas": [
{"texto": "París", "es_correcta": true},
{"texto": "Londres", "es_correcta": false},
{"texto": "Berlín", "es_correcta": false},
{"texto": "Berlín", "es_correcta": false}
]
}
Payload incompleto(no válido)
{
"id_asignatura": 4,
"topico": "X",
"pregunta": ""
}
Endpoint /ensayos/{id}/responder
POST /ensayos/{id}/responder — Caso 1: Envío válido (alumno autenticado)
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}/ensayos/{id}/responder |
| Headers |
Content-Type: application/json + cookies de sesión (alumno autenticado) |
| Body (JSON) |
Payload completo (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Válido |
| Criterios |
Alumno autenticado; payload completo; todas las preguntas respondidas |
| Valores frontera considerados |
Ensayo con 1 pregunta vs. ensayo con varias preguntas |
| Salida esperada — Código HTTP |
200 o 201 |
| Salida esperada — Body |
JSON confirmando envío, incluyendo puntaje, correctas, erroneas, omitidas |
| Salida esperada — Efecto |
Registro de respuestas en BD; actualización del estado del ensayo |
| Contexto de ejecución |
Sesión de alumno activa; id_ensayo válido; servidor activo |
POST /ensayos/{id}/responder — Caso 2: Formato de respuestas inválido (alumno autenticado)
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}/ensayos/{id}/responder |
| Headers |
Content-Type: application/json + cookies de sesión (alumno) |
| Body (JSON) |
Payload incompleto (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Inválido |
| Criterios |
Formato de respuestas incorrecto (no es lista) |
| Valores frontera considerados |
Respuestas enviadas como string, null u otro tipo no lista |
| Salida esperada — Código HTTP |
400 o 422 |
| Salida esperada — Body |
JSON con mensaje de validación indicando error de formato |
| Salida esperada — Efecto |
No se registra ninguna respuesta en BD |
| Contexto de ejecución |
Alumno autenticado; servidor activo; validación de formato implementada |
POST /ensayos/{id}/responder — Caso 3: Envío válido sin autenticación
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}/ensayos/{id}/responder |
| Headers |
Content-Type: application/json (sin cookies o token) |
| Body (JSON) |
Payload completo (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Inválido |
| Criterios |
Usuario no autenticado |
| Valores frontera considerados |
Sesión inexistente vs. token caducado |
| Salida esperada — Código HTTP |
401 o 403 |
| Salida esperada — Body |
Mensaje indicando falta de autenticación |
| Salida esperada — Efecto |
No se registra ninguna respuesta en BD |
| Contexto de ejecución |
Petición sin login previo; servidor activo con middleware de autenticación |
POST /ensayos/{id}/responder — Caso 4: Formato inválido sin autenticación
| Campo |
Valor |
| Método |
POST |
| URL |
{{BASE_URL}}/ensayos/{id}/responder |
| Headers |
Content-Type: application/json (sin cookies o token) |
| Body (JSON) |
Payload incompleto (expuesto al final de la sección) |
| Categoría |
Descripción |
| Clase(s) de equivalencia |
Inválido |
| Criterios |
Usuario no autenticado y payload inválido |
| Valores frontera considerados |
Formato inválido con sesión inexistente; la API puede validar sesión antes o payload antes |
| Salida esperada — Código HTTP |
401, 403 o 400/422 dependiendo del orden de validación |
| Salida esperada — Body |
JSON o texto indicando error de autenticación o de formato |
| Salida esperada — Efecto |
No se registra ninguna respuesta en BD |
| Contexto de ejecución |
Petición sin login; servidor activo; middleware de autenticación y validación de payload activos |
Payload completo (valido)
{
"respuestas": [
{"id_pregunta": 1, "respuesta": "B"},
{"id_pregunta": 2, "respuesta": "A"},
],
"tiempo": 30
}
Payload incompleto (no válido)
{
"respuestas": "esto_no_es_una_lista"
}
Implementación (Python unittest)
Estructura seguida:
tests/
├─ test_api_funcional.py
├─ test_ensayos.py
└─ test_pregunts.py
Ejecución
Para ejecutar los scripts de testing, es necesario levantar el proyecto en modo detached con el siguiente comando:
docker compose up --build -d
Seguido a esto, se ejecutan los casos de prueba por separado:
docker compose exec tester python -m unittest tests.tests_ensayos
docker compose exec tester python -m unittest tests.tests_preguntas