Pruebas / especificaciones de iOS TDD / BDD y pruebas de integración y aceptación

229

¿Cuáles son las mejores tecnologías para el desarrollo basado en el comportamiento en el iPhone? ¿Y cuáles son algunos proyectos de ejemplo de código abierto que demuestran el uso racional de estas tecnologías? Aquí hay algunas opciones que he encontrado:


Examen de la unidad

Prueba :: Estilo de la unidad

  1. OCUnit / SenTestingKit como se explica en la Guía de desarrollo de iOS: Aplicaciones de prueba de unidades y otras referencias de OCUnit .
  2. CAPTURA
  3. GHUnit
  4. Google Toolbox para Mac: pruebas de unidad de iPhone

Estilo RSpec

  1. Kiwi (que también viene con burlas y expectativas)
  2. Cedro
  3. Jasmine con UI Automation como se muestra en las especificaciones de 'Pruebas de aceptación de iOS'

Test de aceptación

Estilo selenio

  1. Automatización de la interfaz de usuario (funciona en el dispositivo)

    ACTUALIZACIÓN: Zucchini Framework parece combinar Cucumber & UI Automation. :)

    Publicaciones de blog antiguas:

  2. UISpec con UISpecRunner

  3. FoneMonkey

Estilo de pepino

  1. Frank e iCuke (basado en el Cucumber conoce la charla de iPhone )

  2. KIF (mantenerlo funcional) por cuadrado

  3. Zucchini Framework usa la sintaxis de Pepino para escribir pruebas y usa CoffeeScript para las definiciones de pasos.

Adiciones

Conclusión

Bueno, obviamente, no hay una respuesta correcta a esta pregunta, pero esto es a lo que elijo ir actualmente:

Para las pruebas unitarias, solía usar OCUnit / SenTestingKit en XCode 4. Es simple y sólido. Pero, prefiero el lenguaje de BDD sobre TDD ( ¿Por qué es RSpec mejor que Test :: Unit ?) Porque nuestras palabras crean nuestro mundo. Entonces, ahora uso Kiwi con ARC y Kiwi code complete / autocompletion . Prefiero Kiwi sobre Cedar porque está construido en la parte superior de OCUnit y viene con matizadores y trozos de estilo RSpec. ACTUALIZACIÓN: ahora estoy investigando OCMock porque, actualmente, Kiwi no admite tropezar objetos puenteados sin cargo .

Para las pruebas de aceptación, utilizo UI Automation porque es increíble. Le permite grabar cada caso de prueba, haciendo que las pruebas de escritura sean automáticas. Además, Apple lo desarrolla, por lo que tiene un futuro prometedor. También funciona en el dispositivo y en Instrumentos, lo que permite otras características interesantes, como mostrar pérdidas de memoria. Desafortunadamente, con UI Automation, no sé cómo ejecutar el código Objective-C, pero con Frank e iCuke puedes. Entonces, solo probaré las cosas de Objective-C de nivel inferior con pruebas unitarias, o crearé UIButtons solo para la TESTconfiguración de compilación , que cuando se hace clic, ejecutará el código de Objective-C.

¿Qué soluciones usas?

preguntas relacionadas

mattdipasquale
fuente
1
Sé por lo menos hace unos meses que los laboratorios fundamentales estaban usando cedro. (um, supongo que es obvio dado que está en su cuenta de Github). Con el apoyo de una tienda como esa, esa sería mi elección.
Jed Schneider el
1
Ese es un buen punto. Pero, de nuevo, Apple sugeriría usar su marco de prueba de unidad, no Cedar, ¿no? Entonces, es Pivotal Vs. Manzana. ¿Con qué ir?
ma11hew28
2
Escribí una publicación comparando la información de Frank, KIF y UIA que puede ser de interés para los lectores de este hilo sgleadow.github.com/blog/2011/10/26/…
Stew

Respuestas:

53

tl; dr

En Pivotal escribimos Cedar porque usamos y amamos a Rspec en nuestros proyectos Ruby. Cedar no está destinado a reemplazar o competir con OCUnit; está destinado a brindar la posibilidad de pruebas de estilo BDD al Objetivo C, al igual que Rspec fue pionera en las pruebas de estilo BDD en Ruby, pero no ha eliminado Test :: Unit. Elegir uno u otro es en gran medida una cuestión de preferencias de estilo.

