SlideShare una empresa de Scribd logo
1 de 49
Descargar para leer sin conexión
5. Testing, protocols & extensions
ÍNDICE
5. Testing, protocols & extensions...............................................................................1
Objetivos ..................................................................................................................2
1. Requisitos.............................................................................................................2
2. Protocols...............................................................................................................2
2.1. ¿Qué son?..............................................................................................................2
2.2. Propósito ...............................................................................................................2
3. Configurar Proyecto en Xcode..............................................................................3
3.1. Código ...................................................................................................................6
3.2. Documentación de código .......................................................................................8
4. Tests unitarios ....................................................................................................11
4.1. Código del test .....................................................................................................13
4.2. Ejecutar los tests desde Xcode ..............................................................................14
4.3. Cobertura de código desde Xcode..........................................................................14
4.4. Ejecutar los tests desde línea de comando .............................................................17
4.3. Cobertura de código desde línea de comando.........................................................18
5. Integración continua..........................................................................................20
5.1. Configuración de Travis-CI ....................................................................................21
5.2. Configuración de Coveralls con Travis-CI................................................................25
5.3. Publicación de informes en github-pages................................................................30
5.4. Configuración de Jenkins.......................................................................................47
Material de interés .................................................................................................48
Objetivos
 Entender el funcionamiento de los protocolos
 Aprender a crear tests unitarios
 Generar informes de resultados de tests y de cobertura de código
 Integración continua (Travis vs. Jenkins)
1. Requisitos
En este workshop se usarán las siguientes herramientas:
 Github: deberéis tener cuenta propia para poder crearos un repositorio público en el que
configurar la integración continua
 Travis CI: servicio de integración continua en el cloud
 Coveralls: servicio para mostrar informes de cobertura de código en el cloud
 Slather: librería para generar informes de cobertura
 Jazzy: utilidad para generar documentación
 xcpretty: utilidad para generar informes de tests
2. Protocols
2.1. ¿Qué son?
Los protocolos son una manera de definir una serie de métodos, constructores, etc. que debe
tener una clase o estructura, pero sin llegar a implementarlos.
Están relacionados con el concepto de herencia múltiple en otros lenguajes como C++, y son
similares al concepto de interface en otros lenguajes como C# o Java.
Se suelen utilizar para abstraer determinadas partes del código para que pueda ser extendida en
un futuro (como veremos en el ejemplo) y su uso es muy habitual para implementar delegates
(que veremos en siguientes workshops, aunque los delegates siguen una filosofía similar a los
listeners en Java).
Sintaxis:
<modifier> protocol ProtocolName : <Extended protocol> {
func someMethod()
func anotherMethodWithParameters(param1: Int, param2: Int)
}
2.2. Propósito
En este workshop implementaremos una función de medida de distancia de edición, o también
conocida como distancia de Levenstein https://es.wikipedia.org/wiki/Distancia_de_Levenshtein
La distancia de edición, es algo que se suele utilizar para comparar textos (palabras), cuando no
son exactamente iguales.
La distancia de edición indica la cantidad de caracteres que es necesario añadir, eliminar, mover
o reemplazar para que dos textos sean iguales.
Su uso es habitual en buscadores de texto (como Google), ya que cuando se realiza una búsqueda
es posible que el usuario cometa errores tipográficos o que el texto no coincida exactamente con
lo que hay indexado en la base de datos, pero sea muy similar. A grandes rasgos, uno de las
algoritmos que se usa en este tipo de herramientas es este (entre muchas otra más cosas que
no detallaremos aquí).
Aunque el uso habitual de la distancia de edición es para la comparación de Strings, en realidad
el algoritmo permite comparar colecciones de cosas (en este caso un string es una colección de
caracteres), por lo que en el workshop implementaremos el algoritmo mediante protocolos para
que así pueda ser utilizado para comparar más cosas a parte de strings de texto.
Finalmente extenderemos la clase String para que implemente el protocolo que hemos creado y
de este modo poderla utilizar con EditDistance utilizando la siguiente sintaxis:
extension <Class> : <Protocol> {
func method() {
}
}
Donde <Class> es la clase que queremos extender, y en este caso (aunque no es obligatorio)
además implementamos un Protocolo. En la extensión de la clase añadimos el método method().
3. Configurar Proyecto en Xcode
A continuación se describen los pasos a seguir para configurar el proyecto en Xcode tal y como
está en el repositorio.
El resultado debería ser el mismo que lo que hay en la rama init del repositorio.
1. Abrir Xcode y seleccionar la opción para crear un proyecto nuevo. Escoger la opción de framework
de cocoa touch.
2. Asignar un nombre al proyecto, la cuenta de desarrollo y la ubicación donde se guardará el
proyecto
3. Guardar el proyecto
4. Al guardar el proyecto, Xcode nos genera una estructura inicial del proyecto con un test unitario
de ejemplo (el cual sustituiremos). A continuación se muestra el aspecto general del proyecto
tras su creación.
3.1. Código
A continuación se proporciona el código para implementar la distancia de edición:
3.2. Documentación de código
En el ejemplo de código puede verse que las clases, métodos y variables miembro pueden
documentarse siguiendo una nomenclatura especial.
Xcode detecta los bloques de código del tipo /** .. */ o que empiecen por tres barras /// y los
trata de forma especial considerándolos como comentarios de documentación.
La documentación se escribe en formato markdown, por lo que resulta sencillo escribir títulos con
la sintaxis #título#, negrita como **negrita**, *cursiva*, etc.
Además, como puede verse, la documentación admite ciertas palabras clave para documentar
parámetros y valores retornados.
Estos bloques de texto son tratados de forma especial por Xcode de modo que al hacer alt + click
sobre una variable, tipo o método, nos mostrará la documentación sobre éste en un popup.
Del mismo modo, también puede verse esta misma documentación en el Quick Help inspector en
el panel de la derecha.
También es posible generar documentación en formato web para tenerla como referencia y
colgarla en un servidor (igual que la documentación de Apple).
Para ello puede utilizarse una herramienta como Jazzy.
Para instalar Jazzy:
Para ejecutar Jazzy:
jazzy --clean --author Alberto Irurueta --github_url
https://github.com/albertoirurueta/swift-protocols-and-generics-workshop --
xcodebuild-arguments -
project,./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj,-
scheme,swiftProtocolsAndGenerics --module swiftProtocolsAndGenerics --output
docs
Nótese que se proporcionan argumentos de xcodebuild para especificar la ruta del archivo de
proyecto y el esquema a documentar. En los argumentos proporcionados, los espacios que
normalmente se proporcionarían en el comando de xcodebuild deben sustituirse por comas.
xcodebuild es una herramienta de línea de comando que permite realizar tareas como
compilación, ejecución de tests, archivado, generación de ipa's, etc desde línea de comando, por
lo que será de gran utilidad para automatizar tareas en el servidor de integración.
Una vez ejecutada esta línea de comando, tendremos en la carpeta docs una página web con
toda la documentación del proyecto.
4. Tests unitarios
A continuación se describen los pasos a seguir para crear tests unitarios
1. Pulsar con el botón derecho sobre el grupo de tests (carpeta amarilla de tests en el
project navigator).
2. Seleccionar nuevo archivo y escoger la opción de nuevo test unitario (no confundir con
la opción de tests de UI)
3. Asignar un nombre al archivo y un lenguaje de programación
4. Aseguraos de que el check del archivo de tests está asociado al target de tests y no al
del framework, ya que de lo contrario estaríais incluyendo el archivo en la librería.
4.1. Código del test
A continuación se proporcionan tests unitarios de la distancia de edición.
Nótese que al comparar con un array de strings, se escoje el string que más separece (el que
tiene menor distancia de edición).
4.2. Ejecutar los tests desde Xcode
Para ejecutar los tests, en el panel izquierdo de Xcode seleccionamos el Test navigator.
Desde el test navigator podremos seleccionar qué tests ejecutar.
Tras la ejecución de los tests se mostrarán unas marcas que indican si se ejecutaron
correctamente o no, tal y como se muestra a continuación.
4.3. Cobertura de código desde Xcode
La cobertura de código nos permite saber realmente qué partes del código se han ejercitado con
la ejecución de los tests y que partes aún no han sido testeadas.
A medida que un proyecto crece es importante ver de un vistazo qué áreas están testeadas y
cuáles faltan por testear.
Del mismo modo, a medida que un proyecto crece es interesante tener un servidor que ejecute
todos los tests por nosotros y nos ofrezca informes de cobertura y de tests de forma automatizada
para poder hacer un mejor seguimiento de la calidad del código de un proyecto, ya que
normalmente en el desarrollo normal el desarrollador no tendrá que ejecutar todos los tests en
su máquina, sólo aquellos que sean relevantes para la parte del código que esté desarrollando.
El resto de tests los ejecutará el servidor de integración
Por defecto Xcode deshabilita la cobertura de código, ya que al ejecutar los tests con la cobertura
de código habilitada hay una pequeña penalización de rendimiento (la cual no tiene importancia
a menos que realmente se esté midiendo el rendimiento con el profiler).
Para poder obtener informes de cobertura, tanto en local como en el servidor, es necesario
habilitar la cobertura de código en el esquema del proyecto. Para ello deben seguirse los
siguientes pasos:
1. En el selector de esquemas, editar el esquema
2. En la opción de test activar la opción de recolección de datos de cobertura (Gather coverage
data). Más adelante también veremos que activamos la opción "shared"
Una vez activada la recolección de datos de cobertura, si volvemos a ejecutar los tests, veremos
en el Report Navigator del panel de la izquierda un resumen de los tests que han pasado y los
que no, así como información de resumen de la cobertura de código. El informe de tests y de
cobertura es interactivo y nos permite ir a las líneas de código específicas haciendo click sobre la
flechita que aparece al pasar el cursor del mouse por un elemento del informe.
En el caso del informe de cobertura, si ahora regresamos al archivo de código (o hacemos click
en la flechita desde el propio informe), veremos que aparecen resaltadas las líneas de código que
se han ejecutado en el test y las que quedan por testear.
4.4. Ejecutar los tests desde línea de comando
Tal y como hemos comentado al ejecutar Jazzy, Xcode ofrece una utilidad de línea de comando
(xcodebuild) que permite realizar tareas como la ejecución de tests desde línea de comando.
Esto como veremos resultará de utilidad para ejecutar los tests en un servidor de integración
continua (Jenkins o Travis).
Los tests pueden ejecutarse con la siguiente línea de comando:
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
En esta línea de comando se indica que primero se haga un clean de proyecto y a continuación
se ejecuten los tests. Se proporciona la ubicación del proyecto, el esquema a ejecutar y el
dispositivo en el que se ejecutarán. Se utilizará la configuración de debug con la cobertura de
código activada.
La ejecución de este comando inicia el simulador de iOS indicado, donde se ejecutarán todos los
tests. Una vez finalizado, el simulador se cierra.
Aunque xcodebuild nos muestra el resultado de la ejecución de los tests en la consola, puede ser
de utilidad generar un informe más visual donde podamos ver qué tests fallan y donde. Para ello
podemos utilizar xcpretty
Para instalar xcpretty debemos ejecutar:
A continuación deberemos ejecutar xcodebuild pero haciendo un pipe de su salida mediante
xcpretty:
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES |
xcpretty
Veremos que el resultado por consola ahora es más visual.
Podemos guardar la salida original de consola de xcodebuild haciendo un pipe con la utilidad tee,
de modo que el comando sería:
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee
xcodebuild.log | xcpretty
Finalmente, podemos generar un informe en formato Junit (que es de utilidad en Jenkins)
mediante el comando:
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee
xcodebuild.log | xcpretty -r junit
El informe se almacena en build/reports/junit.xml
Por otro lado, si lo preferís, podéis generar un informe en formato web, sustituyendo junit por
html en el comando anterior
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee
xcodebuild.log | xcpretty -r html
4.3. Cobertura de código desde línea de comando
Tras ejecutar los tests en un terminal, es posible generar un informe de cobertura desde línea de
comandos mediante Slather.
Slather es una utilidad que podemos instalar y permite transformar los datos de cobertura
obtenidos a un formato que sea legible (formato xml para el plugin de Cobertura en Jenkins,
formato para coveralls o bien formato html para generar el informe en formato web).
Para instalar Slather, debe ejecutarse la siguiente línea de comando:
http://buegling.com/blog/2015/4/26/building-nokogiri-on-os-x.
sudo gem install nokogiri -v 1.6.3.1 -- --with-iconv-dir=`xcode-select -
p`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr --with-xml2-
include=`xcode-select -
p`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml
2
Una vez tengamos slather instalado, podemos obtener el informe de cobertura siguiendo estos
pasos:
1. Abrir una ventana de terminal
2. Ejecutar en la ventana de terminal los tests por línea de comando tal y como hemos visto
3. Ejecutar slather del siguiente modo:
/usr/local/bin/slather coverage --html --scheme swiftProtocolsAndGenerics
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj
Tras la ejecución, en la carpeta html tendremos el informe en formato html
En la web oficial de slather hay más información para generar el informe en otros formatos
(Cobertura, el cual utilizaremos con Jenkins y Coveralls, el cual utilizaremos con Travis).
5. Integración continua
Aunque la configuración de los tests y la cobertura sólo necesario realizarla una sola vez, puede
ser tedioso tener que ejecutar manualmente los tests y generar manualmente el informe e
cobertura cada vez que se hace un cambio en el código.
Por otro lado, a medida que un proyecto crece, puede ser incómodo ejecutar todos los tests del
proyecto cada vez que se hace un commit en el repositorio, ya que la ejecución de todos los tests
puede tomar demasiado tiempo.
En estos casos un servidor de integración continua puede ser de utilidad para automatizar la
ejecución de todos los tests, generación de informes o artefactos compilados cada vez que se
haga un push en el repositorio. De modo que el desarrollador sólo tiene que preocuparse de
desarrollar y testear su parte del código y el servidor se encarga de comprobar que la contribución
de un desarrollador en un equipo de trabajo (mediante un push o pull request) es correcta
mediante la ejecución de todos los tests. Todo esto sin interrumpir el flujo de trabajo del
desarrollador.
En este workshop veremos dos servicios de integración continua:
 Travis-CI: travis CI es un servicio de integración continua en el cloud que se integra con github
