Você está na página 1de 20

En este artículo voy a mostrar cómo utilizar el ABAP Unit en una clase para administrar

una calculadora simple de cuatro operaciones.

Clase ZCL_CALCULATOR

Atributos del ZCL_CALCULATOR

Métodos de la clase ZCL_CALCULATOR.


La secuencia de las acciones será la siguiente:

1. Llama al método ENTER_DIGIT () para cada dígito del primer número;


2. Llama método ENTER_OPERATION (). En este método, el valor actual
del DISPLAY se almacena en el atributo PREVIOUS_VALUE.
3. Llama método ENTER_DIGIT () para cada dígito del segundo número;
4. Llama método EXECUTE () que realiza la operación entre el
PREVIUS_VALUE y el DISPLAY. El resultado será almacenado en el
atributo DISPLAY y entonces debemos llamar al método GET_DISPLAY ()
para mostrar el valor de la pantalla.
Algunas validaciones de operación no válida y división por cero también se implementan,
aún así todavía faltan algunos controles básicos, que dejo para ustedes implementar y
enviarnos el NUGG corregido.

Creación y uso de la clase de prueba


Con los atributos y métodos creados, podemos crear la clase de prueba unitaria, usando
el camino indicado en la figura abajo:

Creación de clases de prueba

Para ejecutar las pruebas unitarias, usamos el siguiente elemento del menú:
Ejecución de pruebas unitarias

Para acceder a la clase local de prueba se utiliza el siguiente elemento del menú:

Acceder a la clase de prueba unitaria

Escribir pruebas unitarias


En la clase unitaria es donde programamos las pruebas que queremos que el sistema se
ejecute al girar la prueba unitaria. En este artículo vamos a estudiar el método EXECUTE
().

* * * * * * * * * * * * * * * * ---------------------
CLASS abap_unit_testclass DEFINITION FOR TESTING "#AU Duration Medium

"#AU Risk_Level Harmless

* * * * * * * * * * * * * * * * ---------------------

* ===================

PUBLIC SECTION.

* ===================

* =======================

PROTECTED SECTION.

* =======================

* ====================

PRIVATE SECTION.

* ====================

TYPE-POOLS: abap.

FECHA:

m_ref TYPE REF TO zcl_calculator. "#EC NOTEXT

DATA: is_exception TYPE abap_bool,

error_message TYPE cadena.

METHODS: setup.

METHODS: teardown.

METHODS: clear_display FOR TESTING.

METHODS: enter_digit FOR TESTING.

METHODS: enter_operation FOR TESTING.

METHODS: ejecute FOR TESTING.

METHODS: get_display FOR TESTING.

Endclass. "Abap_Unit_Testclass

* * * * * * * * * * * * * * * * ---------------------

CLASS abap_unit_testclass IMPLEMENTATION.

* * * * * * * * * * * * * * * * ---------------------
* * * * * * * * * * * * * * * * ---------------------

METHOD setup.

* * * * * * * * * * * * * * * * ---------------------

CREATE OBJECT m_ref.

ENDMETHOD. "Configuración

* * * * * * * * * * * * * * * * ---------------------

METHOD teardown.

* * * * * * * * * * * * * * * * ---------------------

ENDMETHOD. "desmontaje

* * * * * * * * * * * * * * * * ---------------------

METHOD clear_display.

* * * * * * * * * * * * * * * * ---------------------

DATA re_display TYPE cadena.

m_ref-> clear_display ().

re_display = m_ref-> get_display ().

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = zcl_calculator => digit_0

msg = 'Error clearing display.' ).

ENDMETHOD. "Clear_Display

* * * * * * * * * * * * * * * * ---------------------
METHOD enter_digit.

* * * * * * * * * * * * * * * * ---------------------

DATA im_digit TYPE char1.

DATA re_display TYPE cadena.

m_ref-> clear_display ().

im_digit = zcl_calculator => digit_0.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'0'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '0'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_1.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'1'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '1'

msg = error_message).

* --------------------------------------------------
im_digit = zcl_calculator => digit_2.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'12'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '12'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_3.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'123'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '123'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_4.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'1234'

'Actual'

re_display
INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '1234'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_5.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'12345'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '12345'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_6.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'123456'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '123456'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_7.

m_ref-> enter_digit (im_digit).


re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'1234567'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '1234567'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_8.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'12345678'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '12345678'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_9.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'123456789'

'Actual'

re_display