En algunos casos, diseñamos Cedar para superar algunas deficiencias en la forma en que OCUnit funciona para nosotros. Específicamente, queríamos poder usar el depurador en las pruebas, ejecutar pruebas desde la línea de comandos y en las compilaciones de CI, y obtener resultados de texto útiles de los resultados de las pruebas. Estas cosas pueden ser más o menos útiles para usted.

Respuesta larga

Decidir entre dos marcos de prueba como Cedar y OCUnit (por ejemplo) se reduce a dos cosas: estilo preferido y facilidad de uso. Comenzaré con el estilo, porque eso es simplemente una cuestión de opinión y preferencia; la facilidad de uso tiende a ser un conjunto de compensaciones.

Las consideraciones de estilo trascienden qué tecnología o lenguaje usa. Las pruebas unitarias de estilo xUnit han existido durante mucho más tiempo que las pruebas de estilo BDD, pero esta última ha ganado popularidad rápidamente, en gran parte debido a Rspec.

La principal ventaja de las pruebas de estilo xUnit es su simplicidad y su amplia adopción (entre los desarrolladores que escriben pruebas unitarias); Casi cualquier lenguaje en el que pueda considerar escribir código tiene un marco de estilo xUnit disponible.

Los marcos de estilo BDD tienden a tener dos diferencias principales en comparación con el estilo xUnit: cómo estructura la prueba (o las especificaciones) y la sintaxis para escribir sus afirmaciones. Para mí, la diferencia estructural es el principal diferenciador. Las pruebas xUnit son unidimensionales, con un método de configuración para todas las pruebas en una clase de prueba dada. Las clases que probamos, sin embargo, no son unidimensionales; a menudo necesitamos probar acciones en varios contextos diferentes, potencialmente conflictivos. Por ejemplo, considere una clase ShoppingCart simple, con un método addItem: (para los fines de esta respuesta, usaré la sintaxis Objective C). El comportamiento de este método puede diferir cuando el carrito está vacío en comparación con cuando el carrito contiene otros artículos; puede diferir si el usuario ha ingresado un código de descuento; puede diferir si el elemento especificado puede ' t ser enviado por el método de envío seleccionado; etc. Como estas posibles condiciones se cruzan entre sí, terminas con un número geométricamente creciente de contextos posibles; en las pruebas de estilo xUnit, esto a menudo conduce a muchos métodos con nombres como testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. La estructura de los marcos de estilo BDD le permite organizar estas condiciones de forma individual, lo que creo que hace que sea más fácil asegurarse de que cubra todos los casos, así como también es más fácil encontrar, cambiar o agregar condiciones individuales. Como ejemplo, usando la sintaxis de Cedar, el método anterior se vería así: en las pruebas de estilo xUnit, esto a menudo conduce a muchos métodos con nombres como testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. La estructura de los marcos de estilo BDD le permite organizar estas condiciones de forma individual, lo que creo que hace que sea más fácil asegurarse de que cubra todos los casos, así como también es más fácil encontrar, cambiar o agregar condiciones individuales. Como ejemplo, usando la sintaxis de Cedar, el método anterior se vería así: en las pruebas de estilo xUnit, esto a menudo conduce a muchos métodos con nombres como testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. La estructura de los marcos de estilo BDD le permite organizar estas condiciones de forma individual, lo que creo que hace que sea más fácil asegurarse de que cubra todos los casos, así como también es más fácil encontrar, cambiar o agregar condiciones individuales. Como ejemplo, usando la sintaxis de Cedar, el método anterior se vería así:

describe(@"ShoppingCart", ^{
    describe(@"addItem:", ^{
        describe(@"when the cart is empty", ^{
            describe(@"with no discount code", ^{
                describe(@"when the shipping method applies to the item", ^{
                    it(@"should add the item to the cart", ^{
                        ...
                    });

                    it(@"should add the full price of the item to the overall price", ^{
                        ...
                    });
                });

                describe(@"when the shipping method does not apply to the item", ^{
                    ...
                });
            });

            describe(@"with a discount code", ^{
                ...
            });
        });

        describe(@"when the cart contains other items, ^{
            ...
        });
    });
});

