unitarias test tecnicas software pruebas para herramientas funcionales español ejemplos ejemplo driven development unit-testing testing automated-tests

unit testing - test - Comprender cómo funciona la prueba de software y qué probar



tecnicas de pruebas de software (5)

Introducción:
He visto muchos temas aquí en SO sobre las pruebas de software y otros términos que no entiendo.

Problema:
Como desarrollador principiante, desafortunadamente, no tengo idea de cómo funciona la prueba de software, ni siquiera cómo probar una función simple. Esto es una pena, pero esa es la verdad. También espero que esta pregunta pueda ayudar a otros desarrolladores principiantes también.

Pregunta:
¿Me puedes ayudar a entender este tema un poco más?

Tal vez algunas preguntas para comenzar ayuden:

  • Cuando desarrollo una función, ¿cómo debo probarla? Por ejemplo: cuando trabajo con una función de suma, ¿debo probar cada valor de entrada posible o solo algunos límites? ¿Qué tal pruebas de funciones con cadenas como parámetros?
  • En un gran programa, ¿tengo que probar cada pieza del código? Cuando ustedes programan ¿prueban cada código escrito?
  • ¿Cómo funciona la prueba automatizada y cómo puedo probar una? ¿Cómo funcionan las herramientas para las pruebas automatizadas y qué hacen?
  • He oído sobre pruebas unitarias. ¿Puedo tener una breve explicación sobre esto?
  • ¿Qué es un marco de prueba?

Si es posible, publique un código con ejemplos para aclarar las ideas.

¡Cualquier ayuda sobre este tema es muy bienvenida! Gracias.


Bueno, por lo general, hay tres tipos de pruebas. Pruebas unitarias, pruebas del sistema y pruebas de control de calidad. Las pruebas unitarias, como su nombre lo indica, prueban unidades pequeñas: funciones y clases separadas.

Para todos los entornos de desarrollo modernos, existen marcos de pruebas unitarias. Hay Nunit para .net, así como el marco de prueba de unidades MS en Visual Studio, CPPUnit para C ++, JUnit, etc. Todo por una cosa: conectarse a partes de su programa, ejecutar sus scripts predefinidos e informar de errores.

CPPUnit, por ejemplo, se basa en macros como CPPUNIT_ASSERT_EQUAL, destinado a ser utilizado como algo así: CPPUNIT_ASSERT_EQUAL (sum (arr), 17). Y diría si no es igual, en cuyo caso la prueba se considerará fallida.

Se supone que debes desarrollar las pruebas para cada función, y después de eso, no tienes miedo de cambiar y optimizar el código. En general, se lo denomina "repetibilidad": capacidad de realizar una acción compleja, como una prueba completa de toda la base de código, con un solo clic.

Se requieren pruebas unitarias para cada desarrollo de software moden, porque la experiencia muestra que mejoran la velocidad de desarrollo. También se sugiere que el código de prueba unitario pueda servir como una especie de "documentación" para la biblioteca.

Las pruebas del sistema son pruebas automatizadas de mayor funcionalidad de alto nivel. La idea de las pruebas del sistema es proporcionar una entrada limpia (como bases de datos, entradas del usuario, etc.) para probar todo, validando la salida contra los resutls predefinidos. Es esencial que la salida del sistema sea determinista y solo depende de la entrada. Cada vez que el sistema cambia, las pruebas del sistema también cambian.

TDD es una mala idea que suena bien, lo que sugiere que no debe desarrollar nada antes de implementar las pruebas automatizadas adecuadas, y luego escribir el código para satisfacer las pruebas. Se considera como una falla, porque los cambios en el diseño son inevitables durante el desarrollo, y un pequeño cambio de diseño generalmente causa cambios drásticos en las pruebas unitarias.

El control de calidad manual es el último y más importante tipo de prueba de software. La idea es preparar un plan de prueba, que se realiza durante las fases de diseño y codificación, recopilar todas las ideas que los desarrolladores tuvieron durante la codificación de cada sentencia if, cómo hacer que esta instrucción if particular se ejecute a lo largo de la ruta de código menos esperada. El personal de control de calidad, que debe ser capaz de hacer todo lo que se pueda con el programa sin un entorno de desarrollo, puede seguir el procedimiento de prueba resultante y sus propias ideas para encontrar más errores.


