Buscar

Javier Caceres – jacace

Javier's blog about C#, Software Architecture and Design

Categoría

Testing

Combinatorial Testing for taking real world desitions

Recently I run into the problem of figuring out what was wrong with a combination of parameters I needed to use the Amazon Simple Queue Service -SQS for short- (more information here). The Amazon SQS requires the following query string parameters when establishing a HTTP get request:

http://END-POINT/ACCOUNT#/QUEUE-NAME?AWSAccessKeyId=ACCESS-KEY&Action=SendMessage&MessageBody=hello%20world&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp=2012-12-11T13%3A14%3A02&Version=2012-11-05&Signature=YOUR-CALCULATED-SIGNATURE

After reading MANY Amazon forums plus the official documentation I figured out that it’s tricky defining what parameters are required and most importantly, in what format. For example: some forums say the ACCOUNT# and QUEUE-NAME are required, others don’t; some say the time stamp time zone needs to be included, some others don’t.

So I came up with a solution for looking the right parameters and formats in an efficient way. I listed all parameters which potentially could cause the issue as follows:

END-POINT
Ireland end point (HTTP) OR Global end point (HTTP) OR
Ireland end point (HTTPS) OR Global end point (HTTPS) OR
OR Ireland end point (HTTP) plus %0A at the end

QUEUE-NAME (within the signature):
Empty OR with queue name OR with queue name plus account number

Timestamp:
Url Enconded OR Not Url Encoded
AND
with time zone OR without time zone
AND
based on the current time OR based on the current UTC time

Query String Separator:
Ampersand (&) OR Url encoded ampersand

Protocol
HTTP OR HTTPS

Query String Parameters’ ordering:
Lexicographically or random

Signature result:
Url encoded OR not URL encoded

Server end point:
Including Account# plus queue name OR only the end point address

After listing the possible alternatives I did some filtering according to what I thought the most likely working parameters were,  otherwise I would had to test more than 1.000 combinations. The following is the filtered list:

(A) Ireland end point (HTTP)
(B) Ireland end point (HTTP) plus %0A at the end
(C) With queue name
(C1) With queue name plus account number
(D) Timestamp: Url Enconded
(E) Timestamp: with time zone
(E1) Timestamp: without time zone
(F) Timestamp: based on the current time
(F1) Timestamp: based on the current UTC time
(G) Ampersand query string separator
(H) HTTP protocol
(I) Lexicographically ordering
(I1) Random ordering
(J) URL encoding the signature result
(K) Including Account# plus queue name

With the previous filtered list in my hands I only had to find the combinations. So I used PICT (I already commented it in a previous post here). I built the following model in a text file named model.txt:

Hostname: A, B
Quename: C, C1
Timestamp1:D
Timestamp2:E, E1
Timestamp3:F, F1
General1: G
General2: H
General3: I, I1
General4: J
General5: K

Then I instructed PICT to sign my model and changed the default order of the combinations from 2 to 10 (because I want to test all my 10 variables) with the following line:

pict model.txt /o:10 > model.xls

And I got the following combinations:

amazon_http_get_request_pict

Then I applied some filtering again because the (I1) is technically valid but it makes no sense a random order if you already have one in place. So I filtered again and got the following nice data set of 16 items:

amazon_http_get_request_pict_items

I wrote a function to create a query string and then I automated the creation of the 16 test cases with the following code:

string A = "sqs.eu-west-1.amazonaws.com";
 string B = "sqs.eu-west-1.amazonaws.com%0A";
 string C = "/";
 string C1 = "/YOUR_ACCOUNT_NUMBER/YOUR_QUEUE_NAME";
 string DE1F1 = DateTime.Now.ToString("s");
 DE1F1 = HttpUtility.UrlEncode(DE1F1).ToUpper();
 string DE1F = DateTime.UtcNow.ToString("s");
 DE1F = HttpUtility.UrlEncode(DE1F).ToUpper();
 string DEF1 = DateTime.Now.ToString("s") + "Z";
 DEF1 = HttpUtility.UrlEncode(DEF1).ToUpper();
 string DEF = DateTime.UtcNow.ToString("s") + "Z";
 DEF = HttpUtility.UrlEncode(DEF).ToUpper();

string G = "&";
 string H = "http";
 bool I = false; //Not possible
 bool I1 = true;
 bool J = true;
 string K = "/YOUR_ACCOUNT_NUMBER/YOUR_QUEUE_NAME";
 string url = "";
 string canonicalStr = "";

