jueves, 27 de julio de 2017

Automatización: POM (Page Object Model) Profundizando el modelo


En esta segunda parte sobre POM voy a tratar una estrategia que implementé con muy buenos resultados en distintos proyectos y que me permitieron obtener un grado de flexibilidad bastante importante a la hora de realizar y mantener los casos de prueba.
Cómo mencioné en el post anterior POM intenta encapsular la interacción con la página a través de una abstracción que la representa.  Sin embargo esto nos deja bastante atados a la estructura de la página y nos quita flexibilidad a la hora de trabajar, porque si o si, nuestro modelo es una representación de una única página.  Esto es algo que no se puede evitar si se utiliza POM, pero si se puede alivianar o desestructurar un poco. 
Para hacer esto lo primero que tenemos que preguntarnos es ¿Qué es una página web?  Hay muchas respuestas posibles a esta pregunta dependiendo de cómo la encaremos, pero hay una que es muy sencilla, y también poco exacta, pero que nos sirve mucho a la hora de encarar un proyecto de automatización utilizando POM.  Utilizando esta respuesta o definición podemos considerar a una página web como una colección de controles web.  De esta forma podemos dividir nuestro modelado en distintas capas, por un lado tendremos el modelado de los controles posibles, textbox, combos, botones, radiobuttons, etc. Y encapsular dentro de ellos toda la lógica de cómo encontrar el control e interactuar para llevar adelante determinada acción.  Así por ejemplo tendremos una clase de tipo botón que sabrá cómo localizarse a sí mismo en un página web determinada y a su vez expondrá un método HacerClick() que sabrá qué hacer cuando quien diseñe el caso de prueba determine que quiere realizar un click sobre él.  Siguiendo esta lógica luego, en una segunda capa de modelado, crearemos una clase para representar una página web, pero la misma estará compuesta por controles.  Por ejemplo si fuera un login típico, tendría dos controles de tipo textbox, uno para el usuario y otro para el password, un control de tipo botón para realizar el login y uno de tipo texto o etiqueta, donde puedan verse los errores que la página exponga, por ejemplo el cásico “Usuario o clave incorrecta”.  De esta forma si exponemos los controles como parte de la interfaz de la clase, es decir, como propiedades accesibles desde fuera de ella, cualquier caso de prueba podrá interactuar con ellos de la manera que crea conveniente evitando así que tengamos que generar métodos para determinados comportamientos. 
Lo expuesto anteriormente nos permite separar un poco el modelo de la prueba, complica la lógica del modelo, pero simplifica y flexibiliza la prueba porque ahora es el caso de prueba quien interactúa con el modelo de la forma que quiere y no siguiendo métodos preestablecidos que devuelven un valor determinado.  Sin embargo esto se puede flexibilizar un poco más aún o mejor dicho independizar la forma de encontrar un control del código fuente del modelo.  La idea es extraer el método de búsqueda del control y el valor por el cual buscaremos del código y dejarlo almacenado en otro lado.  En mi caso suelo utilizar diccionarios xml de controles donde mediante un nombre “funcional”, amigable para el usuario, pueda obtener el método de búsqueda, por ejemplo xpath y el valor de dicho xpath.  Así entonces un control recibirá un “Nombre funcional” y un diccionario en donde se encuentra dicho nombre, y con estos parámetros será capaz de encontrarse a sí mismo en una página web determinada y, si en un futuro este método y/o valor de búsqueda cambian, sólo hará falta actualizar el diccionario y el script debería seguir funcionando sin problemas, es decir que editando un archivo ajeno al código fuente mantenemos la funcionalidad.



domingo, 5 de febrero de 2017

Mantis BT

Esta entrada iba a ser sobre cómo trabajar los archivos de configuración de Mantis, sin embargo a la hora de empezar a armar el tutorial me encontré con que en la nueva versión de la herramienta cambiaron algunas cosas.  Por lo tanto tengo que investigar un poco esto antes de subir la info, por esto es que decidí hacer un video con una especie de repaso por las funcionalidades de esta herramienta,  Espero les sea útil.


jueves, 19 de enero de 2017

Automatización: POM (Page Object Model)

Comenzaré esta nota describiendo e intentando explicar qué es POM y cómo se utiliza.  En verdad es algo sencillo, tanto que podría resumirse en apenas una frase.  POM es encapsular la interacción con el html, es brindar un servicio a quien realice la automatización para disminuir el costo de mantenimiento y creación de los scripts de prueba.