de modo que cada vez que se hace un push en el repositorio realiza las tareas que se le indiquen.
Travis-CI es gratuito para proyectos open source en github.
 Jenkins: es un servidor open source de integración continua. En visual disponemos
de http://jenkins.oficina.visual-engin.com
5.1. Configuración de Travis-CI
Para utilizar travis, es necesario configurar vuestra cuenta de github para proporcionarle acceso
a travis.
Para ello en la página de github, id a vuestra cuenta y entrad en la sección de integraciones:
Os aparecerán un montón de servicios que pueden integrarse con github. Seleccionad travis (más
adelante también configuraremos coveralls).
Seleccionar el botón verde (a mí me aparece configure porque ya lo tengo añadido en github).
Otorgamos los permisos necesarios a Travis para acceder a nuestra cuenta de github
Tras otorgar permisos a Travis para acceder a github, debemos añadir el repositorio que nos
interesa a travis.
Desde la pantalla principal de Travis, pulsamos en el botón + al lado de "My repositories" o sobre
el nombre de nuestra cuenta.
Desde la pantalla de nuestra cuenta, pulsamos en el botón de sincronización para refrescar la
lista de repositorios que hay en nuestra cuenta de github, y a continuación activamos el
repositorio que nos interese.
A partir de este momento, travis escuchará el repositorio indicado para iniciar la ejecución de los
tests cada vez que se suban cambios al repositorio.
Sólo falta indicarle a travis qué es lo que debe ejecutar.
Para configurar travis es necesario definir el archivo .travis.yml en la raíz del repositorio.
.travis.yml
language: objective-c
osx_image: xcode8.1
script:
- xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
En el archivo indicamos que vamos a utilizar como lenguaje de programación objective-c (aunque
también sirve para Swift). Especificamos que deseamos una imagen de sistema operativo con
xcode8.1, y a continuación indicamos la línea de comando que deseamos ejecutar para pasar los
tests.
Finalmente, para que travis tenga acceso al esquema del proyecto que le hemos indicado
mediante línea de comando, debemos asegurarnos que el esquema esté marcado como "shared"
en Xcode. Para ello debemos editar el esquema y asegurarnos que el check "shared" esté activado
5.5.1. Archivo Readme y badges
Github por defecto nos crea un archivo README.md en el que podemos escribir documentación
del proyecto en formato markdown. Esta información es la que aparece en la página web de
github y puede utilizarse para poner documentación, intrucciones de uso, etc.
En el caso de travis (y también sucede igual con Coveralls y otros servicios), podemos además
añadir un badge que nos indique en todo momento el estado de los testa del proyecto (si pasan
o fallan), para que así de un vistazo podamos saber en todo momento el estado del proyecto.
Para ello debemos hacer click en el badge del proyecto en la web de travis (que inicialmente tiene
estado unknown) y copiar la URL del badge en formato markdown.
Modificamos o creamos el archivo README.md en la raíz del repositorio y añadimos el código
markdown que hemos copiado.
# swift-protocols-and-generics-workshop
Workshop for Swift protocols &amp; generics
[![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and-
generics-workshop.svg?branch=master)](https://travis-
ci.org/albertoirurueta/swift-protocols-and-generics-workshop)
A partir de ahora en la web de github aparecerá el badge de estado de compilación. Lo podéis
comprobar en:
https://github.com/albertoirurueta/swift-protocols-and-generics-workshop
En cuanto realicemos un push en la rama master del repositorio, Travis pondrá nuestro push en
cola hasta que haya una máquina disponible para iniciar la ejecución de los tests. Podemos
comprobar desde la web de travis el estado de la ejecución, la consola de terminal con los
comandos que se han ejecutado, y desde la web de github veremos el estado de la compilación
y ejecución de los tests.
5.2. Configuración de Coveralls con Travis-CI
Del mismo modo que hemos hecho con travis, desde la web de Github, accedemos a integraciones
en nuestra cuenta y añadimos la integración con Coveralls.
Una vez concedido el acceso a nuestra cuenta de Github, en la web de coveralls, vamos a la
sección de repositorios
Sincronizamos los repositorios, y activamos el acceso al repositorio de interés.
Para generar el informe de cobertura en Coveralls, necesitaremos convertir los datos de cobertura
generados por xcodebuild a un formato que entienda coveralls, para ello utilizaremos Slather.
Para utilizar Slather, modificaremos el archivo .travis.yml para instalar slather en la máquina y
ejecutarlo tras la ejecución de los tests
.travis.yml
language: objective-c
osx_image: xcode8.1
before_install:
- gem install slather --no-ri --no-rdoc
script:
- xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
- slather
A continuación, debemos crear un archivo .slather.yml para que slather sepa la configuración que
debe utilizar para enviar los datos de cobertura a coveralls
.slather.yml
input_format: profdata
coverage_service: coveralls
xcodeproj: ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj
scheme: swiftProtocolsAndGenerics
Finalmente, modificaremos el archivo README.md para añadir un badge con información sobre
la cobertura.
La URL del badge de coveralls puede obtenerse en la propia web de coveralls, pulsando sobre el
botón embed al lado del icono del badge y copiando la URL de markdown en nuestro archivo
README.md
Por lo que el archivo README.md quedaría como se muestra a continuación:
README.md
# swift-protocols-and-generics-workshop
Workshop for Swift protocols &amp; generics
[![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and-
generics-workshop.svg?branch=master)](https://travis-
ci.org/albertoirurueta/swift-protocols-and-generics-workshop)
[![Coverage Status](https://coveralls.io/repos/github/albertoirurueta/swift-
protocols-and-generics-
workshop/badge.svg?branch=master)](https://coveralls.io/github/albertoirurueta
/swift-protocols-and-generics-workshop?branch=master)
Ahora sólo es necesario realizar un push, y automáticamente Travis ejecutará los tests y enviará
la información de cobertura a Coveralls, y podremos acceder a ambos desde nuestra página de
github.
5.3. Publicación de informes en github-pages
Tal y como hemos visto en local, podemos generar informes de documentación, cobertura, tests
en formato HTML. Sin embargo sería conveniente tener disponibles dichos informes directamente
en la página web de nuestro proyecto.
Por suerte, github permite publicar páginas web estáticas en la rama gh-pages, de modo que
todo lo que se suba a esa rama aparecerá en la web de github.
En la siguientes secciones veremos cómo podemos hacer que travis genere los informes y a
continuación los suba a github pages para así tenerlos disponibles en la web de nuestro
repositorio.
5.3.1. Configuración para publicar automáticamente en github-pages
desde Travis
Para poder utilizar github-pages deberemos poder hacer pushes en la rama gh-pages desde
Travis, utilizando pasos similares a los indicados aquí:
https://gist.github.com/domenic/ec8b0fc8ab45f39403dd.
Para ello deberemos dar acceso a nuestro repositorio a Travis, lo cual implica proporcionar un
usuario y contraseña o una clave SSH. Por seguridad, y más teniendo en cuenta que es un
repositorio open source público, utilizaremos una funcionalidad de travis para almacenar la clave
de forma segura en el repositorio.
Primero necesitaremos crear una clave SSH. En la documentación de github se indica cómo
hacerlo:
https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
Los pasos a seguir son los siguientes:
1. Crear una clave SSH en local. Utilizaremos el mismo correo electrónico de nuestra cuenta de
github al crear la clave.
Indicamos la ubicación donde guardar la clave (puede usarse la ubicación por defecto) y
es importante no asignarle contraseña, ya que de lo contrario el comando ssh-add que
ejecutará Travis requeriría introducirla manualmente. Este comando creará un archivo de clave
privada y uno de clave pública.
No es necesario añadir la clave al agente SSH tal y como indica la documentación de Github ya
que no la usaremos en local para conectarnos a Github, si no que será Travis el que lo hará, por
lo que el comando ssh-add lo ejecutará Travis.
2. Añadir en la web de Github la clave pública generada para tener acceso. Cuidado, la clave debe
añadirse únicamente al repositorio que queremos dar acceso, no a nuestra cuenta, ya que
entonces daríamos acceso a Travis todos los respositorios. Para ello vamos a los settings del
repositorio.
En la sección de opciones veremos que más abajo hay la opción para activar github-pages e
incluso un editor online de las páginas. Nos aseguramos de que se usa la rama gh-pages o bien
usamos la herramienta de generación de una página de inicio mediante el botón Launch
automatic page generator.
3. Vamos a la sección de claves y pulsamos en el botón para añadir una clave.
4. Asignamos un nombre que identifique a la clave, le proporcionamos acceso de escritura, copiamos
el contenido de la clave pública y la añadimos
5. Veremos una confirmación conforme la clave se ha añadido.
6. Copiamos los archivos de claves pública y privada en el repositorio si no lo habíamos hecho ya
(ojo, no hacer commit aún ya que primero hay que encriptar la clave privada).
7. Comprobamos que ruby está instalado (por defecto en macOS ya viene instalado)
8. Instalamos el cliente de Travis (https://github.com/travis-ci/travis.rb) ejecutando el siguiente
comando.
Podemos comprobar que travis se ha instalado ejecutando el comando:
9. Desde la carpeta donde está la clave privada dentro del repositorio (el archivo github_key)
encriptamos la clave privada con el siguiente comando:
Si es la primera vez que ejecutamos Travis en el repositorio, travis nos lo indicará y nos
preguntará si es correcto. Travis nos devolverá el comando que es necesario para desencriptar
el archivo .enc generado. Debemos anotarlo ya que lo necesitaremos más adelante.
openssl aes-256-cbc -K $encrypted_0d0cc787d66b_key -iv
$encrypted_0d0cc787d66b_iv -in github_key.enc -out github_key -d
10. Veremos que se ha creado el archivo github_key.enc que contiene el archivo github_key pero
encriptado, por lo que podemos borrar el archivo github_key original, ya que únicamente
subiremos al repositorio en archivo github_key.enc.
11. Modificamos el archivo .travis.yml para añadir variables de entorno con los valores para
desencriptar la clave privada, y añadimos el comando ./publish-gh-pages.sh para ejecutar un
script que crearemos para publicar en github-pages
.travis.yml
language: objective-c
osx_image: xcode8.1
env:
global:
- ENCRYPTION_LABEL: "0d0cc787d66b"
- COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com"
before_install:
- gem install slather --no-ri --no-rdoc
script:
- xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
- slather
- ./publish-gh-pages.sh
https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
12. Creamos el archivo de script publish-gh-pages.sh
13. Otorgamos permisos de ejecución al archivo de script que hemos creado, de lo contrario
Travis no podrá ejecutarlo
1. Creamos un token de acceso en la cuenta de github, para ello vamos a settings pulsando sobre
la imagen de nuestra cuenta.
2. Seleccionamos la opción de Personal access tokens y pulsamos el botón de generar un nuevo
token. Asignamos un nombre al token y los permisos que le queremos dar (sólo de acceso a los
repositorios)
3. Copiamos el token devuelto por github, ya que no lo podremos consultar más adelante.
Desde el directorio del repositorio ejecutamos por línea de comando lo siguiente:
Este comando se encarga de generar un string encriptado mediante travis. Este string lo podemos
luego poner como una variable de entorno en el archivo .travis.yml, para ello debemos copiar la
respuesta de este comando en el archivo .travis.yml, tal y como se muestra a continuación:
.travis.yml
language: objective-c
osx_image: xcode8.1
env:
global:
-
secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW
6D4cGUuoiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2
fGKU0ekczoOns9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48
AvOZrjogCBoJNmVup8gtSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OE
p1LcwEWzGIKQ9nv8Ithr89DoG2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0
tfqnO2sGpDM+B/ApZvom/CC71kSCvYWnFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3
hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fHsxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FO
S3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEqxfvfauioWTxFuwo6kjHUjPqvqOAE4
zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhyJyWBJU2ViX8/WOCEkrog+Hm
Z/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM="
- ENCRYPTION_LABEL: "0d0cc787d66b"
- COMMIT_AUTHOR_EMAIL: alberto@irurueta.com
before_install:
- gem install slather --no-ri --no-rdoc
- gem install jazzy --no-ri --no-rdoc
- gem install xcpretty --no-ri --no-rdoc
script:
- set -o pipefail && xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS
Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -
enableCodeCoverage=YES | tee xcodebuild.log | xcpretty -r html
- ./publish-gh-pages.sh
after_success:
- cd $TRAVIS_BUILD_DIR && slather
Una vez hecho este cambio tendremos acceso a la variable de entorno GITHUB_OAUTH_TOKEN
desencriptada sin necesidad de subir el token de forma pública a nuestro repositorio
A continuación, cambiamos la última línea del script publish-gh-pages.sh para realizar el push
mediante https utilizando un usuario con acceso al repositorio (no copiar el que hay aquí) y el
token desencriptado en la variable de entorno GITHUB_OAUTH_TOKEN como contraseña.
Con estos pasos ya estaría todo configurado para que Travis subiera los informes que indiquemos
en la función doStuff en gihub-pages
5.3.1. Publicación de informes de documentación de Jazzy en github-pages
Ya hemos visto cómo generar informes web de documentación mediante Jazzy, ahora vamos a
modificar la función doStuff en el archivo publish-gh-pages para que Travis los genere y los
publique en github-pages.
Puesto que utilizamos jazzy, también tendremos que modificar el archivo .travis.yml para indicarle
a travis que debe instalar jazzy
.travis.yml
language: objective-c
osx_image: xcode8.1
env:
global:
-
secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW6D4cGUu
oiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2fGKU0ekczoOns
9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48AvOZrjogCBoJNmVup8g
tSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OEp1LcwEWzGIKQ9nv8Ithr89DoG
2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0tfqnO2sGpDM+B/ApZvom/CC71kSCvYW
nFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fH
sxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FOS3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEq
xfvfauioWTxFuwo6kjHUjPqvqOAE4zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhy
JyWBJU2ViX8/WOCEkrog+HmZ/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM="
- ENCRYPTION_LABEL: "0d0cc787d66b"
- COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com"
before_install:
- gem install slather --no-ri --no-rdoc
- gem install jazzy --no-ri --no-rdoc
script:
- xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
- slather
- ./publish-gh-pages.sh
Hacemos push y ahora Travis podrá generar el informe de documentación y publicarlo en la
carpeta docs de la rama gh-pages
5.3.2. Publicación de informes de tests de xcpretty en github-pages
Del mismo modo, tal y como hemos visto, podemos modificar doStuff en el archivo publish-gh-
pages para que Travis nos publique el informe de xcpretty en github-pages.
Para ello debemos modificar el archivo .travis.yml para que en lugar de ejecutar xcodebuild
directamente, haga un pipe con xcpretty tal y como hemos visto.
Para poder utilizar xcpretty le tendremos que decir a Travis que primero lo instale.
Además, para que el estado de build sea el correcto, tal y como se indica en la documentación
de xcpretty añadiendo set -o pipefail && antes del comando xcodebuild en el archivo .travis.yml,
tal. Puesto que se usa pipefail, ahora será necesario ejecutar slather por separado tras finalizar
el script correctamente, haciendo primero cd al directorio de compilación de Travis
.travis.yml
language: objective-c
osx_image: xcode8.1
env:
global:
-
secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW6D4cGUu
oiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2fGKU0ekczoOns
9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48AvOZrjogCBoJNmVup8g
tSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OEp1LcwEWzGIKQ9nv8Ithr89DoG
2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0tfqnO2sGpDM+B/ApZvom/CC71kSCvYW
nFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fH
sxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FOS3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEq
xfvfauioWTxFuwo6kjHUjPqvqOAE4zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhy
JyWBJU2ViX8/WOCEkrog+HmZ/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM="
- ENCRYPTION_LABEL: "0d0cc787d66b"
- COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com"
before_install:
- gem install slather --no-ri --no-rdoc
- gem install jazzy --no-ri --no-rdoc
- gem install xcpretty --no-ri --no-rdoc
script:
- set -o pipefail && xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee
xcodebuild.log | xcpretty -r html
- ./publish-gh-pages.sh
after_success:
- cd $TRAVIS_BUILD_DIR && slather
Puesto que xcpretty guarda el resultado del informe en la carpeta build/reports, y el arcivo de
script publish-gh-pages.sh publica todo lo que hay en la carpeta out a github-pages, deberemos
modificar el archivo de script para mover el contenido de build/reports dentro de la carpeta out,
de este modo:
Ahora, tras realizar el push tendremos el informe de tests subido a github-pages.
5.3.3. Enlazar los informes de github-pages.
Aunque hemos creado los informes y los hemos publicado en github-pages, no los podemos ver
de forma cómoda porque no hay un enlace para verlos, para ello podemos modificar el archivo
index.html de github-pages o bien el archivo README.md para colocar un enlace a los informes.
README.md
# swift-protocols-and-generics-workshop
Workshop for Swift protocols &amp; generics
[![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and-
generics-workshop.svg?branch=master)](https://travis-
ci.org/albertoirurueta/swift-protocols-and-generics-workshop)
[![Coverage Status](https://coveralls.io/repos/github/albertoirurueta/swift-
protocols-and-generics-
workshop/badge.svg?branch=master)](https://coveralls.io/github/albertoirurueta
/swift-protocols-and-generics-workshop?branch=master)
[Code Documentation](https://albertoirurueta.github.io/swift-protocols-and-
generics-workshop/docs/index.html)
[Test report](https://albertoirurueta.github.io/swift-protocols-and-generics-
workshop/build/reports/tests.html)
[Github pages](https://albertoirurueta.github.io/swift-protocols-and-generics-
workshop/)
5.4. Configuración de Jenkins
Hasta ahora hemos visto cómo configurar un servicio de integración continua en el cloud mediante
Travis, el cual se integra con Github y es gratuito para proyectos opensource.
Para proyectos privados esto no es una solución viable, (a no ser que tengamos cuentas de pago
en Github y Travis), pero es posible montar un servidor Jenkins para hacer exactamente lo mismo.
En Visual tenemos nuestro servidor Jenkins (http://jenkins.oficina.visual-engin.com).
Jenkins no es más que un servidor capaz de ejecutar scripts de forma programada (cada cierto
intervalo de tiempo o cuando hay un cambio en el repositorio) y de forma distribuida (ya que
puede ejecutar las tareas en nodos esclavos).
Jenkins es muy modular y configurable, y para ellos es posible instalarle una infinidad de plugins.
En nuestro caso necesitaremos los siguientes plugins (algunos ya vienen instalados por defecto):
 SCM y GIT para obtener datos del repositorio
 Junit: para analizar el archivo junit.xml generado por xcpretty con los resultados de los tests
 Cobertura: para analizar el archivo xml de cobertura generado por slather
 Publicación HTML: para publicar informes HTML
Para configurar el proyecto, los pasos a seguir son los siguientes:
1. Añadimos una tarea nueva con un proyecto de estilo libre.
2. Asignamos un nombre al proyecto.
3. Para no hace un uso excesivo de disco duro activamos desechar ejecuciones antiguas y
ponemos un número razonable de ejecuciones a mantener en disco (ej: 4)
4. Si el repositorio es github, podemos activar la casilla y poner la URL al repositorio. Esto nos
permitirá ir a la web del repo en github
5. Activar la casilla restringir donde se puede ejecutar el proyecto e indicad una máquina de un
nodo que esté previamente configurado en Jenkins.
6. En origen de fuente, seleccionamos git, introducimos la URL del repositorio e indicamos la
rama de la cual queremos obtener el código.
7. En disparadores de ejecuciones, podemos activar las casillas para detectar un cambio en
bitbucket o github, pero para que funcionen el servidor jenkins ha de ser accesible
públicamente (no es el caso en Visual), por lo que podemos activar la casilla para comprobar
el repositorio periódicamente (por ejemplo para comprobarlo cada 15 minutos debemos
introducir H/15 * * * *)
8. Es conveniente activar la casilla para detener la ejecución si se atasca. Esto es útil para que
Jenkins no deje el esclavo bloqueado indefinidamente en el caso de que algo falle (los tests
peten, se cierre el simulador, etc). De este modo, si no hay actividad por consola en un
determinado tiempo (ej: 5 minutos = 300 segundos), se detiene la ejecución.
9. En la sección de ejecutar, añadir un paso para ejecutar la linea de comandos (shell) y poner
los siguientes comandos de shell:
#ejecutar tests con informe en ./build/reports/junit.xml
xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee
xcodebuild.log | /usr/local/bin/xcpretty -r junit
#generar documentación en ./docs/index.html
/usr/local/bin/jazzy --clean --author Alberto Irurueta --github_url
https://github.com/albertoirurueta/swift-protocols-and-generics-workshop --
xcodebuild-arguments -
project,./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj,-
scheme,swiftProtocolsAndGenerics --module swiftProtocolsAndGenerics --output
docs
#generar informe de cobertura
/usr/local/bin/slather coverage --cobertura-xml --output-directory ./coverage --
scheme swiftProtocolsAndGenerics
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj
/usr/local/bin/slather coverage --html --scheme swiftProtocolsAndGenerics
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj
10. En la sección de acciones para después, añadir:
a) Publicar informes de "cobertura". El archivo estará ubicado
en: coverage/cobertura.xml
b) Publicar los resultados de test de Junit. El archivo estará ubicado
en: build/reports/junit.xml
c) Publish HTML reports.
i. Informe de documentación de código.
Directorio: docs
Index page(s): index.html
Report title: Code Documentation
ii. Informe HTML de cobertura
Directorio: html
Index page(s): index.html
Report title: Coverage
Material de interés
Página oficial de Swift: https://swift.org (aquí encontraréis toda la documentación oficial de
Swift y el libro oficial en formato ebook en la sección de documentación donde encontraréis
información sobre Protocols).
Documentar código Swift: http://www.appcoda.com/swift-markdown/
Publicar documentación en github: http://www.jessesquires.com/swift-documentation/
Testing y cobertura de código en
Xcode: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/
testing_with_xcode/chapters/07-code_coverage.html
Configurar Travis: https://www.raywenderlich.com/109418/travis-ci-tutorial
Instalar slather: https://github.com/SlatherOrg/slather
Generar informes web de los tests: https://github.com/fastlane/fastlane/tree/master/scan
Github pages: https://pages.github.com
Publicar de forma automática en Github-pages con
Travis: https://gist.github.com/domenic/ec8b0fc8ab45f39403dd
Integración continua y cobertura con Jenkins: https://pspdfkit.com/blog/2016/continuous-ios-
code-coverage-with-jenkins-and-slather/
Generar ipa's en Travis y distribuirlos con Testflight o HockeyApp: https://www.objc.io/issues/6-
build-tools/travis-ci/
NOTA: Aunque en este workshop no lo hemos visto, también es posible utilizar cocoapods con
Travis, para ello habría que descomentar las líneas comentadas mediante # en el siguiente
archivo de travis, y modificar la llamada de xcodebuild para que se utilice un workspace en lugar
de un proyecto
language: objective-c
osx_image: xcode8.1
#cache: cocoapods
before_install:
#- gem install cocoapods --no-ri --no-rdoc
- gem install slather --no-ri --no-rdoc
script:
- xcodebuild clean test -project
./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme
swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone
7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES
- slather

