iphone - test - Pruebas de iOS/Especificaciones TDD/BDD y Pruebas de integración y aceptación
que es bdd (8)
tl; dr
En Pivotal escribimos Cedar porque usamos y amamos Rspec en nuestros proyectos de Ruby. Cedar no está destinado a reemplazar o competir con OCUnit; está destinado a brindar la posibilidad de realizar pruebas de estilo BDD al Objetivo C, al igual que Rspec fue pionero 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 utilizar 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
La decisión entre dos marcos de prueba como Cedar y OCUnit (por ejemplo) se reduce a dos cosas: el estilo preferido y la 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 la tecnología o el lenguaje que usas. x Las pruebas de unidad de estilo unitario han existido durante mucho más tiempo que las pruebas de estilo BDD, pero esta última ha ganado rápidamente popularidad, en gran parte debido a Rspec.
La principal ventaja de las pruebas de estilo xUnit es su simplicidad y amplia adopción (entre los desarrolladores que escriben pruebas unitarias); casi cualquier idioma 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 cuando se comparan con el estilo xUnit: cómo estructura la prueba (o especificaciones) y la sintaxis para escribir sus aserciones. 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 determinada. 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 propósitos de esta respuesta usaré la sintaxis de 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 introducido un código de descuento; puede diferir si el artículo especificado no puede ser enviado por el método de envío seleccionado; etc. A medida que estas posibles condiciones se cruzan entre sí, se obtiene un número geométricamente creciente de contextos posibles; en xUnit-style testing, 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 individualmente, lo que encuentro hace que sea más fácil asegurarse de cubrir todos los casos, así como más fácil de 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 aserciones, que puede SECAR utilizando contextos de ejemplo compartidos.
La segunda diferencia principal entre los marcos de estilo BDD y los marcos de estilo xUnit, sintaxis de aserción (o "emparejador"), simplemente hace que el estilo de las especificaciones sea un poco más agradable; A algunas personas les gusta mucho, 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 por mucho más tiempo que Cedar y está integrado directamente en Xcode. Esto significa que es sencillo hacer un nuevo objetivo de prueba y, la mayoría de las veces, poner las pruebas en funcionamiento "simplemente funciona". Por otro lado, encontramos que en algunos casos, como ejecutar en un dispositivo iOS, hacer que las pruebas de OCUnit funcionen es casi imposible. La configuración de las especificaciones de Cedar requiere algo más de trabajo que las pruebas OCUnit, ya que usted mismo obtiene la biblioteca y el enlace (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 hacer que sus pruebas se ejecuten; Si cualquier prueba falla, tu compilación falla. Esto hace que el proceso de ejecución de las pruebas sea un paso más sencillo, 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 convirtieran en un ejecutable que usted ejecuta por separado por varias razones:
- Queríamos poder utilizar el depurador. Ejecuta las especificaciones de Cedar como si fuera a ejecutar cualquier otro ejecutable, para que pueda usar el depurador de la misma manera.
- Queríamos un sencillo registro de la consola en las pruebas. Puede usar NSLog () en las pruebas OCUnit, pero la salida se envía a la ventana de compilación donde debe desplegar el paso de compilación para poder 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 la compilación desde la línea de comando (o como parte de un proceso de CI) hace que la salida de prueba se mezcle con muchas otras compilaciones. Con fases de compilación y ejecución separadas, Cedar separa la salida para que la salida de prueba sea fácil de encontrar. El corredor de prueba Cedar predeterminado copia el estilo estándar de impresión "." para cada especificación de aprobación, "F" para especificaciones fallidas, etc. Cedar también tiene la capacidad de usar objetos informadores personalizados, por lo que puede obtener resultados de la forma que desee, con un poco de esfuerzo.
OCUnit es el marco oficial de pruebas de unidad para Objective C, y es compatible con Apple. Apple tiene básicamente recursos ilimitados, por lo que si quieren que se haga algo, se hará. Y, después de todo, esta es la caja de arena de Apple en la que estamos jugando. Sin embargo, la otra cara de esta moneda es que Apple recibe en el orden de un billón de solicitudes de soporte e informes de errores cada día. Son extraordinariamente buenos para manejarlos a todos, pero es posible que no puedan manejar los problemas que usted informa de inmediato, o en absoluto. Cedar es mucho más nuevo y está menos preparado 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 todo lo posible para ayudarlo. Además, siéntase libre de compartir el código de Github (github.com/pivotal/cedar) y agregar lo que crea que falta. Hacemos que nuestros frameworks de prueba sean de código abierto por una razón.
La ejecución de las pruebas OCUnit en dispositivos iOS puede ser difícil. Honestamente, no lo he intentado desde hace bastante tiempo, por lo que puede haber sido más fácil, pero la última vez que lo intenté simplemente no pude realizar pruebas OCUnit para que funcionara ninguna funcionalidad UIKit. 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 de unidad, 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 enfocaba principalmente en controlar mediante programación la interfaz de usuario en un dispositivo iOS. Decidimos específicamente no intentar que Cedar sea compatible con este tipo de especificaciones, ya que Apple estaba (en ese momento) a punto de anunciar la automatización.
¿Cuáles son las mejores tecnologías para usar en 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
Test::Unit Style
- OCUnit/SenTestingKit como se explica en la Guía de desarrollo de iOS: Aplicaciones de prueba de unidades y otras referencias de OCUnit .
- Ejemplos: iPhoneUnitTests , Three20
- CATCH
- GHUnit
- Google Toolbox para Mac: iPhone Unit Testing
Estilo RSpec
- Kiwi (que también viene con burlas y expectativas)
- Cedar
- Jasmine con UI Automation como se muestra en las especificaciones de pruebas de aceptación de iOS
Test de aceptación
Estilo Selenium
UI Automation (funciona en el dispositivo)
- Guía de instrumentos de automatización de la interfaz de usuario
- Documentación de referencia de UI Automation
- Tuneup js - biblioteca genial para usar con UIAutomation.
Capturar acciones de interfaz de usuario en secuencias de comandos de automatización
Es posible usar Cucumber (escrito en JavaScript) para controlar la automatización de la interfaz de usuario. Este sería un gran proyecto de código abierto. Luego, podríamos escribir a Gherkin para ejecutar las pruebas de automatización de la interfaz de usuario. Por ahora, solo escribiré a Gherkin como comentarios.
ACTUALIZACIÓN: ¡ Zucchini Framework parece combinar Cucumber y UI Automation! :)
Publicaciones antiguas del blog:
UISpec con UISpecRunner
Estilo de Cucumber
Frank e iCuke (basado en el Cucumber iCuke iPhone Talk )
- El Frank Google Group tiene mucha más actividad que el iCuke Google Group .
- Frank se ejecuta tanto en el dispositivo como en el simulador, mientras que iCuke solo se ejecuta en el simulador.
- Frank parece tener un conjunto más amplio de definiciones de pasos que las definiciones de pasos de iCuke . Y, Frank también tiene un compendio de definición de pasos en su wiki .
- Propuse que fusionáramos iCuke y Frank (similar a cómo Merb y Rails se fusionaron) ya que tienen el mismo objetivo común: Pepino para iOS.
Zucchini Framework usa la sintaxis de pepino para escribir pruebas y usa CoffeeScript para las definiciones de los pasos.
Adiciones
- OCMock para mocking
- OCHamcrest y / o Expecta para las expectativas.
Conclusión
Bueno, obviamente, no hay una respuesta correcta a esta pregunta, pero esto es lo que estoy eligiendo para ir en este momento:
Para pruebas de unidad, solía usar OCUnit/SenTestingKit en XCode 4. Es simple y sólido. Pero, prefiero el lenguaje de BDD sobre TDD ( ¿Por qué es mejor RSpec que Test :: Unit ?) Porque nuestras palabras crean nuestro mundo. Así que ahora, uso Kiwi con la finalización / autocompletado del código ARC y Kiwi . Prefiero Kiwi sobre Cedar porque está construido sobre OCUnit y viene con emparejadores y simulacros de estilo RSpec. ACTUALIZACIÓN: Ahora estoy investigando OCMock porque, en la actualidad, Kiwi no admite el uso de objetos puenteados sin cargo .
Para las pruebas de aceptación, uso UI Automation porque es increíble. Te permite grabar cada caso de prueba, haciendo que las pruebas de escritura sean automáticas. Además, Apple lo desarrolla, y así tiene un futuro prometedor. También funciona en el dispositivo y en Instruments, lo que permite otras funciones interesantes, como mostrar fugas de memoria. Desafortunadamente, con UI Automation, no sé cómo ejecutar el código Objective-C, pero con Frank & iCuke puedes hacerlo. Por lo tanto, solo UIButton
cosas de Objective-C de nivel inferior con pruebas unitarias, o crearé UIButton
s solo para la configuración de compilación TEST
, que al hacer clic, ejecutará el código de Objective-C.
¿Qué soluciones utilizas?
preguntas relacionadas
- ¿Hay alguna solución BDD que actualmente funcione bien con iOS4 y Xcode4?
- SenTestingKit (integrado con XCode) versus GHUnit en XCode 4 para pruebas de unidad?
- Probando código asíncrono en iOS con OCunit
- SenTestingKit en Xcode 4: ¿Pruebas asíncronas?
- ¿Cómo funcionan las pruebas unitarias en el iPhone?
Actualmente utilizo specta para rspec como configuraciones y es su compañero (como se mencionó anteriormente) Expecta que tiene un montón de increíbles opciones de coincidencia.
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; Ejecución automática de pruebas de UIAutomation con instrumentos actualmente no es posible, por ejemplo.
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 deseando probar iCuke, ya que promete ser una configuración liviana, y puedes Utilice los rieles que prueban la bondad, como RSpec y Cucumber.
Gran lista
Encontré otra solución interesante para las aplicaciones de iOS de prueba de interfaz de usuario.
Se basa en UIAutomation
. El marco le permite escribir escenarios centrados en la pantalla en estilo de 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 la captura de pantalla. Suena inflexible, pero le proporciona un buen informe HTML, con una comparación de pantalla resaltada y puede proporcionar máscaras que definen las regiones que desea tener una afirmación exacta de píxeles.
Cada pantalla debe describirse en CoffeScript
y la herramienta en sí misma está escrita en ruby. Es una especie de pesadilla políglota, pero la herramienta proporciona una buena abstracción para la UIAutomation
de la UIAutomation
y, cuando se describen las pantallas, es manejable incluso para las personas de control de calidad.
Para el desarrollo guiado por pruebas, me gusta usar GHUnit , es muy fácil de configurar y también funciona muy bien para la depuración.
Resulta que me gusta mucho OCDSpec2 pero estoy parcializado, escribí OCDSpec y contribuyo al segundo.
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.
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.