El modelo Página-Objeto debe pensarse como la abstracción de la interfaz de usuario, en este caso una página web, que conoce y sabe cómo interactuar con ella, pero que oculta toda su complejidad y le facilita a quien consuma el modelo la interacción con dicha web.  Para lograr este objetivo se modela un objeto que representa la página o una porción de ella, que conoce los controles que esta posee, como interactuar con ellos y la interacción que pueda haber entre los mismos.  De esta forma se separa toda la lógica que relaciona el caso que se desea probar con el objeto de prueba dejando que el script interprete el comportamiento del objeto de prueba, y el modelo se ocupe de llevar a cabo las acciones pertinentes sobre este.  Así será el script quien realice las aserciones sobre lo que el modelo le devuelva luego de haber interactuado con el objeto.

Para que esto funcione bien es necesario entonces que el modelo conozca con suficiente profundidad al objeto de prueba y sepa cómo lograr los comportamientos deseados.  Esto podemos lograrlo exponiendo métodos diferentes, por ejemplo en el caso de querer realizar una validación podríamos exponer un método para el funcionamiento correcto y otro para la excepción, de esta forma será el “usuario” del modelo quien decida cuál de ellos invocar en función de lo que desee probar.
El siguiente fragmento ejemplifica el punto anterior.

Modelo:
public class MiPagina
{
public bool EjecutarConContenidoCorrecto(string nombre, string apellido, string documento)
{
                bool resultadoEjecucion;
//Lógica para Búsqueda de elementos, colocación de valores, ejecución del formulario y determinación de la correcta ejecución.
return resultadoEjecucion;
}
public string EjecutarConContenidoErroneo(string nombre, string apellido, string documento)
{
                string mensajeDeError;
//Lógica para búsqueda de elementos, colocación de los valores, ejecución del formulario y obtención del mensaje de error.
return mensajeDeError;
}
}

Scripts
public void ValidacionFormularioRegistro()
{
                MiPagina formularioRegistro = new MiPagina();
assertText(formularioRegistro. EjecutarConContenidoErroneo(“pepe”, “rodriguez”, “30-9658748-3”));
}
public void RegistrarUsuario(string nombre, string apellido, string documento)
{
                MiPagina formularioRegistro = new MiPagina();
assertTrue(formularioRegistro. EjecutarConContenidoErroneo(nombre, apellido, documento));
}

Aplicando este modelo logramos que quien consuma el servicio provisto por nuestra clase se despreocupe por cómo hacer para hallar los elementos, y en su lugar se concentre en determinar qué hacer con ellos y cómo determinar si su funcionamiento es correcto.  Además, como consecuencia de este encapsulamiento se abarata el costo de mantener los scripts de prueba puesto que en el caso en donde la lógica funcional sea la misma, en el caso propuesto rellenar los campos de un formulario y presionar el botón que lo envía, pero varíe la aplicación técnica, por ejemplo posición o nombre de los controles, el cambio se realizaría dentro del modelo dejando los scripts intactos o con modificaciones mucho menores.

Hasta aquí llevé adelante un aplicación objetiva de este modelo, ahora voy a expresar opiniones personales basadas en mi interpretación y experiencia, por lo tanto suceptible a completos desacuerdos.


A mi parecer POM es una práctica interesante pero limitada en cuanto a que el modelo, en mayor o menor medida, se ata al objeto de prueba y por ende sólo es útil y aplicable en él.  Es cierto que esto se puede extender y generalizar un poco, peor aún así, y siempre desde mí punto de vista y limitada experiencia, estaremos atados a cierta estructura.  Quienes hayan hablado conmigo sobre automatización sabrán que me salgo bastante de los estándares recomendados y que tengo un punto de vista y un objetivo que apunta a desarrollar algo que nos permita reducir al máximo el costo de la automatización.  En esto estuve trabajando hace un tiempo y ya tengo algo bastante pulido para presentar así que posiblemente pronto suba novedades sobre este tema.

lunes, 16 de enero de 2017

Testing unitario, de integración y funcional o de sistema.

La intención de esta nota es acercar una definición para cada uno de estos términos para así poder entender las diferencias entre ellos y el por qué no debería excluirse ninguno de los niveles en las pruebas de un producto software.