Comencemos con lo obvio:

¿Cómo funcionan las pruebas? En el desarrollo impulsado por pruebas, primero piensas en la funcionalidad que deseas implementar y luego escribes una prueba para ello. En el ejemplo que dio de una función suma, es bastante obvio lo que debería hacer. A continuación, escribe una prueba que asegura que la suma funcionó.

Las pruebas unitarias deben ser tan livianas como sea posible para que pueda ejecutarlas cada vez que presione el botón de compilación. Cuando haga esto ahora en este ejemplo, su prueba fallará, porque aún no ha implementado una función de suma.

Ahora escribe la función real y continúa depurando e implementando hasta que pase la prueba. Entonces está seguro de haber implementado la función que deseaba.

Ahora, ¿cómo diseñarías tu prueba? No puedes probar todo, eso es imposible. Como ejemplo, digamos que debe tomar la entrada del usuario, debe validar. Entonces sería una cosa natural escribir al menos dos casos de prueba para ese código de validación: uno que asegure que la entrada válida sea analizada como tal. El segundo caso de prueba recibe una entrada no válida y usted se asegura de que falla, genera una excepción o el comportamiento que desee. Entonces, en este caso, es bueno tener una prueba positiva que se espera que pase y una prueba negativa que verifique si la entrada inválida no está validada.

¿Cuándo debería uno probar? Como mencioné antes, la prueba debería ser lo suficientemente liviana para que puedan ejecutarse en cada compilación. Y sí, ejecuta todos. Esto asegura que no se pierda una dependencia en su código que rompe cosas muy lejos del punto que editó.

¿Se puede probar algo? Bueno, generalmente los métodos que dependen de recursos externos son difíciles de probar. Lo que quiero decir con eso son bases de datos, conexiones de red o hardware y controladores específicos. Se puede hacer, pero luego tiene que configurar una configuración de prueba más grande.

Corrección de errores y pruebas Un escenario típico donde la prueba se vuelve realmente útil es si está exprimiendo errores. No literalmente, por supuesto. Si tiene un error que tiene que corregir, primero intente escribir una prueba para ello. Y luego arregla tu código hasta que pase tu prueba. A partir de este momento en esta prueba "vigila su código" para que este error nunca vuelva a aparecer.

¿Qué ganas al probar? En mi opinión, hay muchas cosas

  1. Código más modular y fácil de mantener porque tiene que ser comprobable
  2. Confianza. Tener una base de código ampliamente probada le da la confianza de que funciona como se espera y se mantiene así.
  3. Encuentra errores temprano. Esto significa que puedes arreglarlos más fácilmente.

Me cuesta un poco acostumbrarme al uso de las pruebas, pero creo que vale la pena. Especialmente si estás escribiendo bibliotecas de algún tipo.


Encontré el libro "JUnit Pocket Guide" de Kent Beck como una introducción excelente (y barata y compacta) a Unit Testing: el libro se divide aproximadamente en secciones sobre los méritos de la programación basada en pruebas y técnicas de prueba generales y luego entra en los detalles del marco JUnit (que él co-creó).

http://www.amazon.co.uk/JUnit-Pocket-Guide-Kent-Beck/dp/0596007434/ref=sr_1_7?ie=UTF8&s=books&qid=1276811600&sr=8-7

Con respecto a su solicitud de algunos ejemplos ilustrativos de Unit Testing; este JUnit Primer no está mal:

http://www.clarkware.com/articles/JUnitPrimer.html#testcase


Puedes dividir las pruebas en tres ramas grandes (en realidad hay más, pero si eres un principiante debes entender primero la base): Alfa, Beta, código de trabajo completo.

  1. En alpha, prueba cada valor individual para cada código.
  2. En versión beta, usted entrega la aplicación supuestamente funcional al mundo, para obtener retroalimentación de los evaluadores y mejorarla.
  3. Cuando su aplicación está funcionando, solo tiene que esperar el informe de error (siempre se produce) de un usuario que descubrió ese problema y lo solucionó con un parche.