Más contenido relacionado

La actualidad más candente

La actualidad más candente (17)

Programación Orientada a Objetos
Programación Orientada a ObjetosProgramación Orientada a Objetos
Programación Orientada a Objetos
 
Tipos de datos
Tipos de datosTipos de datos
Tipos de datos
 
Programación con java en Eclipse
Programación con java en EclipseProgramación con java en Eclipse
Programación con java en Eclipse
 
Cuestionario
CuestionarioCuestionario
Cuestionario
 
Tópicos Avanzados de Programación - Unidad 3 programacion concurrente
Tópicos Avanzados de Programación - Unidad 3 programacion concurrenteTópicos Avanzados de Programación - Unidad 3 programacion concurrente
Tópicos Avanzados de Programación - Unidad 3 programacion concurrente
 
LibreríAs De Java
LibreríAs De JavaLibreríAs De Java
LibreríAs De Java
 
Ppt java
Ppt javaPpt java
Ppt java
 
Programación java1
Programación java1Programación java1
Programación java1
 
Topicos Avanzados de Programacion - Unidad 4 programacion concurrente
Topicos Avanzados de Programacion - Unidad 4 programacion concurrenteTopicos Avanzados de Programacion - Unidad 4 programacion concurrente
Topicos Avanzados de Programacion - Unidad 4 programacion concurrente
 
