Sentencia ASSERT en ABAP: Aserciones para test y debugging

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

La sentencia ASSERT sirve para hacer aserciones (en inglés: Assertions) sobre el estado de tu programa en tiempo de ejecución y verificarlas. Una aserción es una condición de la que tú como desarrollador asumes firmemente que siempre debe ser verdadera (abap_true) en un punto determinado del código.

ASSERT es principalmente una herramienta para:

  • Desarrollo y test: Para detectar tempranamente errores lógicos en el programa o suposiciones incorrectas sobre estados de datos.
  • Debugging: Para determinar rápidamente en qué punto se violó una suposición.
  • Documentación de código: Para expresar explícitamente suposiciones sobre el estado del programa en el código.

Diferencia importante: ASSERT no está pensado para el manejo normal de errores (p.ej. entradas de usuario inválidas, estados de error esperados en la lógica de negocio) en entornos productivos. Para eso debes usar consultas IF, MESSAGE, RAISE EXCEPTION, etc. ASSERT verifica errores de programación o estados que “nunca” deberían ocurrir.

Sintaxis

ASSERT [ ID <grupo_aserciones> ]
[ SUBKEY <subclave> ]
[ FIELDS <campo1> <campo2> ... ]
CONDITION <expresion_logica>. " ¡La palabra clave CONDITION es obligatoria!
  • ID <grupo_aserciones> (Opcional): Asigna la aserción a un llamado “Checkpoint Group” o “grupo de aserciones”. Estos grupos pueden activarse, desactivarse o configurarse centralmente (transacción SAAB). Esto es muy útil para controlar el comportamiento de las aserciones a nivel de sistema o específicamente por usuario.
  • SUBKEY <subclave> (Opcional): Un texto adicional (subclave) para mayor identificación o contextualización de la aserción dentro de un grupo ID.
  • FIELDS <campo1> <campo2> ... (Opcional): Aquí puedes especificar una lista de objetos de datos (variables). Si la aserción falla, los valores de estos campos se muestran en el protocolo (log) o en el dump, lo que facilita considerablemente la búsqueda del error.
  • CONDITION <expresion_logica>: ¡Obligatorio! Esta es la expresión lógica que se evalúa. La aserción se considera cumplida (exitosa) cuando esta expresión evalúa a abap_true.

Funcionamiento y comportamiento en caso de fallo

En tiempo de ejecución se verifica la <expresion_logica>:

  1. Si la condición es abap_true (verdadera): La aserción se cumple. No pasa nada más y el programa continúa normalmente. Tu suposición sobre el estado del programa era correcta.
  2. Si la condición es abap_false (falsa): La aserción falla. Lo que sucede entonces depende de la configuración de activación de la aserción (controlada mediante ID, SUBKEY en la transacción SAAB o parámetros globales del sistema):
    • Inactiva: La sentencia ASSERT se ignora completamente. No tiene efectos en la ejecución ni en el rendimiento. Esta es la configuración por defecto para sistemas productivos.
    • Activa - Modo ‘Log’: El fallo de la aserción se protocola (p.ej. en el System Log, transacción SM21, o en un log especial para checkpoint groups). Los valores especificados en FIELDS pueden incluirse en el protocolo. El programa continúa después. Este modo es útil en sistemas de test o aseguramiento de calidad.
    • Activa - Modo ‘Abort’/‘Break’: El programa aborta con un error en tiempo de ejecución (dump) del tipo ASSERTION_FAILED, o se detiene en el debugger en ese punto (según configuración). Esta suele ser la configuración deseada durante la fase de desarrollo, para alertar inmediatamente sobre el error lógico.

Casos de uso

  • Verificación de precondiciones para métodos o módulos de función (p.ej. ASSERT CONDITION parameter IS NOT INITIAL.).
  • Verificación de postcondiciones tras la ejecución de bloques de código (p.ej. ASSERT CONDITION resultado > 0.).
  • Verificación de invariantes (estados que siempre deben cumplirse, p.ej. dentro de un bucle o para un objeto, ASSERT CONDITION object_ref IS BOUND.).
  • Aseguramiento contra estados “imposibles” en estructuras CASE o IF (p.ej. en la rama WHEN OTHERS de una sentencia CASE donde no se espera ningún otro caso: ASSERT CONDITION 1 = 0.).

Ejemplos

1. Verificación simple de precondición

METHOD calculate_price.
IMPORTING quantity TYPE i.
" Suposición: La cantidad no puede ser negativa para este cálculo
ASSERT CONDITION quantity >= 0.
" ... cálculo de precio ...
ENDMETHOD.

2. Verificación de postcondición con FIELDS

DATA total TYPE p DECIMALS 2.
DATA item_count TYPE i.
" ... código que calcula total e item_count ...
ASSERT ID zmy_calc_group SUBKEY 'FinalCheck'
FIELDS total item_count
CONDITION total >= 0 AND ( item_count = 0 OR total > 0 ).
" Suposición: Suma total nunca negativa; si hay items, la suma debe ser > 0.

3. Verificación de referencia de objeto

DATA factory TYPE REF TO zcl_my_factory.
DATA instance TYPE REF TO zif_my_interface.
factory = zcl_my_factory=>get_instance( ).
ASSERT CONDITION factory IS BOUND. " Suposición: Factory siempre existe
instance = factory->create_object( type = 'A' ).
ASSERT CONDITION instance IS BOUND. " Suposición: Objeto se creó exitosamente
instance->do_work( ).

Notas importantes / Mejores prácticas

  • Usa ASSERT como herramienta de aseguramiento de calidad durante el desarrollo y en test, no para manejar errores en tiempo de ejecución esperados en el sistema productivo.
  • Usa siempre el adicional ID para hacer tus aserciones controlables mediante SAAB. Elige nombres de grupo significativos.
  • Usa el adicional FIELDS para ver valores de variables relevantes en caso de fallo.
  • Asegúrate de que las aserciones están inactivas por defecto en sistemas productivos, para evitar pérdidas de rendimiento o abortos no deseados. La activación se hace entonces de forma específica cuando sea necesario para análisis.
  • Escribe aserciones para todas las suposiciones no triviales que hagas sobre tu código o tus datos.