Cuando desarrollo una función, ¿cómo debo probarla? Por ejemplo: cuando trabajo con una función de suma, ¿debo probar cada valor de entrada posible o solo algunos límites? ¿Qué tal pruebas de funciones con cadenas como parámetros?

En alfa tienes que pensar en TODAS las posibilidades con las que puedes marcar tu código. En el caso de una función sum (), son pocas, pero si está desarrollando, digamos una gran aplicación de servidor de base de datos, debe tener en cuenta cada posible entrada y manejar cada posible error, piense en el usuario final como un persona estúpida o incluso como un cracker malicioso.

En un gran programa, ¿tengo que probar cada pieza del código? Cuando ustedes programan ¿prueban cada código escrito?

Sí, deberías, Microsoft no. (capte la broma;))

¿Cómo funciona la prueba automatizada y cómo puedo probar una? ¿Cómo funcionan las herramientas para las pruebas automatizadas y qué hacen?

Ninguna automatización puede superar la inteligencia humana y un buen depurador (¡esa es la única herramienta que realmente necesita!)

He oído sobre pruebas unitarias. ¿Puedo tener una breve explicación sobre esto?

http://en.wikipedia.org/wiki/Unit_testing

¿Qué es un marco de prueba?

http://en.wikipedia.org/wiki/Test_automation_framework


Qué probar

Hay un par de conceptos realmente útiles que me ayudaron a resolver esto:

El particionamiento de equivalencia dice "Ejecutar la prueba en este contexto con estos eventos es equivalente a esta otra prueba aquí, así que no necesito hacer ambas cosas".

El análisis de límites dice: "Aquí está el punto en el que un cambio en el contexto o un evento diferente causa un resultado diferente, por lo que querré pruebas en ambos lados de este límite".

Pensar en esto realmente puede ayudar a minimizar el número de pruebas que necesita escribir.

Cuándo probar

Siempre pruebo manualmente mi código para asegurarme de que funciona. A menudo escribo una prueba de unidad adicional que cubre cada línea de código que estoy a punto de escribir. La prueba de unidad falla antes de escribir el código para hacerlo pasar. Si es algo que un usuario hará, entonces a menudo también escribo una prueba de aceptación o un escenario automatizado.

Pruebas automatizadas

Las pruebas automatizadas significan crear scripts o grabar una prueba para que no tenga que hacerlo manualmente; su secuencia de comandos o código lo hará por usted. Hay dos tipos de herramientas de automatización: dispositivos de prueba de aceptación BDD o legibles en inglés que le permiten escribir los scripts y envoltorios de automatización que le permiten automatizar más fácilmente. Por ejemplo, puede optar por utilizar GivWenZen o Fitnesse como accesorio y Selenium como su herramienta de automatización web.

Si tienes Visual Studio 2008+, puedes descargar el código fuente desde aquí y probar el escenario para verlo ejecutar:

http://code.google.com/p/wipflash/

Examen de la unidad

En su sentido más estricto, Unit Testing significa probar un elemento de código de forma aislada de todos los demás elementos de código. Usamos simulaciones en lugar de piezas reales de código que requiere nuestro Código bajo prueba. En realidad, a menudo somos pragmáticos con respecto a la naturaleza de las "unidades". Por ejemplo, no me burlo de los objetos de dominio.

Sin embargo, las pruebas unitarias en la forma en que lo usan la mayoría de la gente no se tratan realmente de pruebas. Principalmente es un mecanismo para lograr un diseño limpio y la separación de responsabilidades, porque te ves forzado a esto intentando probarlo.

Me gusta pensar en las pruebas unitarias como "escribir un ejemplo de cómo voy a usar el código que voy a escribir". El ejemplo pasa a residir en un marco de pruebas unitarias y ser ejecutable.

Marcos de prueba

  • Los marcos de pruebas de unidades lo ayudan a realizar muchas pruebas juntos.
  • Los marcos de prueba de aceptación lo ayudan a ejecutar un escenario más amplio y a menudo son legibles en inglés.
  • Los marcos de automatización generalmente se ubican debajo de sus marcos legibles en inglés y lo ayudan a interactuar con una aplicación.

¡Buena suerte!