Pruebas unitarias:  para realizar un prueba unitaria lo primero que deberíamos definir es cuál es el alcance de nuestra unidad, a qué grado de granularidad queremos llegar y esto debe tener en cuenta la tecnología y lenguajes sobre los que estamos trabajando.  Hoy en día el paradigma de objetos se encuentra extendido a muchos negocios y lenguajes de programación como Java, .Net, Ruby, PHP, C++, etc.,  que hacen uso de dicho paradigma, resultan la elección adecuada para modelar y diseñar nuestros sistemas.  Sin embargo hay todavía vetustos sistemas que hacen uso de lenguajes que aplican paradigmas distintos como por ejemplo Report Program Generator (RPG) y COmmon Business-Oriented Language (COBOL ) que, por distintas cuestiones, muchas de ellas económicas, integran y conviven con plataformas más modernas.  Esta cuestión hace que muchas veces no podamos definir de forma taxativa el criterio de unidad para nuestras pruebas ya que la tecnología aplicada, los lenguajes de programación forman parte de ella, influyen en gran medida en el significado de unidad.  Para dar un ejemplo sencillo, si nuestro sistema estuviese diseñado en un lenguaje orientado a objetos podríamos decir sin temor a equivocarnos que nuestra unidad más pequeña podría ser una clase y así definir si quisiéramos, que ese es el nivel de granularidad que elegimos para la ejecución e implementación de nuestras pruebas unitarias, sin embargo  ¿Podríamos aplicar el mismo criterio si tuviéramos que testear programas que fueron realizados en COBOL o RPG?  La respuesta es no, porque la Clase no existe como estructura en estos lenguajes.  Entonces deberemos elegir otra unidad más apropiada a la tecnología con la que está construido ese sistema, quizás debiésemos considerar unidad a un programa entero, podríamos trabajar con las distintas subrutinas que lo componen, hay varias opciones que deberían ser analizadas.

Dije hasta el momento que para realizar una prueba unitaria es primero necesario definir a que llamaremos una unidad, y que esta definición depende en gran medida, aunque no solamente, de las restricciones o limitaciones de la propia tecnología utilizada en la construcción del sistema.  Supongamos entonces que estamos trabajando con .Net como leguaje y nuestra aplicación está modelada siguiendo el paradigma de programación orientada a objetos.  Siguiendo esta lógica definiremos como unidad una clase puesto que queremos llegar a una buena profundidad con nuestras pruebas unitarias.  ¿Cómo se llevarían a cabo estas pruebas?  ¿Qué habilidades debería tener desarrolladas una persona para ser capaz de realizar estas pruebas?
Normalmente suele decirse que las pruebas unitarias las realiza desarrollo, que son pruebas que el propio programador lleva adelante, sin embargo esto no tienen por qué ser así.  Habiendo comenzado esta nota diciendo que la tecnología utilizada en la construcción de nuestro sistema influye en gran medida en la definición de unidad, resulta de alguna manera evidente que quien lleve a cabo las pruebas unitarias debe poseer habilidades técnicas de relevancia, en particular en este caso debería tener un conocimiento medianamente elevado en lo que a programación .Net se refiere y esto se debe a que, en su mayoría las pruebas unitarias son pruebas programadas.  Pueden estar llevadas a cabo por el desarrollador, puede haber un equipo de testing qué, conociendo la estructura de las clases definidas se encargue de desarrollar scripts que consuman y hagan uso de las clases y métodos disponibles.

Las pruebas unitarias son pruebas técnicas, son pruebas que requieren de conocimiento técnico, leguajes de programación y la programación en sí misma.  En una prueba unitaria se generarán arneses de prueba que se encargarán de llamar/ejecutar a nuestras unidades o que serán llamados/ejecutados por estas, la generación de dichos arneses de prueba es también parte del desarrollo de las pruebas unitarias.  Mediante una prueba unitaria puedo detectar cuestiones tales como errores lógicos en la implementación de los métodos públicos y privados de una clase, atributos faltantes e incluso excepciones no controladas dentro de la propia clase y luego también analizar la cobertura que estas pruebas están realizando respecto a la totalidad del código, es decir cuánto código es ejecutado por mis pruebas.

En resumen podría decir que una prueba unitaria es una prueba técnica qué se lleva a cabo sobre una unidad y que requiere normalmente de conocimientos de programación.  Qué puede o no ser llevada a cabo por testers y que es capaz de detectar errores lógicos y de estructura en las unidades probadas.

