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:
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.
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:
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.
#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;
}