2008-09-16 9 views
8

Estoy convencido de this presentation y otros comentarios aquí en el sitio que necesito aprender para probar la unidad. También me doy cuenta de que ha habido muchas preguntas sobre qué pruebas unitarias hay aquí. Cada vez que voy a considerar cómo se debe hacer en la aplicación en la que estoy trabajando actualmente, me alejo confundido. Es una aplicación de aplicación xulrunner, y gran parte de la lógica está basada en eventos: cuando un usuario hace clic aquí, esta acción tiene lugar.¿Cómo comprueba una unidad las secciones de código que son procesales o basadas en eventos?

A menudo, los ejemplos que veo para las pruebas son clases de prueba: crean una instancia de un objeto, le dan datos falsos y luego verifican las propiedades del objeto. Eso tiene sentido para mí, pero ¿qué pasa con las piezas no orientadas a objetos?

This guy mentioned que la prueba de unidad basada en GUI es difícil en la mayoría de los marcos de prueba, quizás ese es el problema. La presentación vinculada arriba menciona que cada prueba solo debe tocar una clase, un método a la vez. Eso parece descartar lo que trato de hacer.

Por lo tanto, la pregunta es: ¿cómo puede una unidad probar el código de procedimiento o basado en eventos? Proporcione un enlace a una buena documentación, o explíquelo usted mismo.

Por un lado, también tengo el desafío de no haber encontrado un marco de prueba que esté configurado para probar aplicaciones xulrunner, parece que las herramientas aún no están desarrolladas. Me imagino que esto es más periférico que mi comprensión de los conceptos, escribir código comprobable, aplicar pruebas unitarias.

Respuesta

5

La idea de la prueba unitaria es probar pequeñas secciones de código con cada prueba. En un sistema basado en eventos, una forma de prueba de unidad que podría hacer sería probar cómo responden los manejadores de eventos a varios eventos. Por lo tanto, su prueba unitaria puede establecer un aspecto de su programa en un estado específico, luego llamar directamente al método de escucha de eventos y finalmente probar el estado posterior de su programa.

Si usted planea en la unidad de prueba de un sistema basado en eventos, que le hará la vida mucho más fácil para usted si se utiliza el patrón de inyección de dependencias y lo ideal sería llegar hasta el final y el uso de la inversión de control (ver http://martinfowler.com/articles/injection.html y http://msdn.microsoft.com/en-us/library/aa973811.aspx para más detalles de estos patrones)

(gracias a pc1oad1etter por señalar que había estropeado los enlaces)

+0

En realidad, se ha vinculado al mismo artículo dos veces allí - ¿tenía intención de hacerlo? – pc1oad1etter

+0

Creo que estos dos conceptos (DI e IoC) pasan por alto. No creo haber aprendido sobre patrones de diseño en la escuela o en ninguno de mis trabajos. – pc1oad1etter

+3

Tampoco aprendí acerca de los que están en la escuela. He aprendido sobre ellos en el campo. No dejes que tu fondo te constriña. No obtendrá una buena comprensión de estos conceptos sin darle una oportunidad (en la implementación). –

1

El problema es que la "programación basada en eventos" vincula demasiada lógica a los eventos. La forma en que debe diseñarse un sistema de este tipo es que debe existir un subsistema que genere eventos (y puede escribir pruebas para asegurarse de que estos eventos se realicen en el orden correcto). Y debería haber otro subsistema que se ocupe solo de administrar, digamos, el estado de una forma. Y puede escribir una prueba unitaria que verificará que, dadas las entradas correctas (es decir, los eventos que se están levantando), establecerá el estado del formulario en los valores correctos.

Más allá de eso, el controlador de eventos real que se genera desde el componente 1 y llama al comportamiento en el componente 2 es solo una prueba de integración que puede realizar manualmente una persona de QA.

2

Al principio me gustaría probar este tipo de eventos:

private bool fired; 

private void HandlesEvent(object sender, EventArgs e) 
{ 
    fired = true; 
} 

public void Test() 
{ 
    class.FireEvent += HandlesEvent; 
    class.PErformEventFiringAction(null, null); 

    Assert.IsTrue(fired); 
} 

y luego me descubierto RhinoMocks. RhinoMocks es un framework que crea objetos simulados y también maneja pruebas de eventos. También puede ser útil para sus pruebas de procedimiento.

0

Un enfoque que he encontrado útil para el código de procedimiento es usar TextTest. No se trata tanto de pruebas unitarias, sino que le ayuda a realizar pruebas de regresión automáticas. La idea es que su aplicación escriba un registro y luego use texttest para comparar el registro antes y después de los cambios.

0

Véase el Working Effectively with Legacy Code ligado frecuentemente. Consulte las secciones tituladas "Mi aplicación son todas las llamadas a la API" y "Mi proyecto no está orientado a objetos. ¿Cómo realizo cambios seguros?".

En C/C++ world (mi experiencia), la mejor solución en la práctica es utilizar el enlazador "seam" y vincular contra dobles de prueba para todas las funciones llamadas por la función bajo prueba. De esta forma, no cambia el código heredado, pero aún puede probarlo de forma aislada.

+0

Pedí el libro, espero que sea tan bueno como todos dicen. – pc1oad1etter

2

Respondiendo a mi propia pregunta aquí, pero encontré un artículo que explica el problema, y ​​hace un recorrido de un ejemplo simple - Agile User Interface Development. El código y las imágenes son grandes, y aquí es un fragmento que muestra la idea:

gurús ágiles como Kent Beck y David Astels sugieren la construcción de la interfaz gráfica de usuario manteniendo los objetos de vista muy fina, y probar el capas "debajo de la superficie ". Este modelo de "objeto inteligente/thin view" es análogo al paradigma de cliente-servidor familiar y , pero se aplica al desarrollo de elementos de GUI individuales . La separación del contenido y la presentación mejoran el diseño del código, haciéndolo más modular y comprobable. Cada componente de la interfaz de usuario se implementa como un objeto inteligente , que contiene el comportamiento de la aplicación que debe ser probado, pero sin código de presentación GUI. Cada objeto inteligente tiene una clase de vista delgada correspondiente que solo contiene comportamiento genérico de la GUI. Con este modelo de diseño , la construcción de GUI se vuelve susceptible a TDD.

1

Su pregunta no indica su lenguaje de programación de elección, pero el mío es C# así que ejemplificaré el uso de eso. Sin embargo, este es solo un refinamiento sobre la respuesta de Gilligans al usar delegados anónimos para alinear su código de prueba. Estoy a favor de que las pruebas sean lo más legibles posible, y para mí eso significa todo el código de prueba dentro del método de prueba;

// Arrange 
var car = new Car(); 
string changedPropertyName = ""; 
car.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) 
         { 
          if (sender == car) 
            changedPropertyName = e.PropertyName; 
         }; 

// Act 
car.Model = "Volvo"; 

// Assert 
Assert.AreEqual("Model", changedPropertyName, 
    "The notification of a property change was not fired correctly."); 

La clase Estoy probando aquí implementa la interfaz INotifyPropertyChanged y por lo tanto un evento NotifyPropertyChanged debe elevarse cada vez que ha cambiado el valor de una propiedad.

Cuestiones relacionadas