Pruebas de integración: las pruebas de integración dependen en gran medida de las decisiones y criterios que hayamos utilizado a la hora de definir nuestras pruebas unitarias y, si bien son independientes en cierta medida de estas, pierde sentido realizar pruebas de integración cuando no se llevaron a cabo pruebas unitarias.  El objetivo de una prueba de integración es comprobar que nuestras unidades interactúan bien entre ellas, es decir que no hay conflictos entre las interfaces que se encargan de comunicar a nuestras unidades.  Las pruebas de integración asumen que los componentes o unidades que van a integrarse fueron probados y que funcionan correctamente de forma independiente y se centra en las dificultades que puedan ocurrir durante su comunicación, de ahí que pierda un poco el sentido realizar una prueba de integración sino realicé una prueba unitaria con anterioridad puesto que puede no resultar claro si la falla se debe a una mala interacción entre las partes o al funcionamiento defectuoso de una de ellas.
Las pruebas de integración también requieren conocimientos técnicos y su efectividad depende en gran medida de la estrategia utilizada en la integración.  Dije anteriormente que el objetivo de una prueba de integración es encontrar defectos en la comunicación entre las unidades que pueden deberse a diversas cuestiones como ser diferencias entre la cantidad de parámetros enviados, el tipo de datos de estos o incluso a problemas en la sincronización de diversos hilos de trabajo.  En este nivel los arneses de prueba construidos comienzan a quitarse, según la estrategia de integración definida, y se reemplazan por unidades reales, también puede que se construyan otros arneses o se modifiquen los existentes porque por ejemplo un arnés resolviera lo realizado por varias unidades.
Me resulta necesario aclarar que una prueba de integración depende en gran medida de la definición que se haya dado de unidad, así podríamos por ejemplo estar hablando de la integración de diversos sistemas, módulos o funcionalidades y de cómo estos interactúan entre sí con todas las particularidades que esto implica.
Para resumir las pruebas de integración diría que son pruebas también técnicas, que su éxito depende mucho de la estrategia de integración utilizada y que tienen sentido si se llevaron a cabo las pruebas unitarias.  Su objetivo es encontrar defectos en cuanto a la comunicación entre las unidades.

Prueba funcional o de sistema: si las pruebas unitarias o de integración requerían de un elevado nivel técnico, las pruebas de sistemas implican un gran conocimiento a nivel negocio.  En estas pruebas nos enfocaremos desde el lado de un usuario y nos encargaremos de comprobar que la funcionalidad se aplicó de forma correcta y completa, es decir que verificaremos no sólo que el sistema lo que hace lo hace bien, sino que además comprobaremos que haga todo lo que tiene que hacer.  Las pruebas de sistemas son en gran medida independientes de las de integración y unidad y, aunque no es recomendable, pueden llevarse a cabo si los anteriores niveles no se probaron puesto que el enfoque que realizan y los defectos que son capaces de encontrar son totalmente diferentes.  Una prueba de sistema no podrá verificar si la comunicación entre las interfaces es correcta, tampoco podrá verificar si un unidad contiene o no problemas lógicos en su construcción, pero podrá detectar errores a nivel funcional, desde mensajes de error incorrectamente aplicados hasta validaciones no realizadas, a caminos que desde lo programático pueden parecer correctos pero que desde el punto de vista del negocio no sólo pueden no tener sentido, sino que hasta puede ser incorrecto o ilegal su recorrido.  Las pruebas de sistema no sólo verificarán que el sistema funciona como un todo haciendo lo que tiene que hacer, de forma completa y bien, sino que además verificarán el cumplimiento normativas internas y/o legales que puedan estar regulando la actividad donde el sistema construido se desarrollará.

Resumiendo las pruebas funcionales se puede decir que su objetivo es comprobar la solución desde el punto de vista de un usuario, verificar y validar su correcto funcionamiento y completitud e incluso el acuerdo con las normas internas o legales que regulen la actividad donde el software producido ejerza sus funciones.


Espero que esta nota pueda aportar un poco de claridad en cuanto a que significa cada nivel de prueba ya que me encontré con errores conceptuales bastante importantes respecto a estos temas que llevan a confusiones bastante perjudiciales para los proyectos de construcción de software.

Herramientas - CBU

Hace un tiempo desarrollé una herramienta que genera CBUs válidos para la entidad financiera solicitada.  Compartí esta herramienta a través del blog de Testing Baires y ahora que poseo un blog propio para tratar estos temas quise compartirla también por acá.  Copiando un poco la forma en la que Gustavo armó el artículo en su blog voy a colocar una definición de lo que es la Clave Bancaria Uniforme, en este caso no será producción propia sino que utilizaré parte de la definición que wikipedia brinda.