Programación multitarea
Programación multitareaProgramación multitarea
Programación multitarea
 
Concurrencia en Java
Concurrencia en JavaConcurrencia en Java
Concurrencia en Java
 
Apendice general 4 terminos de programador
Apendice general 4 terminos de programadorApendice general 4 terminos de programador
Apendice general 4 terminos de programador
 
Introducción a java
Introducción a javaIntroducción a java
Introducción a java
 
Paquetes De Programacion
Paquetes De ProgramacionPaquetes De Programacion
Paquetes De Programacion
 
Multitarea e hilos en java con ejemplos
Multitarea e hilos en java con ejemplosMultitarea e hilos en java con ejemplos
Multitarea e hilos en java con ejemplos
 
Cuestionario
CuestionarioCuestionario
Cuestionario
 
Excepciones
ExcepcionesExcepciones
Excepciones
 

Destacado

Unlock The Value Of Your Microsoft and SAP Investments
Unlock The Value Of Your Microsoft and SAP InvestmentsUnlock The Value Of Your Microsoft and SAP Investments
Unlock The Value Of Your Microsoft and SAP InvestmentsSAP Technology
 
Change document display
Change document displayChange document display
Change document displayRadosław Gref
 
Workshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingWorkshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingVisual Engineering
 
Multithreading 101
Multithreading 101Multithreading 101
Multithreading 101Tim Penhey
 
JavaScript for ABAP Programmers - 7/7 Functional Programming
JavaScript for ABAP Programmers - 7/7 Functional ProgrammingJavaScript for ABAP Programmers - 7/7 Functional Programming
JavaScript for ABAP Programmers - 7/7 Functional ProgrammingChris Whealy
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native IntroductionVisual Engineering
 
Automated Testing Of Web Applications Using XML
Automated  Testing Of  Web  Applications Using  XMLAutomated  Testing Of  Web  Applications Using  XML
Automated Testing Of Web Applications Using XMLdiongillard
 
Getting Started with OpenUI5 (San Francisco State University)
Getting Started with OpenUI5 (San Francisco State University)Getting Started with OpenUI5 (San Francisco State University)
Getting Started with OpenUI5 (San Francisco State University)Alexander Graebe
 
Introduction to Design Thinking
Introduction to Design ThinkingIntroduction to Design Thinking
Introduction to Design ThinkingBlackvard
 
Workhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftWorkhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftVisual Engineering
 
SAP for Utilities 2015 FINAL HOTLIST
SAP for Utilities 2015 FINAL HOTLISTSAP for Utilities 2015 FINAL HOTLIST
SAP for Utilities 2015 FINAL HOTLISTJonathan Toomey
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IVisual Engineering
 
Consuming Data With HANA XS
Consuming Data With HANA XSConsuming Data With HANA XS
Consuming Data With HANA XSBlackvard
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - ComponentsVisual Engineering
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideVisual Engineering
 

Destacado (20)

Workshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
 
Unlock The Value Of Your Microsoft and SAP Investments
Unlock The Value Of Your Microsoft and SAP InvestmentsUnlock The Value Of Your Microsoft and SAP Investments
Unlock The Value Of Your Microsoft and SAP Investments
 
Change document display
Change document displayChange document display
Change document display
 
CDS Unit Testing
CDS Unit TestingCDS Unit Testing
CDS Unit Testing
 
Workshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingWorkshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototyping
 
Hana sql
Hana sql Hana sql
Hana sql
 
Multithreading 101
Multithreading 101Multithreading 101
Multithreading 101
 
JavaScript for ABAP Programmers - 7/7 Functional Programming
JavaScript for ABAP Programmers - 7/7 Functional ProgrammingJavaScript for ABAP Programmers - 7/7 Functional Programming
JavaScript for ABAP Programmers - 7/7 Functional Programming
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native Introduction
 
Automated Testing Of Web Applications Using XML
Automated  Testing Of  Web  Applications Using  XMLAutomated  Testing Of  Web  Applications Using  XML
Automated Testing Of Web Applications Using XML
 
Getting Started with OpenUI5 (San Francisco State University)
Getting Started with OpenUI5 (San Francisco State University)Getting Started with OpenUI5 (San Francisco State University)
Getting Started with OpenUI5 (San Francisco State University)
 
Python Intro
Python IntroPython Intro
Python Intro
 
Introduction to Design Thinking
Introduction to Design ThinkingIntroduction to Design Thinking
Introduction to Design Thinking
 
Workhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftWorkhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de Swift
 
SAP for Utilities 2015 FINAL HOTLIST
SAP for Utilities 2015 FINAL HOTLISTSAP for Utilities 2015 FINAL HOTLIST
SAP for Utilities 2015 FINAL HOTLIST
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
Consuming Data With HANA XS
Consuming Data With HANA XSConsuming Data With HANA XS
Consuming Data With HANA XS
 
