3

Maquinas de estado

Una máquina de estados (también conocida como FSM del inglés finite state machine) es un grafo dirigido cuyos nodos representan estados y cuyas aristas representan transiciones entre dichos estados. De esta forma podemos modelar por ejemplo el comportamiento de entidades o los pasos de un caso de uso (como se vio en una sección anterior).
**
La estructura de la máquina de estados puede utilizarse para diseñar casos de prueba que la recorran atendiendo a algún criterio de cobertura. Algunos de estos criterios de cobertura son:

  • Cobertura de estados: Este criterio se satisface cuando los casos de prueba recorren todos los estados
  • Cobertura de transiciones: En este caso cuando se recorren todas las transiciones.
  • Cobertura de pares de transiciones: Para cada estado se cubren las combinaciones de transiciones de entrada y salida.

Aplicación de la técnica en un ejemplo

Veamos un caso de prueba de ejemplo para la Gestión de Artículos, que quizá sea el concepto central en cualquier sistema de Retail de la operativa de cualquier empresa.
**
Un posible enfoque para el diseño de casos de prueba es modelar el comportamiento de los artículos con una máquina de estados y a partir de ella derivar los casos de prueba. Los artículos pueden tener distintos estados, y el comportamiento esperado para cada acción o funcionalidad del sistema, dependerá del estado asociado al artículo.
Captura.JPG
Los estados determinan distintos comportamientos de las instancias de artículos. Las transiciones se corresponden con funcionalidades del sistema que hacen que el artículo cambie su comportamiento, su estado.
**
La máquina de estado muestra el comportamiento esperado de la entidad Artículo en su ciclo de vida. Lo que se intentará es cubrir todas las transiciones y nodos de este diagrama siguiendo un algoritmo definido. El resultado de aplicar ese algoritmo es un conjunto de secuencias a seguir sobre la máquina de estados, que definen los casos de prueba interesantes, que para esta máquina de estados son las siguientes:

  • Caso 1: Alta preliminar de artículo, verificar datos y rechazar compra
  • Caso 2: Alta preliminar de artículo, verificar datos y aprobar por el comprador responsable de área.
  • Caso 3: Alta preliminar de artículo, verificar datos y aprobar por el comprador responsable de área, completar los datos por trade marketing, el gerente de departamento de compras no aprueba la compra por ser un artículo no promocional y saturado.
  • Caso 4: Alta preliminar de artículo, verificar datos y aprobar por el comprador responsable de área, completar los datos por trade marketing, el gerente de departamento de compras no aprueba la compra para un artículo promocional y saturado.
  • Caso 5: Alta preliminar de artículo, verificar datos y aprobar por el comprador responsable de área, completar los datos por trade marketing, el gerente de departamento de compras aprueba la compra para un artículo no promocional y no saturado
  • Caso 6: Alta preliminar de artículo, verificar datos y aprobar por el comprador responsable de área, completar los datos por trade marketing, el gerente de departamento de compras aprueba la compra para un artículo promocional y saturado

Hasta aquí se cuenta con los casos de prueba en alto nivel (casos de prueba abstractos). O sea, solo se cuenta con las secuencias de funcionalidades que se deben invocar, y las condiciones sobre los datos. Luego se deben definir los datos concretos que permitan ejecutar sobre el sistema. Al ejecutar se utiliza la máquina de estados como oráculo (para determinar si el resultado es válido o inválido), pues se debe verificar en cada paso si se llegó al estado esperado o no. Cada caso de prueba abstracto podrá corresponderse con uno o más casos de prueba concretos en base a los distintos datos que se seleccionen.

Algoritmo en lenguaje C

#include <stdio.h>#include <stdlib.h>

void delay(){
        for(int i = 0; i < 10000; i++){for(int d = 1; d <= 10000; d++){}
        }
}

int main(void){
        char state1, state2, state3, state4;

        printf("Alta preliminar del articulo. \n");
        delay();
        printf("Estado: Pendiente de aprobacion \n");
        delay();
        printf("Verificando datos y evaluando compra... \n");
        delay();
        printf("Aprueba? (Y/N) ");
        scanf(" %c", &state1);if(state1 == 'Y' || state1 == 'y'){
                printf("Producto aprobado\nPasando al siguiente estado... \n");
                delay();
                printf("Llenando datos... Aprobado por el responsable del area \n");
                delay();
                printf("Pendiente de aprobacion por el gerente del departamento... \n");
                delay();
                printf("Articulo promocional? (Y/N) ");
                scanf(" %c", &state2);switch(state2){
                        case'Y':
                                printf("Aprueba el articulo? (Y/N) ");
                                scanf(" %c", &state3);if(state3 == 'Y' || state3 == 'y'){
                                        printf("Articulo dado de alta \n");
                                }elseif(state3 == 'N' || state3 == 'n'){
                                        printf("Articulo rechazado!! \n");
                                }else{
                                        printf("invalid argument \n");
                                }
                                break;case'N':
                                printf("Articulo saturado? (Y/N) ");
                                scanf(" %c", &state4);if(state4 == 'Y' || state4 == 'y'){
                                        printf("Articulo no aprobado \n");
                                }elseif(state4 == 'N' || state4 == 'n'){
                                        printf("Aprueba el producto? (Y/N) ");
                                        scanf(" %c", &state3);if(state3 == 'Y' || state3 == 'y'){
                                                printf("Producto aprobado \n");
                                        }elseif(state3 == 'N' || state3 == 'n'){
                                                printf("Producto rechazado! \n");
                                        }
                                }
                                break;default:
                                printf("invalid argument \n");break;
                }
        }elseif(state1 == 'N' || state1 == 'n'){
                printf("Producto RECHAZADO!! \n");
        }else{
                printf("invalid argument \n");
        }

        return0;
}
Escribe tu comentario
+ 2