En algunos casos, encontrará contextos que contienen los mismos conjuntos de afirmaciones, que puede SECAR utilizando contextos de ejemplo compartidos.

La segunda diferencia principal entre los marcos de estilo BDD y los marcos de estilo xUnit, la sintaxis de aserción (o "matcher"), simplemente hace que el estilo de las especificaciones sea algo más agradable; a algunas personas realmente les gusta, a otras no.

Eso lleva a la cuestión de la facilidad de uso. En este caso, cada marco tiene sus pros y sus contras:

  • OCUnit ha existido mucho más tiempo que Cedar, y está integrado directamente en Xcode. Esto significa que es sencillo crear un nuevo objetivo de prueba y, la mayoría de las veces, hacer que las pruebas funcionen "simplemente funciona". Por otro lado, descubrimos que en algunos casos, como ejecutarse en un dispositivo iOS, hacer que las pruebas de OCUnit funcionen era casi imposible. La configuración de las especificaciones de Cedar requiere más trabajo que las pruebas de OCUnit, ya que usted tiene la biblioteca y el enlace en sí mismo (nunca es una tarea trivial en Xcode). Estamos trabajando para facilitar la configuración, y cualquier sugerencia es más que bienvenida.

  • OCUnit ejecuta pruebas como parte de la compilación. Esto significa que no necesita ejecutar un ejecutable para ejecutar sus pruebas; Si alguna prueba falla, su compilación falla. Esto hace que el proceso de ejecutar pruebas sea un paso más simple, y la salida de prueba va directamente a la ventana de salida de compilación, lo que hace que sea fácil de ver. Elegimos que las especificaciones de Cedar se integren en un ejecutable que se ejecuta por separado por varias razones:

    • Queríamos poder usar el depurador. Ejecuta las especificaciones de Cedar tal como lo haría con cualquier otro ejecutable, por lo que puede usar el depurador de la misma manera.
    • Queríamos un inicio de sesión de consola fácil en las pruebas. Puede usar NSLog () en las pruebas de OCUnit, pero el resultado va a la ventana de compilación donde debe desplegar el paso de compilación para leerlo.
    • Queríamos informes de prueba fáciles de leer, tanto en la línea de comandos como en Xcode. Los resultados de OCUnit aparecen muy bien en la ventana de compilación en Xcode, pero al compilar desde la línea de comandos (o como parte de un proceso de CI) se obtienen resultados de prueba entremezclados con muchos otros resultados de compilación. Con fases separadas de construcción y ejecución, Cedar separa la salida para que la salida de prueba sea fácil de encontrar. El corredor de prueba de Cedar predeterminado copia el estilo estándar de impresión "." para cada especificación que pasa, "F" para especificaciones que fallan, etc. Cedar también tiene la capacidad de usar objetos de reportero personalizados, por lo que puede obtener resultados de la forma que desee, con un poco de esfuerzo.
  • OCUnit es el marco oficial de pruebas unitarias para Objective C y es compatible con Apple. Apple tiene recursos básicamente ilimitados, por lo que si quieren que se haga algo, se hará. Y, después de todo, este es el sandbox de Apple en el que estamos jugando. Sin embargo, la otra cara de esa moneda es que Apple recibe del orden de miles de millones de solicitudes de asistencia e informes de errores cada día. Son notablemente buenos para manejarlos a todos, pero es posible que no puedan manejar los problemas que informa de inmediato, o en absoluto. Cedar es mucho más nuevo y menos horneado que OCUnit, pero si tiene preguntas o problemas o sugerencias, envíe un mensaje a la lista de correo de Cedar ([email protected]) y haremos lo que podamos para ayudarlo. Además, siéntase libre de bifurcar el código de Github (github.com/pivotal/cedar) y agregar lo que crea que falta.

  • Ejecutar pruebas OCUnit en dispositivos iOS puede ser difícil. Honestamente, no lo he intentado durante bastante tiempo, por lo que puede haber sido más fácil, pero la última vez que lo intenté simplemente no pude obtener pruebas de OCUnit para que ninguna funcionalidad UIKit funcione. Cuando escribimos Cedar nos aseguramos de que pudiéramos probar el código dependiente de UIKit tanto en el simulador como en los dispositivos.