La Clave Bancaria Uniforme (CBU), a veces llamada Clave Bancaria Única o Clave Bancaria Unificada, es un código utilizado en Argentina por los bancos para la identificación de las cuentas de sus clientes. Mientras que cada banco identifica las cuentas con números internos, la CBU identifica una cuenta de manera única en todo el sistema financiero argentino. Está compuesta por 22 dígitos, separados en dos bloques.
Los 22 dígitos de la CBU están divididos en dos bloques. El primer bloque tiene un número de entidad de 3 dígitos, un número de sucursal de 4 dígitos y un dígito verificador. El segundo bloque tiene un número de 13 dígitos que identifica la cuenta dentro de la entidad y la sucursal, más un dígito verificador.
Códigos de la entidad según los primeros tres dígitos
Código
Entidad
005
ABN AMRO BANK
007
BANCO DE GALICIA
011
BANCO NACION
014
BANCO DE LA PROVINCIA DE BS. AS
015
INDUSTRIAL AND COMMERCIAL BANK OF CHINA S.A.
016
CITIBANK S.A.
017
BBVA BANCO FRANCES
018
THE BANK OF TOKYO-MITSUBISHI
020
BANCO DE CORDOBA
027
BANCO SUPERVIELLE S.A.
029
BANCO CIUDAD
034
BANCO PATAGONIA S.A.
044
BANCO HIPOTECARIO S.A.
045
BANCO DE SAN JUAN
046
BANCO DO BRASIL S.A.
060
BANCO DE TUCUMAN
065
BANCO MUNICIPAL DE ROSARIO
072
BANCO SANTANDER RIO S.A.
083
BANCO DEL CHUBUT
086
BANCO DE SANTA CRUZ S.A.
093
BANCO DE LA PAMPA
094
BANCO DE CORRIENTES S.A.
097
BANCO PROVINCIA DEL NEUQUÉN
150
HSBC BANK ARGENTINA S.A.
191
BANCO CREDICOOP
259
BANCO ITAU BUEN AYRE S.A.
268
BANCO PCIA DE TIERRA DEL FUEGO
285
BANCO MACRO
299
BANCO COMAFI S.A.
303
BANCO FINANSUR S.A.
311
NUEVO BANCO DEL CHACO S.A.
312
MBA BANCO DE INVERSIONES S.A.
319
BANCO CMF S.A.
322
NUEVO BANCO INDUSTRIAL DE AZUL
325
DEUTSCHE BANK S.A.
330
NUEVO BANCO DE SANTA FE
338
BANCO SANTIAGO DEL ESTERO S.A.
341
BANCO MÁS VENTAS
386
NUEVO BANCO DE ENTRE RIOS S.A.

Fuente: Wikipedia

El programa está compartido a través de Google Drive y pueden acceder a él dese el link Descargar desde aquí

Requisitos

Para que funcione se debe tener instalado el framework 4.5 de .Net:

En Windows

En Linux

Técnica de algoritmo dual, pairwise testing o all-pairs testing.

Pairwise testing, también llamado algoritmo dual, es una técnica utilizada para disminuir la cantidad de casos de prueba que pueden resultar de la combinación de varios valores intentando mantener un nivel de cobertura aceptable.  Para esto se agrupan los valores posibles en duplas, tercetos, etc. y se evalúa la combinación de estos.  Esto se basa en el hecho de que la mayor parte de los errores se producen como consecuencia de la combinación de dos o más factores, es por esto que, a pesar de reducir notablemente la cantidad de casos de prueba generados, se logra mantener altos niveles de cobertura y detección de defectos .

La técnica puede resultar sencilla en la teoría, sin embargo cuando la cantidad de condiciones es muy grande se vuelve muy difícil manejarla sin el apoyo de una herramienta.  Son muchas las herramientas existentes y también lo son las prestaciones que brindan, algunas permiten por ejemplo utilizar combinaciones de n elementos en lugar de sólo dos, realizar combinaciones mezcladas en cuanto a cantidad de elementos e incluso ponderar algunas de las condiciones para darles más peso a la hora de seleccionar casos de prueba.

Supongamos que debemos probar un sistema que recibe tres parámetros: importe, descuento y retiro  con las siguientes clases de equivalencia

Importe: < 1000. >=1000;
Descuento: 25%, 35%
Retiro: en el local, Envío a domicilio