INTO error_message

SEPARATED BY space.
cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '123456789'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_0.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'1234567890'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '1234567890'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_1.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'

'12345678901'

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '12345678901'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_2.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Error entrando digit:'

im_digit

'Esperaba'
'123456789012'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '123456789012'

msg = error_message).

* --------------------------------------------------

im_digit = zcl_calculator => digit_3.

m_ref-> enter_digit (im_digit).

re_display = m_ref-> get_display ().

CONCATENATE 'Enter más de 12 dígitos.'

'Esperaba'

'123456789012'

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = '123456789012'

msg = error_message).

ENDMETHOD. "Enter_Digit

* * * * * * * * * * * * * * * * ---------------------

METHOD enter_operation.

* * * * * * * * * * * * * * * * ---------------------

DATA: is_exception TYPE char1.

" ... SUMA

CLEAR is_exception.

TRY.

m_ref-> enter_operation (zcl_calculator => plus).

CATCH zcx_invalid_operation.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (


act = is_exception

exp = abap_false

msg = 'Error on operation sum.' ).

" ... SUBTRATION

CLEAR is_exception.

TRY.

m_ref-> enter_operation (zcl_calculator => subtraction).

CATCH zcx_invalid_operation.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (

act = is_exception

exp = abap_false

msg = 'Error en la operación de sustracción.' ).

" ... DIVISIÓN

CLEAR is_exception.

TRY.

m_ref-> enter_operation (zcl_calculator => division).

CATCH zcx_invalid_operation.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (

act = is_exception

exp = abap_false

msg = 'Error on operation division.' ).

" ... MULTIPLICACIÓN

CLEAR is_exception.

TRY.

m_ref-> enter_operation (zcl_calculator => multiplication).

CATCH zcx_invalid_operation.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (

act = is_exception

exp = abap_false
msg = 'Error en la operación de multiplicación.' ).

"... WRONG OPERATION

CLEAR is_exception.

TRY.

m_ref-> enter_operation ('@').

CATCH zcx_invalid_operation.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (

act = is_exception

exp = abap_true

msg = 'Error on operation: wrong operation.' ).

ENDMETHOD. "Enter_Operation

* * * * * * * * * * * * * * * * ---------------------

METHOD ejecuta.

* * * * * * * * * * * * * * * * ---------------------

DATA: re_display TYPE cadena,

lv_expected TYPE cadena,

is_exception TYPE char1.

" ... SUMA

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_2).

m_ref-> enter_digit (zcl_calculator => digit_5).

m_ref-> enter_operation (zcl_calculator => plus).

m_ref-> enter_digit (zcl_calculator => digit_1).

m_ref-> enter_digit (zcl_calculator => digit_6).

m_ref-> execute ().

re_display = m_ref-> get_display ().

lv_expected = '41 .00 '.

CONCATENATE 'Error 25 + 16'

'Esperaba'

lv_expected

'Actual'
re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = lv_expected

msg = error_message).

" ... SUBTRATION

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_2).

m_ref-> enter_digit (zcl_calculator => digit_5).

m_ref-> enter_operation (zcl_calculator => subtraction).

m_ref-> enter_digit (zcl_calculator => digit_1).

m_ref-> enter_digit (zcl_calculator => digit_6).

m_ref-> execute ().

re_display = m_ref-> get_display ().

lv_expected = '9.00'.

CONCATENATE 'Error 25 - 16'

'Esperaba'

lv_expected

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = lv_expected

msg = error_message).

" ... MULTIPLICACIÓN

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_2).


m_ref-> enter_digit (zcl_calculator => digit_5).

m_ref-> enter_operation (zcl_calculator => multiplication).

m_ref-> enter_digit (zcl_calculator => digit_1).

m_ref-> enter_digit (zcl_calculator => digit_6).

m_ref-> execute ().

re_display = m_ref-> get_display ().

lv_expected = '400.00'.

CONCATENATE 'Error 25 * 16'

'Esperaba'

lv_expected

'Actual'

re_display

INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = lv_expected

msg = error_message).

" ... DIVISIÓN

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_2).

m_ref-> enter_digit (zcl_calculator => digit_5).

m_ref-> enter_operation (zcl_calculator => division).

m_ref-> enter_digit (zcl_calculator => digit_1).

m_ref-> enter_digit (zcl_calculator => digit_6).

m_ref-> execute ().

re_display = m_ref-> get_display ().