//Case #: 1
 ParametersFinder(A, C1, DE1F1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 2
 ParametersFinder(B, C, DE1F1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 3
 ParametersFinder(B, C1, DE1F, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 4
 ParametersFinder(B, C1, DE1F1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 5
 ParametersFinder(B, C, DEF1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 6
 ParametersFinder(A, C, DE1F1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 7
 ParametersFinder(A, C1, DEF, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 8
 ParametersFinder(A, C, DEF, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 9
 ParametersFinder(B, C, DE1F, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 10
 ParametersFinder(A, C, DE1F, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 11
 ParametersFinder(A, C, DEF1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 12
 ParametersFinder(B, C, DEF, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 13
 ParametersFinder(A, C1, DE1F, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 14
 ParametersFinder(A, C1, DEF1, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 15
 ParametersFinder(B, C1, DEF, G, H, I1, J, K, out url, out canonicalStr);
 //Case #: 16
 ParametersFinder(B, C1, DEF1, G, H, I1, J, K, out url, out canonicalStr);

Finally I run the code, recorded the the result of each ParametersFinder call to a file and quickly tested them in my favorite web browser. At the end I found the right parameters and it was a good exercise. Certainly there are tons of ways to take desitions like this, tons of tools and tons of things to improve in this solution but due the fact that actually this is something  you do not have to do every day then a simple yet powerful set of tools and methods like these ones help you to be successful in this kind of black operations.

Thanks,

Cheers,

Javier Andrés Cáceres Alvis

Microsoft Most Valuable Professional – MVP
Intel Black Belt Software Developer

Ejemplo de Pruebas de Software – Parte 1

Algunas personas me han preguntado sobre cómo hacer pruebas en Windows Phone 7, sin embargo cuando respondo la pregunta me entero que quien pregunto no maneja los conceptos de pruebas, por eso antes de responder preguntas sobre como probar Windows Phone con SilverLigth, realizaré un pequeño ejercicio de diseño de casos de prueba.

Supongan que alguien les dice “diseñe los casos de prueba para la siguiente función”:

char* LoadFile(char filePath[MAX_PATH], char* mode, DWORD dwDesiredAccess, DWORD dwCreationDisposition)

Antes de empezar a pensar que hacer, deben definir una pequeña estrategia que debería responder al menos cuatro preguntas 1-¿Qué se va a probar?, 2-¿Desde cual perspectiva se va a probar?, 3-¿A qué nivel se va a probar? y 4-¿con cuáles técnicas voy a probar? Responder las anteriores preguntas me da una visión más clara del objetivo de mis pruebas, con lo cual sabré cuando he terminado. Quién te encargó diseñar los casos de pruebas solo debería contestarte la pregunta 1-¿Qué se va a probar?, las demás deberías definirlas tú mismo.

 

Pruebas Funcionales.

Supongan que la respuesta fue: “quiero probar los requerimientos funcionales, no funcionales y la cobertura de código.” Esta respuesta es el mínimo insumo para empezar a trabajar. Iniciemos definiendo la estrategia para realizar las pruebas funcionales; si vas a probar requerimientos funcionales debes preguntar ¿Cuáles son los requerimientos? Supongan que la respuesta es: “la función debe recibir una ruta de máximo 256 caracteres (mínimo 4 caracteres) y debe cargar de allí el contenido del archivo en un vector. El contenido de los archivos puede ser cualquier byte que se pueda representar con un juego de caracteres ASCII. Como pudieron observar, ahora tenemos la respuesta a la pregunta 1 (¿Qué se va a probar?).

En adelante trabajaremos por nuestra cuenta; los requerimientos funcionales se prueban usualmente a nivel de sistema, por lo cual no nos interesa saber el contenido de la función LoadFile y la perspectiva de pruebas será caja negra. Con lo anterior tenemos las respuestas a las preguntas 2 y 3, solo falta escoger que técnicas vamos a emplear; existen muchas técnicas por ejemplo: Equivalence Class Partitioning -ECP-, Boundary Value Analysis -BVA- y Combinatorial  (Pair wise) testing. Para nuestro ejemplo utilizaremos una mezcla de las anteriores técnicas.

 

Aplicaremos ECP al parámetro 1 filePath porque sabemos que puede ser cualquier cadena desde 4 hasta 256 caracteres de longitud; como pueden suponer lo peor que podemos hacer es 252 pruebas porque son equivalentes, por lo tanto solo probaremos con una cadena de 4 caracteres y una de 256, de forma positiva (es decir, que la cadena represente una ruta válida) y de forma negativa (que la cadena represente una ruta no válida). Así pues definimos los siguientes conjuntos: v1 (cualquier cadena válida desde 4 hasta 256 caracteres), i1  (cualquier cadena no válida desde 4 hasta 256 caracteres) y i2 (una cadena con valor NULL).

#

Parámetro

Datos

Ejemplo Datos

Comentario

1

filePath

v1

c:\tareas.txt

El archivo del ejemplo existe

2

filePath

i1

c:\taras.txt

El archivo del ejemplo NO existe

3

FilePath

i2

NULL

 

 

Ahora aplicamos la técnica BVA a todo lo que se trate de límites máximos y mínimos; en nuestra ejemplo conocemos los límites 4 y 256, por lo cual deberíamos probar el valor límite y una unidad por encima y por debajo, es decir cualquier valor válido de longitud 3, longitud 5, longitud 255 y longitud 257. La siguiente matriz de pruebas  resume lo anterior:

4

filePath

Longitud 3

No hay cargue.

c:\

 

5

filePath

Longitud 5

Cargue correcto.

c:\mi

El archivo del ejemplo existe

6

filePath

Longitud 255

Cargue correcto.

 Una cadena de 255

El archivo del ejemplo existe

7

filePath

Longitud 257

No hay cargue.

 Una cadena de 257

El archivo del ejemplo existe. 

 

Como todos los demás parámetros tienen valores predefinidos hacemos un conjunto de las posibles opciones que puede tomar cada parámetro:

mode: r, r+, rb, rb+

dwDesiredAccess: GENERIC_READ, GENERIC_READ | GENERIC_WRITE

dwCreationDisposition: PEN_EXISTING, OPEN_ALWAYS            

Ejemplo de Pruebas de Software – Parte 2

Viene de Parte 1

[Update 12/Dec/2012 More on combinatorial testing with PICT here: Combinatorial Testing for taking real world desitions]

Los conjuntos anteriores son independientes, por lo cual deberíamos probar todas las combinaciones posibles; sin embargo las posibles combinaciones son aproximadamente 112 (4 valores posibles para el parámetro mode X 2 valores posibles para el parámetro dwDesiredAccess X 2 posibles valores para el parámetro dwCreationDisposition X 7 posibles valores para el parámetro filePath). 112 pruebas manuales pueden convertirse en 4 días laborales (si gastamos 15 minutos por cada caso de prueba y trabajamos 8 horas diarias), por lo cual es mala idea obtener las combinaciones de forma manual. La mejor opción es utilizar la herramienta PICT de Jacek Czerwonka para encontrar un número de combinaciones que tengan la cobertura más eficiente.  Esta herramienta requiere que pasemos como parámetro los datos de entrada en el siguiente formato:

filePath:              c:\tareas.txt, c:\taras.txt, NULL, c:\, c:\mi, c:\cadenade255.txt,cadenade257.txt

mode:                  r, r+, rb, rb+

dwDesiredAccess:          GENERIC_READ, GENERIC_READ | GENERIC_WRITE

dwCreationDisposition:               PEN_EXISTING, OPEN_ALWAYS

Este artículo no es un tutorial de PICT, por lo cual mostraré la salida que produce dicha herramienta sin entrar en detalles:

 

Como se aprecia en la tabla anterior, PICT nos generó 28 casos de prueba combinando las variables independientes en orden 2 de forma eficiente. Si lo hubiéramos hecho manualmente habrían sido 112 de orden 4 que alcanzaban una cobertura un poco mejor a la generada por PICT.  Tenga en cuenta: lo importante no es conocer una herramienta, sino saberla usar: sin el análisis de datos que hicimos al inicio, no hubiéramos podido definir buenos datos de entrada.

Pruebas Estructurales

De igual forma que definimos una estrategia para el diseño de pruebas funcionales, necesitamos definir una estrategia para las pruebas estructurales. Las pruebas estructurales son casi siempre de nivel unitario y perspectiva caja blanca, por lo cual debemos revisar el código para conocer lo que vamos a probar. El código del método LoadFile se muestra a continuación:

char* LoadFile(char filePath[MAX_PATH], char* mode, DWORD dwDesiredAccess, DWORD dwCreationDisposition)

{    

      if(filePath==NULL)

      {

            return NULL;

      }

      else

      {

            int l=strlen(filePath);

           

            if(lMAX_PATH)

            {

                  return NULL;

            }

            else

            {

                  HANDLE hFile=CreateFile(filePath, dwDesiredAccess, FILE_SHARE_READ, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);

 

                  if(hFile==INVALID_HANDLE_VALUE)

                  {

                        return NULL;

                  }

                  else

                  {

                        LARGE_INTEGER size;

                        GetFileSizeEx(hFile, &size);

                        CloseHandle(hFile);

 

                        if(size.LowPart>MAX_FILE_SIZE)

                        {

                             return NULL;

                        }

                        else

                        {

                             char *fileContent=new char[size.LowPart];

 

                             if(fileContent==NULL)

                             {

                                   return NULL;

                             }

                             else

                             {                      

                                   FILE *fp=fopen(filePath, mode);

 

                                   if(fp==NULL)

                                   {

                                         return NULL;

                                   }

                                   else

                                   {

                                         int i=0;

 

                                         while(!feof(fp))

                                         {

                                               fileContent[i]=fgetc(fp);

                                               i++;

                                         }

 

                                         return fileContent;

                                   }

                             }                                                         

                        }

                  }

            }

      }

}

Continúa en Parte 3

Ejemplo de Pruebas de Software – Parte 3

Viene de Parte 2

Las pruebas estructurales se centran en la cobertura de código y el control del flujo, por lo cual lo primero que hacemos es un diagrama de control de flujo (CFD, por sus siglas en inglés) para ver el código de forma más abstracta (en forma de modelo):

Figura 1. CFD del ejemplo.

Las cláusulas IF y WHILE se expresan como círculos con un número en un CFD y las flechas significan las posibles salidas (Falso o Verdadero) de cada cláusula. Con el código expresado en un CFD podemos definir las técnicas a emplear más fácilmente. Algunas técnicas de pruebas estructurales son: Block, Condition, Desition y Path testing. Emplearemos todas menos block testing porque es la más incompleta de todas las técnicas.

 

El condition testing se enfoca en las cláusulas simples (no compuestas) que pueden ser verdaderas o falsas sin operadores relacionales. Es decir, cada cláusula IF o WHILE se enfoca en la salida Verdadero o Falsa sin importar las sub condiciones o rangos que puedan tener. Para tener una cobertura de código del 100% de las condiciones tendríamos que hacer 13 casos de prueba, uno falso y uno verdadero por cada cláusula IF (6 sentencias IF X 2) más un caso verdadero para la cláusula WHILE.

 

Con la técnica desition testing debemos tener en cuenta las sub condiciones de cada cláusula. Según el código podemos analizar que existen 4 cláusulas IF y una cláusula WHILE simples (con una sola condición) y dos cláusulas IF con sub condiciones que  se muestran a continuación:

1) if(lMAX_PATH)

2) if(size.LowPart>MAX_FILE_SIZE)

La clausula 1 está compuesta por dos sub condiciones en las cuales la variable “l” puede ser menor, igual o mayor que la variable MIN_LEN, de igual modo, la variable “l” puede ser menor, igual o mayor que la variable MAX_PATH; según lo anterior podemos obtener los siguientes casos de prueba:

#

Variable

Variable

Variable

Condición 1

Condición 1

1

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l>MAX_PATH

2

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l>MAX_PATH

3

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l>MAX_PATH

4

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l=MAX_PATH

5

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l=MAX_PATH

6

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l=MAX_PATH

7

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l<MAX_PATH

8

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l<MAX_PATH

9

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l<MAX_PATH

 

Sin embargo al analizar las combinaciones, observamos que algunos casos no son posibles (los casos # 1, 2, 4 y 5), por lo cual depuramos nuestras condiciones y obtenemos solo 5 casos:

Ejemplo de Pruebas de Software – Parte 4

Viene de Parte 3

#

Variable

Variable

Variable

Condición 1

Condición 1

 

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l>MAX_PATH

 

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l>MAX_PATH

1

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l>MAX_PATH

 

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l=MAX_PATH

 

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l=MAX_PATH

2

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l=MAX_PATH

3

l

MIN_LEN

MAX_PATH

l<MIN_LEN

l<MAX_PATH

4

l

MIN_LEN

MAX_PATH

l=MIN_LEN

l<MAX_PATH

5

l

MIN_LEN

MAX_PATH

l>MIN_LEN

l<MAX_PATH

La cláusula numero 2 tiene un operador y dos variables que permiten diseñar los siguientes tres casos de prueba:

#

Variable 1

Variable 2

Condición 1

1

size.LowPart

MAX_FILE_SIZE

size.LowPart>MAX_FILE_SIZE

2

size.LowPart

MAX_FILE_SIZE

size.LowPart=MAX_FILE_SIZE

3

size.LowPart

MAX_FILE_SIZE

size.LowPart

Para tener una cobertura de código del 100% de las decisiones deberíamos hacer 16 casos de prueba (8 + 5 + 3). 

La última técnica estructural es el Path testing, con esta técnica buscamos recorrer todos los flujos de control presentes en el código; observando el CFD anterior podemos concluir que para tener una cobertura del 100% de los paths deberíamos hacer 8 casos de prueba.

Pruebas No Funcionales.

Para diseñar casos de prueba no funcionales, debemos investigar cuáles son los requerimientos no funcionales porque en el enunciado inicial no se mencionó nada sobre el tema. Debemos recordar que un requerimiento no funcional como “el método LoadFile debe ser rápido” no sirve para nada, porque no es medible y por lo tanto no podemos compararlo con nada. Un requerimiento funcional podría ser el método debe ejecutarse en 0.0000005 milisegundos. Las técnicas no funcionales incluyen pruebas de performance, stress, seguridad, usabilidad, accesibilidad y compatibilidad; en nuestro caso la usabilidad y accesibilidad no son importantes porque no tenemos interfaces de usuario finales.

 

Para medir el rendimiento y asegurarnos que cumple el requerimiento, podemos desarrollar nuestro propio código de prueba como el que sigue a continuación:

      time_t dt1;

      time(&dt1);

 

      char* fileContent=LoadFile(“C:\\doc.txt”, “rb+”,  GENERIC_READ, OPEN_EXISTING);

 

      time_t dt2;

      time(&dt2);

 

      double elapsedTime=difftime(dt1, dt2);

Otra opción es utilizar contadores de rendimiento junto con la herramienta Performance Monitor. Para las pruebas de stress, observamos que la función maneja archivos hasta de MAX_FILE_SIZE bytes, por lo cual hacemos pruebas que excedan ampliamente ese límite para ver el comportamiento, también podemos consumir la función de forma continua por largos periodos (por ejemplo toda una noche) para verificar que no degrade la memoria de la máquina.

 

Para hacer pruebas de seguridad nos podríamos concentrar en los bytes que se están leyendo del archivo, sin embargo como no es un requerimiento, solo buscamos las áreas expuestas por nuestra aplicación (por ejemplo: el puntero char* de retorno podría ser empleado para corromper el funcionamiento del método, por lo cual una recomendación o bug al respecto es sugerir un cambio en el diseño para que la memoria sea colocada y destruida por el consumidor).

 

En cuanto a compatibilidad, debemos investigar en que máquinas (32 ó 64 bits) debe correr el método, cuáles tipos de archivos se debe leer, que tipos de rutas de archivos están soportadas (rutas locales, rutas de red, URL’s, etc.); las respuestas a todas estas preguntas nos darán un número de casos de prueba proporcionales.

Las pruebas no funcionales como están basadas en requerimientos, deben ser definidas desde el diseño para mejorar el nivel de “testability” del código; existen muchas herramientas y posibles sets de pruebas, sin embargo solo nos enfocamos en las preguntas más básicas que se deben responder.

 

Conclusión.

Usualmente nos concentramos en las pruebas funcionales y dejamos a un lado otros aspectos inherentes a nuestro software, como la estructura del código y los requerimientos no funcionales. Si probamos eficientemente nuestro software, la calidad aumentará y como resultado, la satisfacción del cliente también. En total diseñé 71 casos de prueba.

Javier Andrés Cáceres Alvis
MVP WIndows Mobile
http://speechflow.spaces.live.com/
http://software.intel.com/en-us/blogs/author/javierandrescaceres/

Testing the Microsoft Developer Network Web Site

Hi everybody,
Today I’m going to share something I’m tired of: the sign in system of the Microsoft Developer Network.
Well I’m a frequent contributor/participant of the MSDN forums and community, so everyday I check the forums for at least three times.
The problem is that I first log in to hotmail.com and then go to the forums page the system doesn’t recognize me:
Until here something is wrong, why does the system ask me about signing in again if I’m logged to hotmail.com?, Well I just click on the “Sign in” hyperlink next to the “United States (English)” hyperlink and after an automatically signing in I’m took back to the last page but again something is weird as you can see in the next picture:
For some reason, I’m not yet logged into the system as the “Sign in to forums” hyperlink next to “My forum links” shows in the above picture. It seems those are two iframes or different pages which don’t talk each other Confundido . Well I’m forced to click on the “Sign in To Forums” but surprise!, I’m not automatically signed in, I’m redirected to the standard Windows Live log in page and I had to introduce my password again. After that I finally reach next page:
After some online activity I decided to leave the system, so click on the Sign Out hyperlink next to the “United States (English)” hyperlink and you know what? the “My Forums Links” sidebar shows me still logged in as shown in the picture below.
Well, what can I say?, as a Software Developer Enginner who likes testing I have built systems which falls in this kind of navigation inconsistency -and belive me, I still develop them-. I know it’s hard to model all the navigation paths a user can take, but as explained in the book “How We Test Software at Microsoft” some combinatorial testing can be performed by using a tool like PICT to ensure most probable combinations are covered or writing a Control Flow Diagrams at system level can be usefull. .
A conclusion at this point, it’s that as developers/testers, We focus on the main functionality (let’s say, posting questions in the MSDN forums system), on the happy path but We forget important features like testing the password recovery system, the about box dialog, the log in system, the integration of external components (like the sign in system in this sample) and others.
Best regards,
Javier Andrés Cáceres Alvis
[Update]: After leaving the MSDN forums web site and browsing back to hotmail.com I usually/randomly get this weird message explaining that there were problems retrieving the contact list. #Fail.

Probando (testing) el Recover Password?

Te has quedado esperando un mensaje de recuperación de password (Recover Password)?
Pues les cuento que yo si me quedé esperando el mensaje de la Microsoft Software Developer Network como se muestra en la siguiente imagen y los 15 minutos de espera máxima garantizada se han vuelto horas y el email nunca llegó Confundido #Fail.
Esto es muy común en los sistemas que desarrollamos, nos enfocamos en la funcionalidad principal (happy path) y detalles como la página de error donde se redireccionan los usuarios, el sistema de recordatorio de contraseñas, el acerca de y otros los dejamos a un lado.

Diagramas de Control de Flujo para Testing

Hola a tod@s,
Quisiera compartirles una poderosa herramienta de abstracción de pruebas: los diagramas de control de flujo. Estos son diagramas más simplificados que un simple diagrama de flujo y permiten modelar y abstraer un caso de pruebas a cualquier nivel. Recuerden que si prueban con perspectiva de caja negra podrán modelar a nivel de sistema (usuario final) pero si lo hacen con perspectiva de caja blanca el modelo será a nivel de funciones (líneas de código).
Imaginen que tenemos el siguiente fragmento de código:
1. if (conditionA)
2. {
3.   c=c+1
4. }
5. if(conditionB)
6.   d=d-1
7. else
8.   e++
El diagrama de control de flujo (CFD, por sus siglas en inglés) con perspectiva de caja blanca será así:
A primera vista puede parecer confuso, pero si utilizan como guía el número e línea de código descubrirán que es más sencillo y legible que el código en sí mismo para cualquier persona (así sea ajena a tu equipo), por consiguiente se podrá modelar y diseñar a un nivel más adecuado los casos de prueba, las condiciones de error que va a probar, la covertura de código que desea alcanzar, etc, etc.
Para más información
Capítulo “Structural testing techniques” -página 115- de el libro “How We Test Software at Microsoft“.
El ejemplo práctico de uno de los autores:

¿El análisis estático es una Verificación ó Validación?

Muchas personas se preguntan si el análisis estático de código es una verificación o validación, pero muchas más personas no saben la diferencia entre las dos y por eso no saben cuando una técnica o herramienta es de un tipo u otro.
Pues para resumir, verificar es un proceso de calidad en el cual revisamos si el producto final y sus artefactos intermedios cumplen con los estándares ó póliticas de la organización; por el contrario validación es revisar si el producto y sus artefactos intermedios cumplen con las necesidades del cliente.
Todo se resume mejor en la siguiente imagen:
Pregunta:   ¿Un producto puede ser verificado satisfactoriamente pero no validado?
Respuesta: Si. De hecho es uno de los casos más comunes en desarrollo de software, en el cual se ejecuta un proceso correctamente cuyo resultado técnico no cumple los requerimientos o no satisface al cliente.
Estos conceptos son usados por muchos como un término umbrella, de ahí la célebre pero confusa pregunta:
Verification: “Are we making the product properly?”
Validation – “Are we making a proper product?”
Finalmente podemos concluir que el análisis estático es una verificación
Saludos,
Javier Andrés Cáceres Alvis

 

Blog de WordPress.com.

Subir ↑