Si quisiéramos realizar todas las combinaciones posibles  para estos 6 valores necesitaríamos 2*2*2 (8)  casos de prueba.


Número de caso
Importe
Descuento
Retiro
1
< 1000
25%,
en el local
2
< 1000
25%,
Envío a domicilio
3
< 1000
35%
en el local
4
< 1000
35%
Envío a domicilio
5
>=1000
25%,
en el local
6
>=1000
25%,
Envío a domicilio
7
>=1000
35%
en el local
8
>=1000
35%
Envío a domicilio

Puede  observarse a través del ejemplo que si la cantidad de condiciones de prueba o sus valores posibles aumenta, la cantidad de casos de prueba asociados a estas lo hará de forma exponencial provocando que resulten cantidades tan grandes que resulten difícil de manejar.

Al aplicar la técnica de pairwise agruparemos dos de los valores como si de uno solo se tratase y lo combinaremos con el tercero.  De esta forma podríamos agrupar por ejemplo importe y descuento, eligiendo valores aleatorios para la combinación, por un lado y combinarlo luego con retiro.

Importe + descuento: <1000 25%, >1000 35%
Retiro: en el local, Envío a domicilio


Número de caso
Importe + Descuento
Retiro
1
<1000, 25%
en el local
2
 <1000, 25%
Envío a domicilio
3
>1000, 35%
en el local
4
>1000, 35%
Envío a domicilio

Ahora al combinar dos valores en un único parámetro, la combinación se reduce a 2*2 pasando de tener los ocho casos originales a trabajar con sólo cuatro de ellas.


En este ejemplo la técnica puede aplicarse con sencillez debido a la poca cantidad de clases de equivalencia y variables con las que estamos trabajando, pero esto será, seguramente, mucho mayor en la realidad por lo que recomiendo el uso de herramientas.  Siguiendo este link encontraran varias herramientas gratuitas y aranceladas, con interfaz gráfica o utilizables por consola junto con varios papers que hablan más profundamente sobre el tema.  También para quienes se lleven bien con el inglés les recomiendo leer este otro link

Pruebas de Performance 1

Tipos de testing de performance

Baseline: tiene por objetivo hallar las métricas para la performance del sistema bajo cargas normales de trabajo y se suele utilizar como base para comparrar los otros tipos de prueba.

Prueba de carga (Load testing): tiene por objetivo medir al sistema bajo una carga intensa sin sobrepasar el máximo establecido, es decir se mantiene dentro de los rangos de trabajo pero cercano al límite mientras se mide la respuesta del servidor.

Prueba de estres (stress testing): Tiene por objetivo encontrar el punto de ruptura del sistema, es decir se fuerza al sistema en forma gradual para ver en que punto deja de responder.

Soak Testing: su objetivo es asegurar que no emergen comportamientos indeseados con el correr del tiempo.  Por lo general este tipo de pruebas suele encontrar problemas de memoria (memory leaks) y las pruebas consisten en ejecutar pruebas de carga o baseline durante un período de tiempo prolongado.

Testing de escalabilidad (Scalability testing): El objetivo es medir al sistema ante grandes volúmenes de datos.  Son pruebas similares a las pruebas de carga con la diferencia que en este caso en lugar de aumentar la cantidad de consultas se realizan consultas más complejas, anidadas o que implican la circulación de un gran volumen de datos.


Estrategias

¿Cómo enfocar el testing de performance de web services?

El testing de web servicies puede enfocarse desde dos aspectos básicos.  El primero tiene que ver con el proceso de parsing y serialization de los XML que viajarán haciendo que falle el proceso de las cargas útiles esperadas.
El segundo factor tiene que ver con la seguridad y radica en la utilización de una capa de seguridad a nivel servicios que puede provocar una merma en cuanto a performance, sobre todo si esta se encuentra detrás de un sitio que trabaja con el protocolo https.
Estos dos factores implican enfoques o estrategias distintas a la hora de realizar pruebas de performance sobre servicios web, para el primer factor se hará foco en pruebas de escalabilidad mientras que para el segundo se utilizarán pruebas de carga, especialmente si se está trabajando con una capa de seguridad a nivel servicios.

Por otro lado, independientemente del factor a tratar siempre es conveniente realizar un análisis de los WSDL´s para comprobar la complejidad, el tamaño o si incluye adjuntos de gran tamaño.  Para casos como estos es conveniente también realizar pruebas de carga.