OpenUI5
OpenUI5OpenUI5
OpenUI5
 
Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - Components
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
 

Similar a Workshop iOS 3: Testing, protocolos y extensiones

Ejercicio compiladores
Ejercicio compiladoresEjercicio compiladores
Ejercicio compiladoresSheyli Patiño
 
Framework by Marcos Acosta
Framework by Marcos AcostaFramework by Marcos Acosta
Framework by Marcos AcostaMarcos Acosta
 
Programación básica en java
Programación básica en javaProgramación básica en java
Programación básica en javaJorge Tapia
 
Gestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterGestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterandrewzg
 
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para guardar información
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para   guardar informaciónJAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para   guardar información
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para guardar informaciónUniversidad Santo Tomás
 
04 taller-django
04 taller-django04 taller-django
04 taller-djangosamerscd
 
Manual de usuarios_de_eclipse_jenny
Manual de usuarios_de_eclipse_jennyManual de usuarios_de_eclipse_jenny
Manual de usuarios_de_eclipse_jennyJenny Martinez
 
Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Edgar Dueñas
 
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptxFabianAndresNuezPinz
 
[ES] Fundamentos esenciales de la plataforma java
[ES] Fundamentos esenciales de la plataforma java[ES] Fundamentos esenciales de la plataforma java
[ES] Fundamentos esenciales de la plataforma javaEudris Cabrera
 
Aspect Oriented Programming introduction
Aspect Oriented Programming introductionAspect Oriented Programming introduction
Aspect Oriented Programming introductionMiguel Pastor
 
investigacion unidad tres componentes y librerias
investigacion unidad tres componentes y libreriasinvestigacion unidad tres componentes y librerias
investigacion unidad tres componentes y libreriasAnel Sosa
 

Similar a Workshop iOS 3: Testing, protocolos y extensiones (20)

Ejercicio compiladores
Ejercicio compiladoresEjercicio compiladores
Ejercicio compiladores
 
Manual tecnico umasoft
Manual tecnico umasoftManual tecnico umasoft
Manual tecnico umasoft
 
Framework by Marcos Acosta
Framework by Marcos AcostaFramework by Marcos Acosta
Framework by Marcos Acosta
 
Programación básica en java
Programación básica en javaProgramación básica en java
Programación básica en java
 
Hola mundorafaelnavarroprieto
Hola mundorafaelnavarroprietoHola mundorafaelnavarroprieto
Hola mundorafaelnavarroprieto
 
Lp pract2006
Lp pract2006Lp pract2006
Lp pract2006
 
Gestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterGestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniter
 
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para guardar información
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para   guardar informaciónJAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para   guardar información
JAVA: TRY-CATCH-FINALLY y Uso de ficheros de texto para guardar información
 
Presentación: xUnit y Junit
Presentación: xUnit y JunitPresentación: xUnit y Junit
Presentación: xUnit y Junit
 
04 taller-django
04 taller-django04 taller-django
04 taller-django
 
Manual de usuarios_de_eclipse_jenny
Manual de usuarios_de_eclipse_jennyManual de usuarios_de_eclipse_jenny
Manual de usuarios_de_eclipse_jenny
 
Tutorial net beans
Tutorial net beansTutorial net beans
Tutorial net beans
 
Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2
 
Welcome to Django
Welcome to DjangoWelcome to Django
Welcome to Django
 
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
 
[ES] Fundamentos esenciales de la plataforma java
[ES] Fundamentos esenciales de la plataforma java[ES] Fundamentos esenciales de la plataforma java
[ES] Fundamentos esenciales de la plataforma java
 
Aspect Oriented Programming introduction
Aspect Oriented Programming introductionAspect Oriented Programming introduction
Aspect Oriented Programming introduction
 
Fondo1 (2)
Fondo1 (2)Fondo1 (2)
Fondo1 (2)
 
investigacion unidad tres componentes y librerias
investigacion unidad tres componentes y libreriasinvestigacion unidad tres componentes y librerias
investigacion unidad tres componentes y librerias
 
Manual de eclpse emrt
Manual de eclpse emrtManual de eclpse emrt
Manual de eclpse emrt
 

Más de Visual Engineering

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSVisual Engineering
 
Workshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresWorkshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresVisual Engineering
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedVisual Engineering
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareVisual Engineering
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxVisual Engineering
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionVisual Engineering
 
Workshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsWorkshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsVisual Engineering
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIVisual Engineering
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIVisual Engineering
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSVisual Engineering
 
Workshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCWorkshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCVisual Engineering
 
Workshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsWorkshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsVisual Engineering
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testingVisual Engineering
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Visual Engineering
 

Más de Visual Engineering (20)

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
Workshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresWorkshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - Structures
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS Introduction
 
Workshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsWorkshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effects
 
Workshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte II
 
Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte III
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte II
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Workshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCWorkshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVC
 
Workshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsWorkshop 7: Single Page Applications
Workshop 7: Single Page Applications
 
Workshop 6: Designer tools
Workshop 6: Designer toolsWorkshop 6: Designer tools
Workshop 6: Designer tools
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.
 

Último

International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)GDGSucre
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx241521559
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...silviayucra2
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfJulian Lamprea
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxLolaBunny11
 

Último (10)

International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdf
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptx
 