Finalmente, escribimos Cedar para pruebas unitarias, lo que significa que no es realmente comparable con proyectos como UISpec. Ha pasado bastante tiempo desde que intenté usar UISpec, pero entendí que se centraba principalmente en conducir la UI mediante programación en un dispositivo iOS. Decidimos específicamente no intentar que Cedar admita este tipo de especificaciones, ya que Apple estaba (en ese momento) a punto de anunciar la automatización UIA.

Adam Milligan
fuente
Gracias por la respuesta completa. Voy a leer el libro RSpec y probaré Ceder. Moví UISpec a la sección Selenium y agregué UIAutomation allí también. Estoy leyendo tu publicación de blog sobre UIAutomation. En realidad, Frank parece mucho más simple y legible, además de estar mejor documentado, así que estoy pensando en comenzar con eso. Solo espero que sea tan poderoso como la automatización UIA. Usted dice que UIAutomation puede probar problemas del ciclo de vida. Me pregunto si iCuke también puede ...
ma11hew28
8

Voy a tener que lanzar a Frank a la mezcla de pruebas de aceptación. Esta es una adición bastante nueva, pero ha funcionado excelente para mí hasta ahora. Además, en realidad se está trabajando activamente, a diferencia de icuke y los demás.

raidfive
fuente
5

Para el desarrollo basado en pruebas, me gusta usar GHUnit , es muy fácil de configurar y funciona muy bien para la depuración también.

Richard J. Ross III
fuente
Gracias. Lo vi pero olvidé mencionarlo.
ma11hew28
PLus 1 para GHUnit. Lo usé mucho con OCMock. Es muy fácil de configurar, extender y funciona de manera muy confiable.
drekka
4

Gran lista!

Encontré otra solución interesante para probar aplicaciones de IU en iOS.

Marco de calabacín

Se basa en UIAutomation. El marco le permite escribir escenarios centrados en la pantalla en estilo pepino. Los escenarios se pueden ejecutar en el simulador y en el dispositivo desde una consola (es compatible con CI).

Las afirmaciones están basadas en capturas de pantalla. Suena inflexible, pero le brinda un buen informe HTML, con una comparación de pantalla resaltada y puede proporcionar máscaras que definen las regiones en las que desea tener una aserción exacta de píxeles.

Cada pantalla tiene que describirse CoffeScripty la herramienta en sí misma está escrita en rubí. Es una especie de pesadilla políglota, pero la herramienta proporciona una buena abstracción UIAutomationy, cuando se describen las pantallas, es manejable incluso para una persona de control de calidad.

usuario1129998
fuente
¡Apretado! Gracias. Agregué esto a la pregunta anterior.
ma11hew28
2

Elegiría iCuke para las pruebas de aceptación y Cedar para las pruebas unitarias. UIAutomation es un paso en la dirección correcta para Apple, pero las herramientas necesitan un mejor soporte para una integración continua; Por ejemplo, actualmente no es posible ejecutar automáticamente pruebas de automatización UIA con instrumentos.

SamCee
fuente
1

GHUnit es bueno para pruebas unitarias; para las pruebas de integración, he usado UISpec con cierto éxito (github fork aquí: https://github.com/drync/UISpec ), pero estoy ansioso por probar iCuke, ya que promete ser una configuración liviana, y puedes use los rieles para probar la bondad, como RSpec y Cucumber.

Robar
fuente
1

Actualmente uso Specta para rspec como configuraciones y que la pareja (como se mencionó anteriormente) Expecta que tiene toneladas de opciones de concordancia de impresionantes.

Keith Smiley
fuente
0

Me gusta mucho OCDSpec2 pero soy parcial, escribí OCDSpec y contribuyo a la segunda.

Es muy rápido incluso en iOS, en parte porque está construido desde cero en lugar de ser puesto encima de OCUnit. También tiene una sintaxis RSpec / Jasmine.

https://github.com/ericmeyer/ocdspec2

Eric Smith
fuente