lv_expected = '1.56'.

CONCATENATE 'Error 25/16'

'Esperaba'

lv_expected

'Actual'

re_display
INTO error_message

SEPARATED BY space.

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = lv_expected

msg = error_message).

"... DIVISION BY CERO

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_2).

m_ref-> enter_digit (zcl_calculator => digit_5).

m_ref-> enter_operation (zcl_calculator => division).

m_ref-> enter_digit (zcl_calculator => digit_0).

TRY.

m_ref-> execute ().

CATCH cx_sy_zerodivide.

is_exception = abap_true.

EndTry.

cl_aunit_assert => ASSERT_EQUALS (

act = is_exception

exp = abap_true

msg = 'Error on operation division - cero divide.' ).

lv_expected = zcl_calculator => error.

re_display = m_ref-> get_display ().

CONCATENATE 'Error de pantalla después de cero divide'

'Esperaba'

lv_expected

'Actual'

re_display

INTO error_message

SEPARATED BY space.
cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = lv_expected

msg = error_message).

ENDMETHOD. "Ejecutar

* * * * * * * * * * * * * * * * ---------------------

METHOD get_display.

* * * * * * * * * * * * * * * * ---------------------

DATA: re_display TYPE cadena.

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_1).

re_display = m_ref-> get_display ().

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = zcl_calculator => digit_1

msg = 'devuelto el valor.' ).

* --------------------------------------------------

m_ref-> clear_display ().

m_ref-> enter_digit (zcl_calculator => digit_0).

re_display = m_ref-> get_display ().

cl_aunit_assert => ASSERT_EQUALS (

act = re_display

exp = zcl_calculator => digit_0

msg = 'devuelve un valor erróneo en la pantalla clara.' ).

ENDMETHOD. "Get_Display

Endclass. "Abap_Unit_Testclass
ver primaabap_unit_testclass CLASE - ZCL_CALCULATOR acogió con por GitHub

Dentro del método podemos probar cuántos escenarios deseamos. En el caso estamos
probando las cuatro operaciones y más una división por cero. En la prueba unitaria
simulamos el uso de la clase ZCL_CALCULATOR. En el primer escenario probamos la
suma de los números 25 y 16 donde el resultado esperado es 41. Entramos con los
dígitos 2 y 5, la operación de suma y de ahí los dígitos 1 y 6 y ejecuta el método
EXECUTE (). La magia ocurre en el método CL_AUNIT_ASSERT => ASSERT_EQUALS
(), donde pasamos como parámetros el valor esperado, el valor del resultado de la
ejecución del método EXECUTE () y el mensaje de error. Si el valor esperado no es igual
al valor calculado se contabiliza un error. Al ejecutar las pruebas unitarias, tenemos un
informe de error:

Unidad de ensayo de ensayo

En la figura anterior tenemos la indicación de fallo en una de nuestras pruebas. En el lado


derecho del informe de prueba unitaria, puede encontrar el detalle del error:

Unidad de ensayo de ensayo

Observe el mensaje de error: 'Error 25 + 16 Expected: 41.00 actual: 42.00'. Este mensaje
fue generado por esta prueba (de un clic en el enlace de Stack):
ABAP Unit - Escenario de suma

Por eso es interesante generar un mensaje bien explicativo.

Corregir el error
Sabemos que el error fue en el método EXECUTE (), cuando estamos haciendo una
suma. Esto significa que el código está "roto" y debemos comprobar lo que está mal con
él. Veamos lo que está sucediendo con el método en cuestión:

METHOD ejecuta.

DATA: vl_result TYPE p LENGTH 9 DECIMALS 2,

vl_actual TYPE p LENGTH 9 DECIMALS 2.

vl_actual = display.

CASE operand.

WHEN plus.

vl_result = previous_value + vl_actual + 1. "<===== EL ERROR ESTÁ AQUÍ !!!!

WHEN subtraction.

vl_result = previous_value - vl_actual.


WHEN division.

TRY.

vl_result = previous_value / vl_actual.

LIMPIEZA.

display = error.

EndTry.

WHEN multiplicación.

vl_result = previous_value * vl_actual.

ENDCASE.

display = vl_result.

ENDMETHOD.
ver primamétodo run acogido con por GitHub

El error está en la suma, donde se agrega el resultado de uno. Después de la corrección


del código podemos ejecutar la prueba uniario nuevamente y ver el resultado:

Resultado ABAP Unit