Workshop iOS 3: Testing, protocolos y extensiones

  • 1. 5. Testing, protocols & extensions ÍNDICE 5. Testing, protocols & extensions...............................................................................1 Objetivos ..................................................................................................................2 1. Requisitos.............................................................................................................2 2. Protocols...............................................................................................................2 2.1. ¿Qué son?..............................................................................................................2 2.2. Propósito ...............................................................................................................2 3. Configurar Proyecto en Xcode..............................................................................3 3.1. Código ...................................................................................................................6 3.2. Documentación de código .......................................................................................8 4. Tests unitarios ....................................................................................................11 4.1. Código del test .....................................................................................................13 4.2. Ejecutar los tests desde Xcode ..............................................................................14 4.3. Cobertura de código desde Xcode..........................................................................14 4.4. Ejecutar los tests desde línea de comando .............................................................17 4.3. Cobertura de código desde línea de comando.........................................................18 5. Integración continua..........................................................................................20 5.1. Configuración de Travis-CI ....................................................................................21 5.2. Configuración de Coveralls con Travis-CI................................................................25 5.3. Publicación de informes en github-pages................................................................30 5.4. Configuración de Jenkins.......................................................................................47 Material de interés .................................................................................................48
  • 2. Objetivos  Entender el funcionamiento de los protocolos  Aprender a crear tests unitarios  Generar informes de resultados de tests y de cobertura de código  Integración continua (Travis vs. Jenkins) 1. Requisitos En este workshop se usarán las siguientes herramientas:  Github: deberéis tener cuenta propia para poder crearos un repositorio público en el que configurar la integración continua  Travis CI: servicio de integración continua en el cloud  Coveralls: servicio para mostrar informes de cobertura de código en el cloud  Slather: librería para generar informes de cobertura  Jazzy: utilidad para generar documentación  xcpretty: utilidad para generar informes de tests 2. Protocols 2.1. ¿Qué son? Los protocolos son una manera de definir una serie de métodos, constructores, etc. que debe tener una clase o estructura, pero sin llegar a implementarlos. Están relacionados con el concepto de herencia múltiple en otros lenguajes como C++, y son similares al concepto de interface en otros lenguajes como C# o Java. Se suelen utilizar para abstraer determinadas partes del código para que pueda ser extendida en un futuro (como veremos en el ejemplo) y su uso es muy habitual para implementar delegates (que veremos en siguientes workshops, aunque los delegates siguen una filosofía similar a los listeners en Java). Sintaxis: <modifier> protocol ProtocolName : <Extended protocol> { func someMethod() func anotherMethodWithParameters(param1: Int, param2: Int) } 2.2. Propósito En este workshop implementaremos una función de medida de distancia de edición, o también conocida como distancia de Levenstein https://es.wikipedia.org/wiki/Distancia_de_Levenshtein La distancia de edición, es algo que se suele utilizar para comparar textos (palabras), cuando no son exactamente iguales.
  • 3. La distancia de edición indica la cantidad de caracteres que es necesario añadir, eliminar, mover o reemplazar para que dos textos sean iguales. Su uso es habitual en buscadores de texto (como Google), ya que cuando se realiza una búsqueda es posible que el usuario cometa errores tipográficos o que el texto no coincida exactamente con lo que hay indexado en la base de datos, pero sea muy similar. A grandes rasgos, uno de las algoritmos que se usa en este tipo de herramientas es este (entre muchas otra más cosas que no detallaremos aquí). Aunque el uso habitual de la distancia de edición es para la comparación de Strings, en realidad el algoritmo permite comparar colecciones de cosas (en este caso un string es una colección de caracteres), por lo que en el workshop implementaremos el algoritmo mediante protocolos para que así pueda ser utilizado para comparar más cosas a parte de strings de texto. Finalmente extenderemos la clase String para que implemente el protocolo que hemos creado y de este modo poderla utilizar con EditDistance utilizando la siguiente sintaxis: extension <Class> : <Protocol> { func method() { } } Donde <Class> es la clase que queremos extender, y en este caso (aunque no es obligatorio) además implementamos un Protocolo. En la extensión de la clase añadimos el método method(). 3. Configurar Proyecto en Xcode A continuación se describen los pasos a seguir para configurar el proyecto en Xcode tal y como está en el repositorio. El resultado debería ser el mismo que lo que hay en la rama init del repositorio. 1. Abrir Xcode y seleccionar la opción para crear un proyecto nuevo. Escoger la opción de framework de cocoa touch.
  • 4. 2. Asignar un nombre al proyecto, la cuenta de desarrollo y la ubicación donde se guardará el proyecto
  • 5. 3. Guardar el proyecto 4. Al guardar el proyecto, Xcode nos genera una estructura inicial del proyecto con un test unitario de ejemplo (el cual sustituiremos). A continuación se muestra el aspecto general del proyecto tras su creación.
  • 6. 3.1. Código A continuación se proporciona el código para implementar la distancia de edición:
  • 7.
  • 8. 3.2. Documentación de código En el ejemplo de código puede verse que las clases, métodos y variables miembro pueden documentarse siguiendo una nomenclatura especial. Xcode detecta los bloques de código del tipo /** .. */ o que empiecen por tres barras /// y los trata de forma especial considerándolos como comentarios de documentación. La documentación se escribe en formato markdown, por lo que resulta sencillo escribir títulos con la sintaxis #título#, negrita como **negrita**, *cursiva*, etc. Además, como puede verse, la documentación admite ciertas palabras clave para documentar parámetros y valores retornados. Estos bloques de texto son tratados de forma especial por Xcode de modo que al hacer alt + click sobre una variable, tipo o método, nos mostrará la documentación sobre éste en un popup.
  • 9. Del mismo modo, también puede verse esta misma documentación en el Quick Help inspector en el panel de la derecha. También es posible generar documentación en formato web para tenerla como referencia y colgarla en un servidor (igual que la documentación de Apple). Para ello puede utilizarse una herramienta como Jazzy. Para instalar Jazzy: Para ejecutar Jazzy: jazzy --clean --author Alberto Irurueta --github_url https://github.com/albertoirurueta/swift-protocols-and-generics-workshop -- xcodebuild-arguments - project,./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj,- scheme,swiftProtocolsAndGenerics --module swiftProtocolsAndGenerics --output docs
  • 10. Nótese que se proporcionan argumentos de xcodebuild para especificar la ruta del archivo de proyecto y el esquema a documentar. En los argumentos proporcionados, los espacios que normalmente se proporcionarían en el comando de xcodebuild deben sustituirse por comas. xcodebuild es una herramienta de línea de comando que permite realizar tareas como compilación, ejecución de tests, archivado, generación de ipa's, etc desde línea de comando, por lo que será de gran utilidad para automatizar tareas en el servidor de integración. Una vez ejecutada esta línea de comando, tendremos en la carpeta docs una página web con toda la documentación del proyecto.
  • 11. 4. Tests unitarios A continuación se describen los pasos a seguir para crear tests unitarios 1. Pulsar con el botón derecho sobre el grupo de tests (carpeta amarilla de tests en el project navigator). 2. Seleccionar nuevo archivo y escoger la opción de nuevo test unitario (no confundir con la opción de tests de UI) 3. Asignar un nombre al archivo y un lenguaje de programación
  • 12. 4. Aseguraos de que el check del archivo de tests está asociado al target de tests y no al del framework, ya que de lo contrario estaríais incluyendo el archivo en la librería.
  • 13. 4.1. Código del test A continuación se proporcionan tests unitarios de la distancia de edición. Nótese que al comparar con un array de strings, se escoje el string que más separece (el que tiene menor distancia de edición).
  • 14. 4.2. Ejecutar los tests desde Xcode Para ejecutar los tests, en el panel izquierdo de Xcode seleccionamos el Test navigator. Desde el test navigator podremos seleccionar qué tests ejecutar. Tras la ejecución de los tests se mostrarán unas marcas que indican si se ejecutaron correctamente o no, tal y como se muestra a continuación. 4.3. Cobertura de código desde Xcode La cobertura de código nos permite saber realmente qué partes del código se han ejercitado con la ejecución de los tests y que partes aún no han sido testeadas.
  • 15. A medida que un proyecto crece es importante ver de un vistazo qué áreas están testeadas y cuáles faltan por testear. Del mismo modo, a medida que un proyecto crece es interesante tener un servidor que ejecute todos los tests por nosotros y nos ofrezca informes de cobertura y de tests de forma automatizada para poder hacer un mejor seguimiento de la calidad del código de un proyecto, ya que normalmente en el desarrollo normal el desarrollador no tendrá que ejecutar todos los tests en su máquina, sólo aquellos que sean relevantes para la parte del código que esté desarrollando. El resto de tests los ejecutará el servidor de integración Por defecto Xcode deshabilita la cobertura de código, ya que al ejecutar los tests con la cobertura de código habilitada hay una pequeña penalización de rendimiento (la cual no tiene importancia a menos que realmente se esté midiendo el rendimiento con el profiler). Para poder obtener informes de cobertura, tanto en local como en el servidor, es necesario habilitar la cobertura de código en el esquema del proyecto. Para ello deben seguirse los siguientes pasos: 1. En el selector de esquemas, editar el esquema 2. En la opción de test activar la opción de recolección de datos de cobertura (Gather coverage data). Más adelante también veremos que activamos la opción "shared"
  • 16. Una vez activada la recolección de datos de cobertura, si volvemos a ejecutar los tests, veremos en el Report Navigator del panel de la izquierda un resumen de los tests que han pasado y los que no, así como información de resumen de la cobertura de código. El informe de tests y de cobertura es interactivo y nos permite ir a las líneas de código específicas haciendo click sobre la flechita que aparece al pasar el cursor del mouse por un elemento del informe.
  • 17. En el caso del informe de cobertura, si ahora regresamos al archivo de código (o hacemos click en la flechita desde el propio informe), veremos que aparecen resaltadas las líneas de código que se han ejecutado en el test y las que quedan por testear. 4.4. Ejecutar los tests desde línea de comando Tal y como hemos comentado al ejecutar Jazzy, Xcode ofrece una utilidad de línea de comando (xcodebuild) que permite realizar tareas como la ejecución de tests desde línea de comando. Esto como veremos resultará de utilidad para ejecutar los tests en un servidor de integración continua (Jenkins o Travis). Los tests pueden ejecutarse con la siguiente línea de comando: xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES En esta línea de comando se indica que primero se haga un clean de proyecto y a continuación se ejecuten los tests. Se proporciona la ubicación del proyecto, el esquema a ejecutar y el dispositivo en el que se ejecutarán. Se utilizará la configuración de debug con la cobertura de código activada. La ejecución de este comando inicia el simulador de iOS indicado, donde se ejecutarán todos los tests. Una vez finalizado, el simulador se cierra. Aunque xcodebuild nos muestra el resultado de la ejecución de los tests en la consola, puede ser de utilidad generar un informe más visual donde podamos ver qué tests fallan y donde. Para ello podemos utilizar xcpretty Para instalar xcpretty debemos ejecutar:
  • 18. A continuación deberemos ejecutar xcodebuild pero haciendo un pipe de su salida mediante xcpretty: xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | xcpretty Veremos que el resultado por consola ahora es más visual. Podemos guardar la salida original de consola de xcodebuild haciendo un pipe con la utilidad tee, de modo que el comando sería: xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee xcodebuild.log | xcpretty Finalmente, podemos generar un informe en formato Junit (que es de utilidad en Jenkins) mediante el comando: xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee xcodebuild.log | xcpretty -r junit El informe se almacena en build/reports/junit.xml Por otro lado, si lo preferís, podéis generar un informe en formato web, sustituyendo junit por html en el comando anterior xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee xcodebuild.log | xcpretty -r html 4.3. Cobertura de código desde línea de comando Tras ejecutar los tests en un terminal, es posible generar un informe de cobertura desde línea de comandos mediante Slather. Slather es una utilidad que podemos instalar y permite transformar los datos de cobertura obtenidos a un formato que sea legible (formato xml para el plugin de Cobertura en Jenkins, formato para coveralls o bien formato html para generar el informe en formato web).
  • 19. Para instalar Slather, debe ejecutarse la siguiente línea de comando: http://buegling.com/blog/2015/4/26/building-nokogiri-on-os-x. sudo gem install nokogiri -v 1.6.3.1 -- --with-iconv-dir=`xcode-select - p`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr --with-xml2- include=`xcode-select - p`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml 2 Una vez tengamos slather instalado, podemos obtener el informe de cobertura siguiendo estos pasos: 1. Abrir una ventana de terminal 2. Ejecutar en la ventana de terminal los tests por línea de comando tal y como hemos visto 3. Ejecutar slather del siguiente modo: /usr/local/bin/slather coverage --html --scheme swiftProtocolsAndGenerics ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj Tras la ejecución, en la carpeta html tendremos el informe en formato html
  • 20. En la web oficial de slather hay más información para generar el informe en otros formatos (Cobertura, el cual utilizaremos con Jenkins y Coveralls, el cual utilizaremos con Travis). 5. Integración continua Aunque la configuración de los tests y la cobertura sólo necesario realizarla una sola vez, puede ser tedioso tener que ejecutar manualmente los tests y generar manualmente el informe e cobertura cada vez que se hace un cambio en el código. Por otro lado, a medida que un proyecto crece, puede ser incómodo ejecutar todos los tests del proyecto cada vez que se hace un commit en el repositorio, ya que la ejecución de todos los tests puede tomar demasiado tiempo. En estos casos un servidor de integración continua puede ser de utilidad para automatizar la ejecución de todos los tests, generación de informes o artefactos compilados cada vez que se haga un push en el repositorio. De modo que el desarrollador sólo tiene que preocuparse de desarrollar y testear su parte del código y el servidor se encarga de comprobar que la contribución de un desarrollador en un equipo de trabajo (mediante un push o pull request) es correcta mediante la ejecución de todos los tests. Todo esto sin interrumpir el flujo de trabajo del desarrollador. En este workshop veremos dos servicios de integración continua:  Travis-CI: travis CI es un servicio de integración continua en el cloud que se integra con github de modo que cada vez que se hace un push en el repositorio realiza las tareas que se le indiquen. Travis-CI es gratuito para proyectos open source en github.  Jenkins: es un servidor open source de integración continua. En visual disponemos de http://jenkins.oficina.visual-engin.com
  • 21. 5.1. Configuración de Travis-CI Para utilizar travis, es necesario configurar vuestra cuenta de github para proporcionarle acceso a travis. Para ello en la página de github, id a vuestra cuenta y entrad en la sección de integraciones: Os aparecerán un montón de servicios que pueden integrarse con github. Seleccionad travis (más adelante también configuraremos coveralls).
  • 22. Seleccionar el botón verde (a mí me aparece configure porque ya lo tengo añadido en github). Otorgamos los permisos necesarios a Travis para acceder a nuestra cuenta de github Tras otorgar permisos a Travis para acceder a github, debemos añadir el repositorio que nos interesa a travis. Desde la pantalla principal de Travis, pulsamos en el botón + al lado de "My repositories" o sobre el nombre de nuestra cuenta.
  • 23. Desde la pantalla de nuestra cuenta, pulsamos en el botón de sincronización para refrescar la lista de repositorios que hay en nuestra cuenta de github, y a continuación activamos el repositorio que nos interese. A partir de este momento, travis escuchará el repositorio indicado para iniciar la ejecución de los tests cada vez que se suban cambios al repositorio. Sólo falta indicarle a travis qué es lo que debe ejecutar.
  • 24. Para configurar travis es necesario definir el archivo .travis.yml en la raíz del repositorio. .travis.yml language: objective-c osx_image: xcode8.1 script: - xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES En el archivo indicamos que vamos a utilizar como lenguaje de programación objective-c (aunque también sirve para Swift). Especificamos que deseamos una imagen de sistema operativo con xcode8.1, y a continuación indicamos la línea de comando que deseamos ejecutar para pasar los tests. Finalmente, para que travis tenga acceso al esquema del proyecto que le hemos indicado mediante línea de comando, debemos asegurarnos que el esquema esté marcado como "shared" en Xcode. Para ello debemos editar el esquema y asegurarnos que el check "shared" esté activado 5.5.1. Archivo Readme y badges Github por defecto nos crea un archivo README.md en el que podemos escribir documentación del proyecto en formato markdown. Esta información es la que aparece en la página web de github y puede utilizarse para poner documentación, intrucciones de uso, etc. En el caso de travis (y también sucede igual con Coveralls y otros servicios), podemos además añadir un badge que nos indique en todo momento el estado de los testa del proyecto (si pasan o fallan), para que así de un vistazo podamos saber en todo momento el estado del proyecto.
  • 25. Para ello debemos hacer click en el badge del proyecto en la web de travis (que inicialmente tiene estado unknown) y copiar la URL del badge en formato markdown. Modificamos o creamos el archivo README.md en la raíz del repositorio y añadimos el código markdown que hemos copiado. # swift-protocols-and-generics-workshop Workshop for Swift protocols &amp; generics [![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and- generics-workshop.svg?branch=master)](https://travis- ci.org/albertoirurueta/swift-protocols-and-generics-workshop) A partir de ahora en la web de github aparecerá el badge de estado de compilación. Lo podéis comprobar en: https://github.com/albertoirurueta/swift-protocols-and-generics-workshop En cuanto realicemos un push en la rama master del repositorio, Travis pondrá nuestro push en cola hasta que haya una máquina disponible para iniciar la ejecución de los tests. Podemos comprobar desde la web de travis el estado de la ejecución, la consola de terminal con los comandos que se han ejecutado, y desde la web de github veremos el estado de la compilación y ejecución de los tests. 5.2. Configuración de Coveralls con Travis-CI Del mismo modo que hemos hecho con travis, desde la web de Github, accedemos a integraciones en nuestra cuenta y añadimos la integración con Coveralls. Una vez concedido el acceso a nuestra cuenta de Github, en la web de coveralls, vamos a la sección de repositorios
  • 26. Sincronizamos los repositorios, y activamos el acceso al repositorio de interés. Para generar el informe de cobertura en Coveralls, necesitaremos convertir los datos de cobertura generados por xcodebuild a un formato que entienda coveralls, para ello utilizaremos Slather. Para utilizar Slather, modificaremos el archivo .travis.yml para instalar slather en la máquina y ejecutarlo tras la ejecución de los tests
  • 27. .travis.yml language: objective-c osx_image: xcode8.1 before_install: - gem install slather --no-ri --no-rdoc script: - xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES - slather A continuación, debemos crear un archivo .slather.yml para que slather sepa la configuración que debe utilizar para enviar los datos de cobertura a coveralls .slather.yml input_format: profdata coverage_service: coveralls xcodeproj: ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj scheme: swiftProtocolsAndGenerics Finalmente, modificaremos el archivo README.md para añadir un badge con información sobre la cobertura. La URL del badge de coveralls puede obtenerse en la propia web de coveralls, pulsando sobre el botón embed al lado del icono del badge y copiando la URL de markdown en nuestro archivo README.md
  • 28. Por lo que el archivo README.md quedaría como se muestra a continuación: README.md # swift-protocols-and-generics-workshop Workshop for Swift protocols &amp; generics [![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and- generics-workshop.svg?branch=master)](https://travis- ci.org/albertoirurueta/swift-protocols-and-generics-workshop) [![Coverage Status](https://coveralls.io/repos/github/albertoirurueta/swift- protocols-and-generics- workshop/badge.svg?branch=master)](https://coveralls.io/github/albertoirurueta /swift-protocols-and-generics-workshop?branch=master) Ahora sólo es necesario realizar un push, y automáticamente Travis ejecutará los tests y enviará la información de cobertura a Coveralls, y podremos acceder a ambos desde nuestra página de github.
  • 29.
  • 30. 5.3. Publicación de informes en github-pages Tal y como hemos visto en local, podemos generar informes de documentación, cobertura, tests en formato HTML. Sin embargo sería conveniente tener disponibles dichos informes directamente en la página web de nuestro proyecto. Por suerte, github permite publicar páginas web estáticas en la rama gh-pages, de modo que todo lo que se suba a esa rama aparecerá en la web de github.
  • 31. En la siguientes secciones veremos cómo podemos hacer que travis genere los informes y a continuación los suba a github pages para así tenerlos disponibles en la web de nuestro repositorio. 5.3.1. Configuración para publicar automáticamente en github-pages desde Travis Para poder utilizar github-pages deberemos poder hacer pushes en la rama gh-pages desde Travis, utilizando pasos similares a los indicados aquí: https://gist.github.com/domenic/ec8b0fc8ab45f39403dd. Para ello deberemos dar acceso a nuestro repositorio a Travis, lo cual implica proporcionar un usuario y contraseña o una clave SSH. Por seguridad, y más teniendo en cuenta que es un repositorio open source público, utilizaremos una funcionalidad de travis para almacenar la clave de forma segura en el repositorio. Primero necesitaremos crear una clave SSH. En la documentación de github se indica cómo hacerlo: https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/ Los pasos a seguir son los siguientes: 1. Crear una clave SSH en local. Utilizaremos el mismo correo electrónico de nuestra cuenta de github al crear la clave. Indicamos la ubicación donde guardar la clave (puede usarse la ubicación por defecto) y es importante no asignarle contraseña, ya que de lo contrario el comando ssh-add que ejecutará Travis requeriría introducirla manualmente. Este comando creará un archivo de clave privada y uno de clave pública. No es necesario añadir la clave al agente SSH tal y como indica la documentación de Github ya que no la usaremos en local para conectarnos a Github, si no que será Travis el que lo hará, por lo que el comando ssh-add lo ejecutará Travis.
  • 32. 2. Añadir en la web de Github la clave pública generada para tener acceso. Cuidado, la clave debe añadirse únicamente al repositorio que queremos dar acceso, no a nuestra cuenta, ya que entonces daríamos acceso a Travis todos los respositorios. Para ello vamos a los settings del repositorio. En la sección de opciones veremos que más abajo hay la opción para activar github-pages e incluso un editor online de las páginas. Nos aseguramos de que se usa la rama gh-pages o bien usamos la herramienta de generación de una página de inicio mediante el botón Launch automatic page generator.
  • 33. 3. Vamos a la sección de claves y pulsamos en el botón para añadir una clave. 4. Asignamos un nombre que identifique a la clave, le proporcionamos acceso de escritura, copiamos el contenido de la clave pública y la añadimos
  • 34. 5. Veremos una confirmación conforme la clave se ha añadido.
  • 35. 6. Copiamos los archivos de claves pública y privada en el repositorio si no lo habíamos hecho ya (ojo, no hacer commit aún ya que primero hay que encriptar la clave privada). 7. Comprobamos que ruby está instalado (por defecto en macOS ya viene instalado) 8. Instalamos el cliente de Travis (https://github.com/travis-ci/travis.rb) ejecutando el siguiente comando. Podemos comprobar que travis se ha instalado ejecutando el comando: 9. Desde la carpeta donde está la clave privada dentro del repositorio (el archivo github_key) encriptamos la clave privada con el siguiente comando: Si es la primera vez que ejecutamos Travis en el repositorio, travis nos lo indicará y nos preguntará si es correcto. Travis nos devolverá el comando que es necesario para desencriptar el archivo .enc generado. Debemos anotarlo ya que lo necesitaremos más adelante.
  • 36. openssl aes-256-cbc -K $encrypted_0d0cc787d66b_key -iv $encrypted_0d0cc787d66b_iv -in github_key.enc -out github_key -d 10. Veremos que se ha creado el archivo github_key.enc que contiene el archivo github_key pero encriptado, por lo que podemos borrar el archivo github_key original, ya que únicamente subiremos al repositorio en archivo github_key.enc. 11. Modificamos el archivo .travis.yml para añadir variables de entorno con los valores para desencriptar la clave privada, y añadimos el comando ./publish-gh-pages.sh para ejecutar un script que crearemos para publicar en github-pages .travis.yml language: objective-c osx_image: xcode8.1 env: global: - ENCRYPTION_LABEL: "0d0cc787d66b" - COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com" before_install: - gem install slather --no-ri --no-rdoc script: - xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES - slather - ./publish-gh-pages.sh
  • 38. 13. Otorgamos permisos de ejecución al archivo de script que hemos creado, de lo contrario Travis no podrá ejecutarlo 1. Creamos un token de acceso en la cuenta de github, para ello vamos a settings pulsando sobre la imagen de nuestra cuenta.
  • 39. 2. Seleccionamos la opción de Personal access tokens y pulsamos el botón de generar un nuevo token. Asignamos un nombre al token y los permisos que le queremos dar (sólo de acceso a los repositorios) 3. Copiamos el token devuelto por github, ya que no lo podremos consultar más adelante.
  • 40. Desde el directorio del repositorio ejecutamos por línea de comando lo siguiente: Este comando se encarga de generar un string encriptado mediante travis. Este string lo podemos luego poner como una variable de entorno en el archivo .travis.yml, para ello debemos copiar la respuesta de este comando en el archivo .travis.yml, tal y como se muestra a continuación: .travis.yml
  • 41. language: objective-c osx_image: xcode8.1 env: global: - secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW 6D4cGUuoiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2 fGKU0ekczoOns9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48 AvOZrjogCBoJNmVup8gtSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OE p1LcwEWzGIKQ9nv8Ithr89DoG2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0 tfqnO2sGpDM+B/ApZvom/CC71kSCvYWnFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3 hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fHsxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FO S3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEqxfvfauioWTxFuwo6kjHUjPqvqOAE4 zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhyJyWBJU2ViX8/WOCEkrog+Hm Z/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM=" - ENCRYPTION_LABEL: "0d0cc787d66b" - COMMIT_AUTHOR_EMAIL: alberto@irurueta.com before_install: - gem install slather --no-ri --no-rdoc - gem install jazzy --no-ri --no-rdoc - gem install xcpretty --no-ri --no-rdoc script: - set -o pipefail && xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug - enableCodeCoverage=YES | tee xcodebuild.log | xcpretty -r html - ./publish-gh-pages.sh after_success: - cd $TRAVIS_BUILD_DIR && slather Una vez hecho este cambio tendremos acceso a la variable de entorno GITHUB_OAUTH_TOKEN desencriptada sin necesidad de subir el token de forma pública a nuestro repositorio A continuación, cambiamos la última línea del script publish-gh-pages.sh para realizar el push mediante https utilizando un usuario con acceso al repositorio (no copiar el que hay aquí) y el token desencriptado en la variable de entorno GITHUB_OAUTH_TOKEN como contraseña.
  • 42. Con estos pasos ya estaría todo configurado para que Travis subiera los informes que indiquemos en la función doStuff en gihub-pages 5.3.1. Publicación de informes de documentación de Jazzy en github-pages Ya hemos visto cómo generar informes web de documentación mediante Jazzy, ahora vamos a modificar la función doStuff en el archivo publish-gh-pages para que Travis los genere y los publique en github-pages.
  • 43. Puesto que utilizamos jazzy, también tendremos que modificar el archivo .travis.yml para indicarle a travis que debe instalar jazzy
  • 44. .travis.yml language: objective-c osx_image: xcode8.1 env: global: - secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW6D4cGUu oiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2fGKU0ekczoOns 9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48AvOZrjogCBoJNmVup8g tSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OEp1LcwEWzGIKQ9nv8Ithr89DoG 2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0tfqnO2sGpDM+B/ApZvom/CC71kSCvYW nFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fH sxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FOS3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEq xfvfauioWTxFuwo6kjHUjPqvqOAE4zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhy JyWBJU2ViX8/WOCEkrog+HmZ/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM=" - ENCRYPTION_LABEL: "0d0cc787d66b" - COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com" before_install: - gem install slather --no-ri --no-rdoc - gem install jazzy --no-ri --no-rdoc script: - xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES - slather - ./publish-gh-pages.sh Hacemos push y ahora Travis podrá generar el informe de documentación y publicarlo en la carpeta docs de la rama gh-pages 5.3.2. Publicación de informes de tests de xcpretty en github-pages Del mismo modo, tal y como hemos visto, podemos modificar doStuff en el archivo publish-gh- pages para que Travis nos publique el informe de xcpretty en github-pages. Para ello debemos modificar el archivo .travis.yml para que en lugar de ejecutar xcodebuild directamente, haga un pipe con xcpretty tal y como hemos visto. Para poder utilizar xcpretty le tendremos que decir a Travis que primero lo instale. Además, para que el estado de build sea el correcto, tal y como se indica en la documentación de xcpretty añadiendo set -o pipefail && antes del comando xcodebuild en el archivo .travis.yml, tal. Puesto que se usa pipefail, ahora será necesario ejecutar slather por separado tras finalizar el script correctamente, haciendo primero cd al directorio de compilación de Travis
  • 45. .travis.yml language: objective-c osx_image: xcode8.1 env: global: - secure: "l7sVCVmEoGW+NMQkx6F7XFM7HXVhrmDGE5mwqHNy2qZ/zkOOFvhh2/fbxiCDsW6D4cGUu oiwtp+aL5I7x/R2RfLU4KEDnuk+Nu8OwEXKpdXlNKCt/sbjokrJieuhyufHFpD6d2fGKU0ekczoOns 9Vvl0Sa8MILaffEsW8R8cEMYC6jReb0d9el/CfFb/4N9R2gEK5zXi9v2z48AvOZrjogCBoJNmVup8g tSTjbnJWo431FSlF8dlFS7bhemn/cKBfLEvyK4bhlLogYgGAwH5OEp1LcwEWzGIKQ9nv8Ithr89DoG 2YG48/n+vD2fpRaThuBjnHFmLvaTwGj0GWcGjrk+xkrkch0tfqnO2sGpDM+B/ApZvom/CC71kSCvYW nFW5fRcXsXF6atvwbgP7iKlw/Ju66WewF7wANgyK3hguhDy2RSUgUTYDvMuH8KpxmI6FcciN0GB0fH sxG9mf2laGNzLFzqO329RmXKHkxdV1wD/FOS3498z9XyDulu/AvWdU73tvOEgPeqCTwEXkV8tP5bEq xfvfauioWTxFuwo6kjHUjPqvqOAE4zSFB/k9XdHfV8OSJyfNh0+MoHWFBspHhqIErX3JnlFhfPvJhy JyWBJU2ViX8/WOCEkrog+HmZ/Sal5mUz8eRraqVVn4IFq1t8oP48ZOkAjM3am+8uuQpM=" - ENCRYPTION_LABEL: "0d0cc787d66b" - COMMIT_AUTHOR_EMAIL: "alberto@irurueta.com" before_install: - gem install slather --no-ri --no-rdoc - gem install jazzy --no-ri --no-rdoc - gem install xcpretty --no-ri --no-rdoc script: - set -o pipefail && xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee xcodebuild.log | xcpretty -r html - ./publish-gh-pages.sh after_success: - cd $TRAVIS_BUILD_DIR && slather Puesto que xcpretty guarda el resultado del informe en la carpeta build/reports, y el arcivo de script publish-gh-pages.sh publica todo lo que hay en la carpeta out a github-pages, deberemos modificar el archivo de script para mover el contenido de build/reports dentro de la carpeta out, de este modo:
  • 46. Ahora, tras realizar el push tendremos el informe de tests subido a github-pages. 5.3.3. Enlazar los informes de github-pages. Aunque hemos creado los informes y los hemos publicado en github-pages, no los podemos ver de forma cómoda porque no hay un enlace para verlos, para ello podemos modificar el archivo index.html de github-pages o bien el archivo README.md para colocar un enlace a los informes. README.md # swift-protocols-and-generics-workshop Workshop for Swift protocols &amp; generics [![Build Status](https://travis-ci.org/albertoirurueta/swift-protocols-and- generics-workshop.svg?branch=master)](https://travis- ci.org/albertoirurueta/swift-protocols-and-generics-workshop) [![Coverage Status](https://coveralls.io/repos/github/albertoirurueta/swift- protocols-and-generics- workshop/badge.svg?branch=master)](https://coveralls.io/github/albertoirurueta /swift-protocols-and-generics-workshop?branch=master) [Code Documentation](https://albertoirurueta.github.io/swift-protocols-and- generics-workshop/docs/index.html) [Test report](https://albertoirurueta.github.io/swift-protocols-and-generics- workshop/build/reports/tests.html) [Github pages](https://albertoirurueta.github.io/swift-protocols-and-generics- workshop/)
  • 47. 5.4. Configuración de Jenkins Hasta ahora hemos visto cómo configurar un servicio de integración continua en el cloud mediante Travis, el cual se integra con Github y es gratuito para proyectos opensource. Para proyectos privados esto no es una solución viable, (a no ser que tengamos cuentas de pago en Github y Travis), pero es posible montar un servidor Jenkins para hacer exactamente lo mismo. En Visual tenemos nuestro servidor Jenkins (http://jenkins.oficina.visual-engin.com). Jenkins no es más que un servidor capaz de ejecutar scripts de forma programada (cada cierto intervalo de tiempo o cuando hay un cambio en el repositorio) y de forma distribuida (ya que puede ejecutar las tareas en nodos esclavos). Jenkins es muy modular y configurable, y para ellos es posible instalarle una infinidad de plugins. En nuestro caso necesitaremos los siguientes plugins (algunos ya vienen instalados por defecto):  SCM y GIT para obtener datos del repositorio  Junit: para analizar el archivo junit.xml generado por xcpretty con los resultados de los tests  Cobertura: para analizar el archivo xml de cobertura generado por slather  Publicación HTML: para publicar informes HTML Para configurar el proyecto, los pasos a seguir son los siguientes: 1. Añadimos una tarea nueva con un proyecto de estilo libre. 2. Asignamos un nombre al proyecto. 3. Para no hace un uso excesivo de disco duro activamos desechar ejecuciones antiguas y ponemos un número razonable de ejecuciones a mantener en disco (ej: 4) 4. Si el repositorio es github, podemos activar la casilla y poner la URL al repositorio. Esto nos permitirá ir a la web del repo en github 5. Activar la casilla restringir donde se puede ejecutar el proyecto e indicad una máquina de un nodo que esté previamente configurado en Jenkins. 6. En origen de fuente, seleccionamos git, introducimos la URL del repositorio e indicamos la rama de la cual queremos obtener el código. 7. En disparadores de ejecuciones, podemos activar las casillas para detectar un cambio en bitbucket o github, pero para que funcionen el servidor jenkins ha de ser accesible públicamente (no es el caso en Visual), por lo que podemos activar la casilla para comprobar el repositorio periódicamente (por ejemplo para comprobarlo cada 15 minutos debemos introducir H/15 * * * *) 8. Es conveniente activar la casilla para detener la ejecución si se atasca. Esto es útil para que Jenkins no deje el esclavo bloqueado indefinidamente en el caso de que algo falle (los tests peten, se cierre el simulador, etc). De este modo, si no hay actividad por consola en un determinado tiempo (ej: 5 minutos = 300 segundos), se detiene la ejecución. 9. En la sección de ejecutar, añadir un paso para ejecutar la linea de comandos (shell) y poner los siguientes comandos de shell:
  • 48. #ejecutar tests con informe en ./build/reports/junit.xml xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES | tee xcodebuild.log | /usr/local/bin/xcpretty -r junit #generar documentación en ./docs/index.html /usr/local/bin/jazzy --clean --author Alberto Irurueta --github_url https://github.com/albertoirurueta/swift-protocols-and-generics-workshop -- xcodebuild-arguments - project,./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj,- scheme,swiftProtocolsAndGenerics --module swiftProtocolsAndGenerics --output docs #generar informe de cobertura /usr/local/bin/slather coverage --cobertura-xml --output-directory ./coverage -- scheme swiftProtocolsAndGenerics ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj /usr/local/bin/slather coverage --html --scheme swiftProtocolsAndGenerics ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj 10. En la sección de acciones para después, añadir: a) Publicar informes de "cobertura". El archivo estará ubicado en: coverage/cobertura.xml b) Publicar los resultados de test de Junit. El archivo estará ubicado en: build/reports/junit.xml c) Publish HTML reports. i. Informe de documentación de código. Directorio: docs Index page(s): index.html Report title: Code Documentation ii. Informe HTML de cobertura Directorio: html Index page(s): index.html Report title: Coverage Material de interés Página oficial de Swift: https://swift.org (aquí encontraréis toda la documentación oficial de Swift y el libro oficial en formato ebook en la sección de documentación donde encontraréis información sobre Protocols). Documentar código Swift: http://www.appcoda.com/swift-markdown/ Publicar documentación en github: http://www.jessesquires.com/swift-documentation/ Testing y cobertura de código en Xcode: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/ testing_with_xcode/chapters/07-code_coverage.html Configurar Travis: https://www.raywenderlich.com/109418/travis-ci-tutorial Instalar slather: https://github.com/SlatherOrg/slather
  • 49. Generar informes web de los tests: https://github.com/fastlane/fastlane/tree/master/scan Github pages: https://pages.github.com Publicar de forma automática en Github-pages con Travis: https://gist.github.com/domenic/ec8b0fc8ab45f39403dd Integración continua y cobertura con Jenkins: https://pspdfkit.com/blog/2016/continuous-ios- code-coverage-with-jenkins-and-slather/ Generar ipa's en Travis y distribuirlos con Testflight o HockeyApp: https://www.objc.io/issues/6- build-tools/travis-ci/ NOTA: Aunque en este workshop no lo hemos visto, también es posible utilizar cocoapods con Travis, para ello habría que descomentar las líneas comentadas mediante # en el siguiente archivo de travis, y modificar la llamada de xcodebuild para que se utilice un workspace en lugar de un proyecto language: objective-c osx_image: xcode8.1 #cache: cocoapods before_install: #- gem install cocoapods --no-ri --no-rdoc - gem install slather --no-ri --no-rdoc script: - xcodebuild clean test -project ./swiftProtocolsAndGenerics/swiftProtocolsAndGenerics.xcodeproj -scheme swiftProtocolsAndGenerics -destination 'platform=iOS Simulator,name=iPhone 7' TEST_AFTER_BUILD=YES -configuration Debug -enableCodeCoverage=YES - slather