2009-06-22 8 views
6

Quiero escribir una prueba unitaria de solo la parte de la GUI de mi aplicación Cocoa.¿Cómo puedo escribir una prueba de unidad automática de una GUI en Xcode?

En la prueba de la unidad de libro de texto, hay un marco de prueba y un caso de prueba que llama a la unidad bajo prueba. Todo el código debajo de esa unidad es burlado. Entonces, tanto la entrada como la salida son controladas y monitoreadas; solo se prueba el código en la unidad bajo prueba.

Quiero hacer lo mismo en la unidad bajo prueba es mi GUI:
1) Establecer algún tipo de marco en el que puedo escribir código que va a manipular e inspeccionar controles GUI.
2) Conecte los controles de mi GUI a los simulacros de mi código real, no a las instancias reales.
3) Ejecute la prueba, que manipula los controles y luego verifica el objeto falso para ver si se invocaron los métodos correctos con los parámetros correctos y verifica si las respuestas del objeto simulado causan los cambios correctos en los widgets .

¿Alguien que hace esto? ¿Si es así, cómo? ¿Alguna idea sobre cómo podría hacer esto?

Gracias,

Pat

(Editar) para dar un ejemplo muy específico, quiero:
1) Escribir un caso de prueba que se seleccione la opción de menú 'MiMenú' -> 'myItem '. En este caso de prueba, quiero verificar que el método [AppDelegate doMyItem] se llame exactamente una vez y que no se llame a ningún otro método en AppDelegate.
2) Genera un objeto simulado de AppDelegate. (Sé cómo hacer esto)
3) De alguna manera (moviendo manualmente aquí) enlace mi aplicación para que una instancia simulada de AppDelegate esté vinculada en lugar de la real.
4) Ejecute la prueba. Míralo fallar porque 1) aún no he creado MyMenu. 2) Todavía no he creado MyItem. 3) No he realizado el trabajo del IB para conectar MyItem a [AppDelegate doMyItem], o 4) porque todavía no he escrito el método 'doMyItem'.
5) Repare los cuatro problemas anteriores (uno a la vez si me siento realmente pedante ese día).
6) Ejecute la prueba nuevamente y obsérvela.

¿Esto aclara la pregunta?

Respuesta

1

Aquí hay un par de formas populares de hacerlo en general (debería funcionar con la mayoría de los lenguajes compatibles con cacao, si no todos).

1 - crear una interfaz de devolución de llamada. Una de las entradas al crear sus elementos GUI es una implementación de esta interfaz. Cuando hay una interacción del usuario, el elemento GUI llama a una función de actualización en esa interfaz. Tener una implementación real y una implementación de prueba.

2 - Use controladores de eventos. Registre todos sus elementos GUI con uno o más controladores de eventos, y haga que la GUI genere eventos en la interacción del usuario. Tener una interfaz de controlador de eventos con dos implementaciones, otra vez una para uso real y otra para pruebas.

Edit: whoops, requisito # 1 perdido. Nunca he hecho esto con controles específicos de OSX, pero en general hay dos enfoques.

1 - crea una secuencia de comandos o una aplicación que genera una entrada similar a la del usuario. Tiene el inconveniente de no ser fácil inspeccionar realmente la GUI. En su lugar, necesita generar buenos casos de prueba para asegurarse de que todo lo que debería estar allí es, y no hay nada extra.

2 - crear una interfaz con una implementación de prueba que reemplaza la capa de procesamiento e interfaz. Esto es más fácil con bibliotecas como SDL o directFB y menos con cosas como la API OSX, Win32 API, etc.

Editar: responder a la edición en cuestión.

En el caso de tu ejemplo, usando un separadas de aplicaciones de prueba y controladores de eventos Así es como miraría:

Su aplicación de prueba es una aplicación simple o script que inicia su interfaz gráfica de usuario y genera ratón/teclado eventos basados ​​en archivos de entrada. Como ya he dicho, nunca hice esto en OSX (solo QNX). Con un poco de suerte, podrás generar eventos de mouse y teclado con la API, pero tendrás que preguntarle a alguien más si es posible.

Por lo tanto, cree una entrada para su caso de prueba. La aplicación de prueba analizará esto para saber qué hacer. Puede ser un XML simple como este:

<testcase name="blah"><mouseevent x="120" y="175" type="click"/></testcase> 

o cualquiera que sea la secuencia del mouse en realidad.

Cuando la secuencia de comandos ejecuta ese comando, hará clic con el mouse en ese botón. Su controlador de eventos se dará cuenta de esto. Pero ahora deberías ejecutar tu aplicación con una bandera de prueba o un somesuch para que realmente esté usando el controlador de eventos de prueba. En lugar de hacer lo que normalmente hace su aplicación, el controlador de eventos de prueba puede realizar alguna acción personalizada. Por ejemplo, puede hacer algunas de las acciones normales (aún necesita la GUI para responder) y luego enviar un mensaje (a través de un socket, un conducto, lo que sea) a su aplicación de prueba.

Su aplicación de prueba recogerá este mensaje y lo comparará con lo que espera ver. Así que ahora tal vez su caso_prueba XML es el siguiente:

<testcase name="blah"> 
    <mouseevent x="120" y="175" type="click"/> 
    <response>doMyItem() called</response> 
</testcase> 

Si la respuesta generada desde el controlador de eventos es diferente, entonces el caso de la prueba ha fallado. Puede imprimir la respuesta real para ayudar en la depuración.

+0

Hola Patros, Para su segundo # 1, no acabo de ver lo que significa 'generar entrada de usuario como'. ¿Puedes darme un ejemplo? Gracias, Pat –

+0

Simplemente significa generar los eventos de teclado y mouse que desea ver. Puede hacerlo envolviendo las clases UI nativas y secuestrando sus eventos, posiblemente accediendo a la API o escribiendo controladores personalizados. – patros

3

dos principios, dos enlaces:

  • que la vista tan tontos como sea posible, con el patrón passive view: esto hace más fácil interfaz gráfica de usuario para probar
  • : La confianza puesta en práctica de cacao de botones, menús, .. . Pero verifique que target and action estén conectados correctamente, que bindings sean los esperados.
1

¿Has consultado el marco de accesibilidad? Debe permitir que una aplicación inspeccione la interfaz de usuario de otra aplicación y genere eventos de interacción similares a los del usuario.

Accessibility Overview

Cuestiones relacionadas