<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://1984.lsi.us.es/wiki-egc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ajramirez</id>
		<title>Wiki de EGC - Contribuciones del usuario [es]</title>
		<link rel="self" type="application/atom+xml" href="https://1984.lsi.us.es/wiki-egc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ajramirez"/>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php/Especial:Contribuciones/Ajramirez"/>
		<updated>2026-04-10T10:58:53Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.29.0</generator>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9474</id>
		<title>Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9474"/>
				<updated>2022-11-23T16:21:59Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
'''Nota: En esta práctica se hacen uso de los servicios de CleverCloud, el cual no ofrece capa gratuita pero sí da [https://www.clever-cloud.com/blog/company/2015/04/14/why-isnt-t-there-a-free-tier-in-clever-cloud/ un periodo de prueba] (Actualmente da 20€ para nuevas cuentas)'''&lt;br /&gt;
&lt;br /&gt;
'''Por lo tanto: '''&lt;br /&gt;
# '''Recomendamos no introducir nuestros datos bancarios para que no se nos haga ningún cargo involuntario tras el periodo de prueba.'''&lt;br /&gt;
# '''La realización de la práctica es voluntaria, aunque los conceptos que se enseñan en ella sí son materia de estudio.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
* Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contraseña.&lt;br /&gt;
* Asociar una llave SSH a la cuenta de CleverCloud en el [https://console.clever-cloud.com/users/me/ssh-keys menú de gestión de SSH]. &lt;br /&gt;
* Instalar CleverCloud CLI sobre Ubuntu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
# Instalamos llave de cifrado:&lt;br /&gt;
curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;quot; | sudo tee -a /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
# Instalamos CleverCloud tools&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clever-tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Comprobar que la instalación es correcta con &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
clever login&lt;br /&gt;
# Se abrirá un navegador con el login de CleverCloud.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Despliegue puntual en CleverCloud =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1. Crear aplicación ==&lt;br /&gt;
* Desde el &amp;quot;espacio personal&amp;quot; de CleverCloud cree una aplicación. Use la opción &amp;quot;Create a Brand new App&amp;quot;.&lt;br /&gt;
* Elija una aplicación de tipo &amp;quot;Python&amp;quot; e incluya &amp;quot;Postgress&amp;quot; como Add-on.&lt;br /&gt;
 ¿Para qué sirve el hecho de escoger un &amp;quot;Plan&amp;quot; o una &amp;quot;Localización&amp;quot; concreta?&lt;br /&gt;
* Seguir las instrucciones para hacer un push de nuestros código de decide hacia CleverCloud.&lt;br /&gt;
* Visualizar el log de la aplicación&lt;br /&gt;
 ¿Por qué está fallando?&lt;br /&gt;
 ¿Cuál es la URL dónde debería estar la aplicación desplegada en CleverCloud?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. Archivo de configuración de CleverCloud ==&lt;br /&gt;
CleverCloud realiza dos etapas:&lt;br /&gt;
# Build: Prepara el entorno, instala las dependencias, etc.&lt;br /&gt;
# Run: Despliega y expone la aplicación.&lt;br /&gt;
Parte de la configuración de estas etapas se hace en el archivo de configuración de CleverCloud. Para Python, este archivo deberá estar en &amp;lt;code&amp;gt; clevercloud/python.json &amp;lt;/code&amp;gt;. &lt;br /&gt;
* Cree ese archivo con el siguiente contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;build&amp;quot;: {&lt;br /&gt;
        &amp;quot;folder&amp;quot;: &amp;quot;decide&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;deploy&amp;quot;: {&lt;br /&gt;
        &amp;quot;module&amp;quot;: &amp;quot;decide.wsgi:application&amp;quot;,&lt;br /&gt;
        &amp;quot;managetasks&amp;quot;: [&lt;br /&gt;
			&amp;quot;collectstatic --noinput&amp;quot;,&lt;br /&gt;
			&amp;quot;migrate&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Como en CleverCloud no habrá local_settings, editaremos el &amp;lt;code&amp;gt; decide/settings.py &amp;lt;/code&amp;gt; para que contenga una configuración válida para CleverCloud. Estos son los cambios principales que habrá que hacer:&lt;br /&gt;
# Permitir conexiones más allá de localhost: &amp;lt;code&amp;gt;ALLOWED_HOSTS = ['*'] &amp;lt;/code&amp;gt;&lt;br /&gt;
# Actualizar la url en &amp;lt;code&amp;gt; BASEURL &amp;lt;/code&amp;gt;&lt;br /&gt;
# Añadir el bloque de API={ …} apuntando a base url. Puede copiarlo de algún local_settings.py&lt;br /&gt;
# Específicar las rutas de los archivos estáticos &amp;lt;code&amp;gt;STATIC_URL = '/static/'&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;STATIC_ROOT= 'static/'&amp;lt;/code&amp;gt;&lt;br /&gt;
# El 'migrate' no funcionará si la base de datos no está bien configurada. Para ello puede observar en su aplicación en CleverCloud que hay una configuración de variables de entorno para sus Add-on de postgres. # Desde el settings.py puede acceder al valor de dichas variables con &amp;lt;code&amp;gt;os.environ.get(NOMBRE_VARIABLE)&amp;lt;/code&amp;gt;. Actualize el objeto &amp;quot;DATABASES&amp;quot; del settings.py para que acceda a dichas variables.&lt;br /&gt;
*Vuelva a realizar un push a CleverCloud (no olvide hacer commit antes).&lt;br /&gt;
 ¿Por qué sigue sin funcionar?&lt;br /&gt;
* El requirements.txt no lo está identificando al buscarlo, por defecto, dentro de la carpeta indicada en &amp;quot;folder&amp;quot;. Copie el requirements.txt dentro de la carpeta decide (También puede especificar la ruta del requirements.txt usando la variable de entorno CC_PIP_REQUIREMENTS_FILE, ver siguiente ejercicio). &lt;br /&gt;
== Ejercicio 3. Variables de entorno de CleverCloud ==&lt;br /&gt;
Hay otra parte de la configuración de CleverCloud que ha de especificarse dentro las variables de entorno de la aplicación. &lt;br /&gt;
* Para que la aplicación se levante correctamente, ha de usar la versión de python 3.8 en la variable CC_PYTHON_VERSION.&lt;br /&gt;
* Para indicar qué url dirige a los archivo estáticos, use STATIC_URL_PREFIX con el valor /static. Por ejemplo, el CSS de la aplicación.&lt;br /&gt;
* Para indicar la ruta donde se almacenarán dichos archivos, use STATIC_FILES_PATH con el valor decide/static/.&lt;br /&gt;
* Pulse sobre &amp;quot;Update changes&amp;quot; y reinicie la aplicacion desde el menú &amp;quot;Overview&amp;quot;.&lt;br /&gt;
 ¿Puede ya nevegar hasta el menú de administración de decide?&lt;br /&gt;
* Cree el superusuario accediendo por ssh con:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -t ssh@sshgateway-clevercloud-customers.services.clever-cloud.com &amp;lt;&amp;lt;app_name&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
El código de la aplicación (manage.py) se encuentra en una carpeta con el nombre de su aplicación.&lt;br /&gt;
= Despliege continuo =&lt;br /&gt;
== Ejercicio 4. CleverCloud y GitHub Actions==&lt;br /&gt;
Para integrar GitHub Actions y CleverCloud cree un workflow de GitHub Actions nuevo, con un solo job.&lt;br /&gt;
* Use este workflow a modo de ejemplo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: Deploy example&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest    &lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/checkout@v2&lt;br /&gt;
        with:&lt;br /&gt;
          fetch-depth: 0&lt;br /&gt;
      - uses: 47ng/actions-clever-cloud@v1.3.1&lt;br /&gt;
        with:&lt;br /&gt;
          appID: app_fd57a008-7dbd-4636-8b34-af951947911f&lt;br /&gt;
        env:&lt;br /&gt;
          CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}&lt;br /&gt;
          CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Añada la dos secrets al proyecto de GitHub. Estas secrets se obtiene en el proceso de hacer &amp;lt;code&amp;gt;clever login&amp;lt;/code&amp;gt;. Aunque lo hiciera en los prerrequisitos, puede repetirlo ahora.&lt;br /&gt;
* Recuerde que necesita pushear este código (incluídos los cambios anteriores) a su repositorio en GitHub.&lt;br /&gt;
 ¿Ha funcionado el workflow?&lt;br /&gt;
 ¿Ha estado la aplicación en algún momento caída?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. Condiciones de despliegue ==&lt;br /&gt;
En GitHub Actions, los workflows tienen la capacidad de definir el/los evento/s que los disparan con la clausua &amp;quot;on:&amp;quot;.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags aquí]] más detalles de dicha cláusula. &lt;br /&gt;
Sin embargo eso no se puede especificar a nivel de job o de step.  &lt;br /&gt;
A esos niveles pueden expresarse sentencias &amp;quot;if&amp;quot; que permiten ejecutarlas condicionalmente.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsif aquí]] más detalles de dicha cláusula. &lt;br /&gt;
&lt;br /&gt;
* Integra el job de &amp;quot;deploy&amp;quot; en el workflow que creaste en prácticas anteriores.&lt;br /&gt;
* Para hacer que solo se lance el job &amp;quot;deploy&amp;quot; cuando estemos en una rama concreta, por ejemplo, &amp;quot;master&amp;quot;, incluiya lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
deploy:&lt;br /&gt;
    if: ${{github.ref == 'refs/heads/master' }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Haga push del nuevo workflow incluyen el job de deploy y su condición. Posterioremente, haz un push de algún otro código a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
 ¿Se lanza el job &amp;quot;deploy&amp;quot;? ¿En que estado se queda?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modifica la clausula &amp;quot;on:&amp;quot; para que se lance el workflow solo cuando se hiciera push a la rama master.&lt;br /&gt;
Despues de hacer un push del workflow, haz un push a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
&lt;br /&gt;
= Ejercicio 6. Creación de incidencias =&lt;br /&gt;
# El usuario “superuser” no se crea dentro del ciclo de despliegue continuo y obliga a hacer una tarea manual en los nuevos despliegues (salvo cuando se mantiene la BD).&lt;br /&gt;
# Crear una incidencia según las [[Gestión de incidencias | recomendaciones vistas en clase]] para el error que obtenemos al votar en heroku.&lt;br /&gt;
# Asegurarse que la incidencia creada incluye, al menos, un título descriptivo, información de qué es lo que ocurre y cómo puede reproducirse el error.&lt;br /&gt;
---------------&lt;br /&gt;
* Transparencias: [[Archivo:06-PaaSyDespliegueContinuo.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9473</id>
		<title>Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9473"/>
				<updated>2022-11-21T12:59:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
'''Nota: En esta práctica se hacen uso de los servicios de CleverCloud, el cual no ofrece capa gratuita pero sí da [https://www.clever-cloud.com/blog/company/2015/04/14/why-isnt-t-there-a-free-tier-in-clever-cloud/ un periodo de prueba] (Actualmente da 20€ para nuevas cuentas)'''&lt;br /&gt;
&lt;br /&gt;
'''Por lo tanto: '''&lt;br /&gt;
# '''Recomendamos no introducir nuestros datos bancarios para que no se nos haga ningún cargo involuntario tras el periodo de prueba.'''&lt;br /&gt;
# '''La realización de la práctica es voluntaria, aunque los conceptos que se enseñan en ella sí son materia de estudio.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
* Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contraseña.&lt;br /&gt;
* Asociar una llave SSH a la cuenta de CleverCloud en el [https://console.clever-cloud.com/users/me/ssh-keys menú de gestión de SSH]. &lt;br /&gt;
* Instalar CleverCloud CLI sobre Ubuntu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
# Instalamos llave de cifrado:&lt;br /&gt;
curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;quot; | sudo tee -a /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
# Instalamos CleverCloud tools&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clever-tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Comprobar que la instalación es correcta con &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
clever login&lt;br /&gt;
# Se abrirá un navegador con el login de CleverCloud.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Despliegue puntual en CleverCloud =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1. Crear aplicación ==&lt;br /&gt;
* Desde el &amp;quot;espacio personal&amp;quot; de CleverCloud cree una aplicación. Use la opción &amp;quot;Create a Brand new App&amp;quot;.&lt;br /&gt;
* Elija una aplicación de tipo &amp;quot;Python&amp;quot; e incluya &amp;quot;Postgress&amp;quot; como Add-on.&lt;br /&gt;
 ¿Para qué sirve el hecho de escoger un &amp;quot;Plan&amp;quot; o una &amp;quot;Localización&amp;quot; concreta?&lt;br /&gt;
* Seguir las instrucciones para hacer un push de nuestros código de decide hacia CleverCloud.&lt;br /&gt;
* Visualizar el log de la aplicación&lt;br /&gt;
 ¿Por qué está fallando?&lt;br /&gt;
 ¿Cuál es la URL dónde debería estar la aplicación desplegada en CleverCloud?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. Archivo de configuración de CleverCloud ==&lt;br /&gt;
CleverCloud realiza dos etapas:&lt;br /&gt;
# Build: Prepara el entorno, instala las dependencias, etc.&lt;br /&gt;
# Run: Despliega y expone la aplicación.&lt;br /&gt;
Parte de la configuración de estas etapas se hace en el archivo de configuración de CleverCloud. Para Python, este archivo deberá estar en &amp;lt;code&amp;gt; clevercloud/python.json &amp;lt;/code&amp;gt;. &lt;br /&gt;
* Cree ese archivo con el siguiente contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;build&amp;quot;: {&lt;br /&gt;
        &amp;quot;folder&amp;quot;: &amp;quot;decide&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;deploy&amp;quot;: {&lt;br /&gt;
        &amp;quot;module&amp;quot;: &amp;quot;decide.wsgi:application&amp;quot;,&lt;br /&gt;
        &amp;quot;managetasks&amp;quot;: [&lt;br /&gt;
			&amp;quot;collectstatic --noinput&amp;quot;,&lt;br /&gt;
			&amp;quot;migrate&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Como en CleverCloud no habrá local_settings, editaremos el &amp;lt;code&amp;gt; decide/settings.py &amp;lt;/code&amp;gt; para que contenga una configuración válida para CleverCloud. Estos son los cambios principales que habrá que hacer:&lt;br /&gt;
# Permitir conexiones más allá de localhost: &amp;lt;code&amp;gt;ALLOWED_HOSTS = ['*'] &amp;lt;/code&amp;gt;&lt;br /&gt;
# Actualizar la url en &amp;lt;code&amp;gt; BASEURL &amp;lt;/code&amp;gt;&lt;br /&gt;
# Añadir el bloque de API={ …} apuntando a base url. Puede copiarlo de algún local_settings.py&lt;br /&gt;
# Específicar las rutas de los archivos estáticos &amp;lt;code&amp;gt;STATIC_URL = '/static/'&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;STATIC_ROOT= 'static/'&amp;lt;/code&amp;gt;&lt;br /&gt;
# El 'migrate' no funcionará si la base de datos no está bien configurada. Para ello puede observar en su aplicación en CleverCloud que hay una configuración de variables de entorno para sus Add-on de postgres. # Desde el settings.py puede acceder al valor de dichas variables con &amp;lt;code&amp;gt;os.environ.get(NOMBRE_VARIABLE)&amp;lt;/code&amp;gt;. Actualize el objeto &amp;quot;DATABASES&amp;quot; del settings.py para que acceda a dichas variables.&lt;br /&gt;
*Vuelva a realizar un push a CleverCloud (no olvide hacer commit antes).&lt;br /&gt;
 ¿Por qué sigue sin funcionar?&lt;br /&gt;
* El requirements.txt no lo está identificando al buscarlo, por defecto, dentro de la carpeta indicada en &amp;quot;folder&amp;quot;. Copie el requirements.txt dentro de la carpeta decide (También puede especificar la ruta del requirements.txt usando la variable de entorno CC_PIP_REQUIREMENTS_FILE, ver siguiente ejercicio). &lt;br /&gt;
== Ejercicio 3. Variables de entorno de CleverCloud ==&lt;br /&gt;
Hay otra parte de la configuración de CleverCloud que ha de especificarse dentro las variables de entorno de la aplicación. &lt;br /&gt;
* Para que la aplicación se levante correctamente, ha de usar la versión de python 3.8 en la variable CC_PYTHON_VERSION.&lt;br /&gt;
* Para indicar qué url dirige a los archivo estáticos, use STATIC_URL_PREFIX con el valor /static. Por ejemplo, el CSS de la aplicación.&lt;br /&gt;
* Para indicar la ruta donde se almacenarán dichos archivos, use STATIC_FILES_PATH con el valor static/.&lt;br /&gt;
* Pulse sobre &amp;quot;Update changes&amp;quot; y reinicie la aplicacion desde el menú &amp;quot;Overview&amp;quot;.&lt;br /&gt;
 ¿Puede ya nevegar hasta el menú de administración de decide?&lt;br /&gt;
* Cree el superusuario accediendo por ssh con:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -t ssh@sshgateway-clevercloud-customers.services.clever-cloud.com &amp;lt;&amp;lt;app_name&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
El código de la aplicación (manage.py) se encuentra en una carpeta con el nombre de su aplicación.&lt;br /&gt;
= Despliege continuo =&lt;br /&gt;
== Ejercicio 4. CleverCloud y GitHub Actions==&lt;br /&gt;
Para integrar GitHub Actions y CleverCloud cree un workflow de GitHub Actions nuevo, con un solo job.&lt;br /&gt;
* Use este workflow a modo de ejemplo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: Deploy example&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest    &lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/checkout@v2&lt;br /&gt;
        with:&lt;br /&gt;
          fetch-depth: 0&lt;br /&gt;
      - uses: 47ng/actions-clever-cloud@v1.3.1&lt;br /&gt;
        with:&lt;br /&gt;
          appID: app_fd57a008-7dbd-4636-8b34-af951947911f&lt;br /&gt;
        env:&lt;br /&gt;
          CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}&lt;br /&gt;
          CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Añada la dos secrets al proyecto de GitHub. Estas secrets se obtiene en el proceso de hacer &amp;lt;code&amp;gt;clever login&amp;lt;/code&amp;gt;. Aunque lo hiciera en los prerrequisitos, puede repetirlo ahora.&lt;br /&gt;
* Recuerde que necesita pushear este código (incluídos los cambios anteriores) a su repositorio en GitHub.&lt;br /&gt;
 ¿Ha funcionado el workflow?&lt;br /&gt;
 ¿Ha estado la aplicación en algún momento caída?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. Condiciones de despliegue ==&lt;br /&gt;
En GitHub Actions, los workflows tienen la capacidad de definir el/los evento/s que los disparan con la clausua &amp;quot;on:&amp;quot;.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags aquí]] más detalles de dicha cláusula. &lt;br /&gt;
Sin embargo eso no se puede especificar a nivel de job o de step.  &lt;br /&gt;
A esos niveles pueden expresarse sentencias &amp;quot;if&amp;quot; que permiten ejecutarlas condicionalmente.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsif aquí]] más detalles de dicha cláusula. &lt;br /&gt;
&lt;br /&gt;
* Integra el job de &amp;quot;deploy&amp;quot; en el workflow que creaste en prácticas anteriores.&lt;br /&gt;
* Para hacer que solo se lance el job &amp;quot;deploy&amp;quot; cuando estemos en una rama concreta, por ejemplo, &amp;quot;master&amp;quot;, incluiya lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
deploy:&lt;br /&gt;
    if: ${{github.ref == 'refs/heads/master' }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Haga push del nuevo workflow incluyen el job de deploy y su condición. Posterioremente, haz un push de algún otro código a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
 ¿Se lanza el job &amp;quot;deploy&amp;quot;? ¿En que estado se queda?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modifica la clausula &amp;quot;on:&amp;quot; para que se lance el workflow solo cuando se hiciera push a la rama master.&lt;br /&gt;
Despues de hacer un push del workflow, haz un push a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
&lt;br /&gt;
= Ejercicio 6. Creación de incidencias =&lt;br /&gt;
# El usuario “superuser” no se crea dentro del ciclo de despliegue continuo y obliga a hacer una tarea manual en los nuevos despliegues (salvo cuando se mantiene la BD).&lt;br /&gt;
# Crear una incidencia según las [[Gestión de incidencias | recomendaciones vistas en clase]] para el error que obtenemos al votar en heroku.&lt;br /&gt;
# Asegurarse que la incidencia creada incluye, al menos, un título descriptivo, información de qué es lo que ocurre y cómo puede reproducirse el error.&lt;br /&gt;
---------------&lt;br /&gt;
* Transparencias: [[Archivo:06-PaaSyDespliegueContinuo.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:06-PaaSyDespliegueContinuo.pdf&amp;diff=9472</id>
		<title>Archivo:06-PaaSyDespliegueContinuo.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:06-PaaSyDespliegueContinuo.pdf&amp;diff=9472"/>
				<updated>2022-11-21T04:14:14Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9471</id>
		<title>Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9471"/>
				<updated>2022-11-21T04:06:44Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
* Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contraseña.&lt;br /&gt;
* Asociar una llave SSH a la cuenta de CleverCloud en el [https://console.clever-cloud.com/users/me/ssh-keys menú de gestión de SSH]. &lt;br /&gt;
* Instalar CleverCloud CLI sobre Ubuntu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
# Instalamos llave de cifrado:&lt;br /&gt;
curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;quot; | sudo tee -a /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
# Instalamos CleverCloud tools&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clever-tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Comprobar que la instalación es correcta con &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
clever login&lt;br /&gt;
# Se abrirá un navegador con el login de CleverCloud.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Despliegue puntual en CleverCloud =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1. Crear aplicación ==&lt;br /&gt;
* Desde el &amp;quot;espacio personal&amp;quot; de CleverCloud cree una aplicación. Use la opción &amp;quot;Create a Brand new App&amp;quot;.&lt;br /&gt;
* Elija una aplicación de tipo &amp;quot;Python&amp;quot; e incluya &amp;quot;Postgress&amp;quot; como Add-on.&lt;br /&gt;
 ¿Para qué sirve el hecho de escoger un &amp;quot;Plan&amp;quot; o una &amp;quot;Localización&amp;quot; concreta?&lt;br /&gt;
* Seguir las instrucciones para hacer un push de nuestros código de decide hacia CleverCloud.&lt;br /&gt;
* Visualizar el log de la aplicación&lt;br /&gt;
 ¿Por qué está fallando?&lt;br /&gt;
 ¿Cuál es la URL dónde debería estar la aplicación desplegada en CleverCloud?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. Archivo de configuración de CleverCloud ==&lt;br /&gt;
CleverCloud realiza dos etapas:&lt;br /&gt;
# Build: Prepara el entorno, instala las dependencias, etc.&lt;br /&gt;
# Run: Despliega y expone la aplicación.&lt;br /&gt;
Parte de la configuración de estas etapas se hace en el archivo de configuración de CleverCloud. Para Python, este archivo deberá estar en &amp;lt;code&amp;gt; clevercloud/python.json &amp;lt;/code&amp;gt;. &lt;br /&gt;
* Cree ese archivo con el siguiente contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;build&amp;quot;: {&lt;br /&gt;
        &amp;quot;folder&amp;quot;: &amp;quot;decide&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;deploy&amp;quot;: {&lt;br /&gt;
        &amp;quot;module&amp;quot;: &amp;quot;decide.wsgi:application&amp;quot;,&lt;br /&gt;
        &amp;quot;managetasks&amp;quot;: [&lt;br /&gt;
			&amp;quot;collectstatic --noinput&amp;quot;,&lt;br /&gt;
			&amp;quot;migrate&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Como en CleverCloud no habrá local_settings, editaremos el &amp;lt;code&amp;gt; decide/settings.py &amp;lt;/code&amp;gt; para que contenga una configuración válida para CleverCloud. Estos son los cambios principales que habrá que hacer:&lt;br /&gt;
# Permitir conexiones más allá de localhost: &amp;lt;code&amp;gt;ALLOWED_HOSTS = ['*'] &amp;lt;/code&amp;gt;&lt;br /&gt;
# Actualizar la url en &amp;lt;code&amp;gt; BASEURL &amp;lt;/code&amp;gt;&lt;br /&gt;
# Añadir el bloque de API={ …} apuntando a base url. Puede copiarlo de algún local_settings.py&lt;br /&gt;
# Específicar las rutas de los archivos estáticos &amp;lt;code&amp;gt;STATIC_URL = '/static/'&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;STATIC_ROOT= 'static/'&amp;lt;/code&amp;gt;&lt;br /&gt;
# El 'migrate' no funcionará si la base de datos no está bien configurada. Para ello puede observar en su aplicación en CleverCloud que hay una configuración de variables de entorno para sus Add-on de postgres. # Desde el settings.py puede acceder al valor de dichas variables con &amp;lt;code&amp;gt;os.environ.get(NOMBRE_VARIABLE)&amp;lt;/code&amp;gt;. Actualize el objeto &amp;quot;DATABASES&amp;quot; del settings.py para que acceda a dichas variables.&lt;br /&gt;
*Vuelva a realizar un push a CleverCloud (no olvide hacer commit antes).&lt;br /&gt;
 ¿Por qué sigue sin funcionar?&lt;br /&gt;
* El requirements.txt no lo está identificando al buscarlo, por defecto, dentro de la carpeta indicada en &amp;quot;folder&amp;quot;. Copie el requirements.txt dentro de la carpeta decide (También puede especificar la ruta del requirements.txt usando la variable de entorno CC_PIP_REQUIREMENTS_FILE, ver siguiente ejercicio). &lt;br /&gt;
== Ejercicio 3. Variables de entorno de CleverCloud ==&lt;br /&gt;
Hay otra parte de la configuración de CleverCloud que ha de especificarse dentro las variables de entorno de la aplicación. &lt;br /&gt;
* Para que la aplicación se levante correctamente, ha de usar la versión de python 3.8 en la variable CC_PYTHON_VERSION.&lt;br /&gt;
* Para indicar qué url dirige a los archivo estáticos, use STATIC_URL_PREFIX con el valor /static. Por ejemplo, el CSS de la aplicación.&lt;br /&gt;
* Para indicar la ruta donde se almacenarán dichos archivos, use STATIC_FILES_PATH con el valor static/.&lt;br /&gt;
* Pulse sobre &amp;quot;Update changes&amp;quot; y reinicie la aplicacion desde el menú &amp;quot;Overview&amp;quot;.&lt;br /&gt;
 ¿Puede ya nevegar hasta el menú de administración de decide?&lt;br /&gt;
* Cree el superusuario accediendo por ssh con:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -t ssh@sshgateway-clevercloud-customers.services.clever-cloud.com &amp;lt;&amp;lt;app_name&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
El código de la aplicación (manage.py) se encuentra en una carpeta con el nombre de su aplicación.&lt;br /&gt;
= Despliege continuo =&lt;br /&gt;
== Ejercicio 4. CleverCloud y GitHub Actions==&lt;br /&gt;
Para integrar GitHub Actions y CleverCloud cree un workflow de GitHub Actions nuevo, con un solo job.&lt;br /&gt;
* Use este workflow a modo de ejemplo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: Deploy example&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest    &lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/checkout@v2&lt;br /&gt;
        with:&lt;br /&gt;
          fetch-depth: 0&lt;br /&gt;
      - uses: 47ng/actions-clever-cloud@v1.3.1&lt;br /&gt;
        with:&lt;br /&gt;
          appID: app_fd57a008-7dbd-4636-8b34-af951947911f&lt;br /&gt;
        env:&lt;br /&gt;
          CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}&lt;br /&gt;
          CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Añada la dos secrets al proyecto de GitHub. Estas secrets se obtiene en el proceso de hacer &amp;lt;code&amp;gt;clever login&amp;lt;/code&amp;gt;. Aunque lo hiciera en los prerrequisitos, puede repetirlo ahora.&lt;br /&gt;
* Recuerde que necesita pushear este código (incluídos los cambios anteriores) a su repositorio en GitHub.&lt;br /&gt;
 ¿Ha funcionado el workflow?&lt;br /&gt;
 ¿Ha estado la aplicación en algún momento caída?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. Condiciones de despliegue ==&lt;br /&gt;
En GitHub Actions, los workflows tienen la capacidad de definir el/los evento/s que los disparan con la clausua &amp;quot;on:&amp;quot;.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags aquí]] más detalles de dicha cláusula. &lt;br /&gt;
Sin embargo eso no se puede especificar a nivel de job o de step.  &lt;br /&gt;
A esos niveles pueden expresarse sentencias &amp;quot;if&amp;quot; que permiten ejecutarlas condicionalmente.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsif aquí]] más detalles de dicha cláusula. &lt;br /&gt;
&lt;br /&gt;
* Integra el job de &amp;quot;deploy&amp;quot; en el workflow que creaste en prácticas anteriores.&lt;br /&gt;
* Para hacer que solo se lance el job &amp;quot;deploy&amp;quot; cuando estemos en una rama concreta, por ejemplo, &amp;quot;master&amp;quot;, incluiya lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
deploy:&lt;br /&gt;
    if: ${{github.ref == 'refs/heads/master' }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Haga push del nuevo workflow incluyen el job de deploy y su condición. Posterioremente, haz un push de algún otro código a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
 ¿Se lanza el job &amp;quot;deploy&amp;quot;? ¿En que estado se queda?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modifica la clausula &amp;quot;on:&amp;quot; para que se lance el workflow solo cuando se hiciera push a la rama master.&lt;br /&gt;
Despues de hacer un push del workflow, haz un push a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
&lt;br /&gt;
= Ejercicio 6. Creación de incidencias =&lt;br /&gt;
# El usuario “superuser” no se crea dentro del ciclo de despliegue continuo y obliga a hacer una tarea manual en los nuevos despliegues (salvo cuando se mantiene la BD).&lt;br /&gt;
# Crear una incidencia según las [[Gestión de incidencias | recomendaciones vistas en clase]] para el error que obtenemos al votar en heroku.&lt;br /&gt;
# Asegurarse que la incidencia creada incluye, al menos, un título descriptivo, información de qué es lo que ocurre y cómo puede reproducirse el error.&lt;br /&gt;
---------------&lt;br /&gt;
* Transparencias: [[Archivo:06-PaaSyDespliegueContinuo.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9470</id>
		<title>Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9470"/>
				<updated>2022-11-21T04:06:10Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
* Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contraseña.&lt;br /&gt;
* Asociar una llave SSH a la cuenta de CleverCloud en el [https://console.clever-cloud.com/users/me/ssh-keys menú de gestión de SSH]. &lt;br /&gt;
* Instalar CleverCloud CLI sobre Ubuntu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
# Instalamos llave de cifrado:&lt;br /&gt;
curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;quot; | sudo tee -a /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
# Instalamos CleverCloud tools&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clever-tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Comprobar que la instalación es correcta con &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
clever login&lt;br /&gt;
# Se abrirá un navegador con el login de CleverCloud.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Despliegue puntual en CleverCloud =&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 1. Crear aplicación ==&lt;br /&gt;
* Desde el &amp;quot;espacio personal&amp;quot; de CleverCloud cree una aplicación. Use la opción &amp;quot;Create a Brand new App&amp;quot;.&lt;br /&gt;
* Elija una aplicación de tipo &amp;quot;Python&amp;quot; e incluya &amp;quot;Postgress&amp;quot; como Add-on.&lt;br /&gt;
 ¿Para qué sirve el hecho de escoger un &amp;quot;Plan&amp;quot; o una &amp;quot;Localización&amp;quot; concreta?&lt;br /&gt;
* Seguir las instrucciones para hacer un push de nuestros código de decide hacia CleverCloud.&lt;br /&gt;
* Visualizar el log de la aplicación&lt;br /&gt;
 ¿Por qué está fallando?&lt;br /&gt;
 ¿Cuál es la URL dónde debería estar la aplicación desplegada en CleverCloud?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. Archivo de configuración de CleverCloud ==&lt;br /&gt;
CleverCloud realiza dos etapas:&lt;br /&gt;
# Build: Prepara el entorno, instala las dependencias, etc.&lt;br /&gt;
# Run: Despliega y expone la aplicación.&lt;br /&gt;
Parte de la configuración de estas etapas se hace en el archivo de configuración de CleverCloud. Para Python, este archivo deberá estar en &amp;lt;code&amp;gt; clevercloud/python.json &amp;lt;/code&amp;gt;. &lt;br /&gt;
* Cree ese archivo con el siguiente contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;build&amp;quot;: {&lt;br /&gt;
        &amp;quot;folder&amp;quot;: &amp;quot;decide&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;deploy&amp;quot;: {&lt;br /&gt;
        &amp;quot;module&amp;quot;: &amp;quot;decide.wsgi:application&amp;quot;,&lt;br /&gt;
        &amp;quot;managetasks&amp;quot;: [&lt;br /&gt;
			&amp;quot;collectstatic --noinput&amp;quot;,&lt;br /&gt;
			&amp;quot;migrate&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Como en CleverCloud no habrá local_settings, editaremos el &amp;lt;code&amp;gt; decide/settings.py &amp;lt;/code&amp;gt; para que contenga una configuración válida para CleverCloud. Estos son los cambios principales que habrá que hacer:&lt;br /&gt;
# Permitir conexiones más allá de localhost: &amp;lt;code&amp;gt;ALLOWED_HOSTS = ['*'] &amp;lt;/code&amp;gt;&lt;br /&gt;
# Actualizar la url en &amp;lt;code&amp;gt; BASEURL &amp;lt;/code&amp;gt;&lt;br /&gt;
# Añadir el bloque de API={ …} apuntando a base url. Puede copiarlo de algún local_settings.py&lt;br /&gt;
# Específicar las rutas de los archivos estáticos &amp;lt;code&amp;gt;STATIC_URL = '/static/'&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;STATIC_ROOT= 'static/'&amp;lt;/code&amp;gt;&lt;br /&gt;
# El 'migrate' no funcionará si la base de datos no está bien configurada. Para ello puede observar en su aplicación en CleverCloud que hay una configuración de variables de entorno para sus Add-on de postgres. # Desde el settings.py puede acceder al valor de dichas variables con &amp;lt;code&amp;gt;os.environ.get(NOMBRE_VARIABLE)&amp;lt;/code&amp;gt;. Actualize el objeto &amp;quot;DATABASES&amp;quot; del settings.py para que acceda a dichas variables.&lt;br /&gt;
*Vuelva a realizar un push a CleverCloud (no olvide hacer commit antes).&lt;br /&gt;
 ¿Por qué sigue sin funcionar?&lt;br /&gt;
* El requirements.txt no lo está identificando al buscarlo, por defecto, dentro de la carpeta indicada en &amp;quot;folder&amp;quot;. Copie el requirements.txt dentro de la carpeta decide (También puede especificar la ruta del requirements.txt usando la variable de entorno CC_PIP_REQUIREMENTS_FILE, ver siguiente ejercicio). &lt;br /&gt;
== Ejercicio 3. Variables de entorno de CleverCloud ==&lt;br /&gt;
Hay otra parte de la configuración de CleverCloud que ha de especificarse dentro las variables de entorno de la aplicación. &lt;br /&gt;
* Para que la aplicación se levante correctamente, ha de usar la versión de python 3.8 en la variable CC_PYTHON_VERSION.&lt;br /&gt;
* Para indicar qué url dirige a los archivo estáticos, use STATIC_URL_PREFIX con el valor /static. Por ejemplo, el CSS de la aplicación.&lt;br /&gt;
* Para indicar la ruta donde se almacenarán dichos archivos, use STATIC_FILES_PATH con el valor static/.&lt;br /&gt;
* Pulse sobre &amp;quot;Update changes&amp;quot; y reinicie la aplicacion desde el menú &amp;quot;Overview&amp;quot;.&lt;br /&gt;
 ¿Puede ya nevegar hasta el menú de administración de decide?&lt;br /&gt;
* Cree el superusuario accediendo por ssh con:&lt;br /&gt;
&amp;lt;code&amp;gt;ssh -t ssh@sshgateway-clevercloud-customers.services.clever-cloud.com &amp;lt;&amp;lt;app_name&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
El código de la aplicación (manage.py) se encuentra en una carpeta con el nombre de su aplicación.&lt;br /&gt;
= Despliege continuo =&lt;br /&gt;
== Ejercicio 4. CleverCloud y GitHub Actions==&lt;br /&gt;
Para integrar GitHub Actions y CleverCloud cree un workflow de GitHub Actions nuevo, con un solo job.&lt;br /&gt;
* Use este workflow a modo de ejemplo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: Deploy example&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  deploy:&lt;br /&gt;
    runs-on: ubuntu-latest    &lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/checkout@v2&lt;br /&gt;
        with:&lt;br /&gt;
          fetch-depth: 0&lt;br /&gt;
      - uses: 47ng/actions-clever-cloud@v1.3.1&lt;br /&gt;
        with:&lt;br /&gt;
          appID: app_fd57a008-7dbd-4636-8b34-af951947911f&lt;br /&gt;
        env:&lt;br /&gt;
          CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}&lt;br /&gt;
          CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Añada la dos secrets al proyecto de GitHub. Estas secrets se obtiene en el proceso de hacer &amp;lt;code&amp;gt;clever login&amp;lt;/code&amp;gt;. Aunque lo hiciera en los prerrequisitos, puede repetirlo ahora.&lt;br /&gt;
* Recuerde que necesita pushear este código (incluídos los cambios anteriores) a su repositorio en GitHub.&lt;br /&gt;
 ¿Ha funcionado el workflow?&lt;br /&gt;
 ¿Ha estado la aplicación en algún momento caída?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. Condiciones de despliegue ==&lt;br /&gt;
En GitHub Actions, los workflows tienen la capacidad de definir el/los evento/s que los disparan con la clausua &amp;quot;on:&amp;quot;.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags aquí]] más detalles de dicha cláusula. &lt;br /&gt;
Sin embargo eso no se puede especificar a nivel de job o de step.  &lt;br /&gt;
A esos niveles pueden expresarse sentencias &amp;quot;if&amp;quot; que permiten ejecutarlas condicionalmente.&lt;br /&gt;
Puedes ver [[https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsif aquí]] más detalles de dicha cláusula. &lt;br /&gt;
&lt;br /&gt;
* Integra el job de &amp;quot;deploy&amp;quot; en el workflow que creaste en prácticas anteriores.&lt;br /&gt;
* Para hacer que solo se lance el job &amp;quot;deploy&amp;quot; cuando estemos en una rama concreta, por ejemplo, &amp;quot;master&amp;quot;, incluiya lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
deploy:&lt;br /&gt;
    if: ${{github.ref == 'refs/heads/master' }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Haga push del nuevo workflow incluyen el job de deploy y su condición. Posterioremente, haz un push de algún otro código a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
 ¿Se lanza el job &amp;quot;deploy&amp;quot;? ¿En que estado se queda?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modifica la clausula &amp;quot;on:&amp;quot; para que se lance el workflow solo cuando se hiciera push a la rama master.&lt;br /&gt;
Despues de hacer un push del workflow, haz un push a otra rama.&lt;br /&gt;
 ¿Se lanza el workflow?&lt;br /&gt;
&lt;br /&gt;
= Ejercicio 6. Creación de incidencias =&lt;br /&gt;
# El usuario “superuser” no se crea dentro del ciclo de despliegue continuo y obliga a hacer una tarea manual en los nuevos despliegues (salvo cuando se mantiene la BD).&lt;br /&gt;
# Crear una incidencia según las [[Gestión de incidencias | recomendaciones vistas en clase]] para el error que obtenemos al votar en heroku.&lt;br /&gt;
# Asegurarse que la incidencia creada incluye, al menos, un título descriptivo, información de qué es lo que ocurre y cómo puede reproducirse el error.&lt;br /&gt;
---------------&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9469</id>
		<title>Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_PaaS_y_Despliegue_Continuo_22-23&amp;diff=9469"/>
				<updated>2022-11-21T02:55:13Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Página_Principal -&amp;gt; 2022/2023 -&amp;gt; Prácticas - 22/23 = Prerequisitos = * Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contrase...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
* Crear una cuenta en [https://www.clever-cloud.com CleverCloud] usando email y contraseña.&lt;br /&gt;
* Asociar una llave SSH a la cuenta de CleverCloud en el [https://console.clever-cloud.com/users/me/ssh-keys menú de gestión de SSH]. &lt;br /&gt;
* Instalar CleverCloud CLI sobre Ubuntu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
# Instalamos llave de cifrado:&lt;br /&gt;
curl -fsSL https://clever-tools.clever-cloud.com/gpg/cc-nexus-deb.public.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/cc-nexus-deb.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/cc-nexus-deb.gpg] https://nexus.clever-cloud.com/repository/deb stable main&amp;quot; | sudo tee -a /etc/apt/sources.list&lt;br /&gt;
&lt;br /&gt;
# Instalamos CleverCloud tools&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clever-tools&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Comprobar que la instalación es correcta con &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
clever login&lt;br /&gt;
# Se abrirá un navegador con el login de CleverCloud.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9468</id>
		<title>Prácticas - 22/23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9468"/>
				<updated>2022-11-21T02:44:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]]&lt;br /&gt;
&lt;br /&gt;
* Práctica 1: [[Instalación de Decide 22-23 | Instalación de Decide]]&lt;br /&gt;
* Práctica 2: [[Pruebas de software 22-23 | Pruebas de Software]]&lt;br /&gt;
* Práctica 3: [[Gestión de Código Fuente e Integración Continua 22-23 | Gestión de Código Fuente e Integración Continua]]&lt;br /&gt;
* Práctica 4: [[Despliegue de aplicaciones: Contenedores 22-23 | Despliegue de aplicaciones: Contenedores ]]&lt;br /&gt;
* Práctica 5: [[Despliegue de aplicaciones: Máquinas virtuales 22-23|Despliegue de aplicaciones: Máquinas virtuales]]&lt;br /&gt;
* Práctica 6: [[Despliegue de aplicaciones: PaaS y Despliegue Continuo 22-23|Despliegue de aplicaciones: PaaS y Despliegue Continuo]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9459</id>
		<title>Despliegue de aplicaciones: Máquinas virtuales 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9459"/>
				<updated>2022-11-15T06:43:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
&lt;br /&gt;
* [https://videos.us.es/media/P5-+M%C3%A1quinas+virtuales/1_9075tuv8 Vídeo explicando la instalación de los prerequisitos y configuración]&lt;br /&gt;
&lt;br /&gt;
= Instalación de Vagrant Ansible =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instrucciones para instalar sobre Ubuntu 20.04&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install vagrant ansible virtualbox&lt;br /&gt;
&lt;br /&gt;
#Para probar que funciona&lt;br /&gt;
vagrant init ubuntu/trusty32&lt;br /&gt;
vagrant up&lt;br /&gt;
#Suele tardar varios minutos&lt;br /&gt;
vagrant ssh -c 'hostnamectl'   &lt;br /&gt;
#Comparar que devuelve el comando con respecto a ejecutar hostnamectl en local&lt;br /&gt;
vagrant destroy #Para eliminar la imagen y liberar espacio&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uso sobre máquinas virtuales (desaconsejado) ==&lt;br /&gt;
'''Es altamente recomendable realizar esta práctica en un sistema Linux NO VIRTUALIZADO, es decir, instalado directamente en el equipo (por ejemplo, en una partición).'''&lt;br /&gt;
'''En caso contrario, los más probable es que no llegue a funcionar la práctica.  Raramente, llegará a funcionar pero con un rendimiento muy bajo (las instrucciones tardan mucho en ejecutarse).'''&lt;br /&gt;
Si decides continuar usando máquinas virtuales, lee este texto hasta el final. Tanto el uso dentro de virtualbox como en WSL requieren de bastante configuración.&lt;br /&gt;
&lt;br /&gt;
En caso de usar máquina virtual hay que habilitar la virtualización anidada y asegurarse de tener suficiente espacio en disco. &lt;br /&gt;
* [https://www.raulprietofernandez.net/blog/virtualizacion/como-redimensionar-un-disco-virtual-en-virtualbox Espacio en disco]. &lt;br /&gt;
En caso de usar WSL teneis el [https://www.vagrantup.com/docs/other/wsl tutorial de la propia Vagrant].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Ejercicios=&lt;br /&gt;
&lt;br /&gt;
* [[Ejercicio 1: Operaciones básicas en Vagrant 21-22 |Ejercicio 1: Operaciones básicas en Vagrant]]&lt;br /&gt;
* [[Ejercicio 2: Carpetas compartidas y redirección de puertos 21-22 | Ejercicio 2: Carpetas compartidas y redirección de puertos]]&lt;br /&gt;
* [[Ejercicio 3: Encapsulado y aprovisionamiento de una app en Vagrant 21-22 | Ejercicio 3: Encapsulado y aprovisionamiento de una app en Vagrant]]&lt;br /&gt;
* [[Ejercicio 4: Despliegue de Decide en Vagrant 21-22 | Ejercicio 4: Despliegue de Decide en Vagrant]]&lt;br /&gt;
&lt;br /&gt;
* Transparencias [[Archivo:05-vagrant.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9458</id>
		<title>Despliegue de aplicaciones: Máquinas virtuales 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9458"/>
				<updated>2022-11-09T09:11:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
&lt;br /&gt;
* [https://videos.us.es/media/P5-+M%C3%A1quinas+virtuales/1_9075tuv8 Vídeo explicando la instalación de los prerequisitos y configuración]&lt;br /&gt;
&lt;br /&gt;
= Instalación de Vagrant Ansible =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instrucciones para instalar sobre Ubuntu 20.04&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install vagrant ansible virtualbox&lt;br /&gt;
&lt;br /&gt;
#Para probar que funciona&lt;br /&gt;
vagrant init ubuntu/trusty32&lt;br /&gt;
vagrant up&lt;br /&gt;
#Suele tardar varios minutos&lt;br /&gt;
vagrant ssh -c 'hostnamectl'   &lt;br /&gt;
#Comparar que devuelve el comando con respecto a ejecutar hostnamectl en local&lt;br /&gt;
vagrant destroy #Para eliminar la imagen y liberar espacio&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uso sobre máquinas virtuales (desaconsejado) ==&lt;br /&gt;
'''Es altamente recomendable realizar esta práctica en un sistema Linux NO VIRTUALIZADO, es decir, instalado directamente en el equipo (por ejemplo, en una partición).'''&lt;br /&gt;
'''En caso contrario, los más probable es que no llegue a funcionar la práctica.  Raramente, llegará a funcionar pero con un rendimiento muy bajo (las instrucciones tardan mucho en ejecutarse).'''&lt;br /&gt;
Si decides continuar usando máquinas virtuales, lee este texto hasta el final. Tanto el uso dentro de virtualbox como en WSL requieren de bastante configuración.&lt;br /&gt;
&lt;br /&gt;
En caso de usar máquina virtual hay que habilitar la virtualización anidada y asegurarse de tener suficiente espacio en disco. &lt;br /&gt;
* [https://www.raulprietofernandez.net/blog/virtualizacion/como-redimensionar-un-disco-virtual-en-virtualbox Espacio en disco]. &lt;br /&gt;
En caso de usar WSL teneis el [https://www.vagrantup.com/docs/other/wsl tutorial de la propia Vagrant].&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9457</id>
		<title>Despliegue de aplicaciones: Máquinas virtuales 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_M%C3%A1quinas_virtuales_22-23&amp;diff=9457"/>
				<updated>2022-11-09T09:08:28Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Página_Principal -&amp;gt; 2022/2023 -&amp;gt; Prácticas - 22/23 = Prerequisitos =  * [https://videos.us.es/media/P5-+M%C3%A1quinas+virtuales/1_9075tuv8 Vídeo explicando l...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
&lt;br /&gt;
* [https://videos.us.es/media/P5-+M%C3%A1quinas+virtuales/1_9075tuv8 Vídeo explicando la instalación de los prerequisitos y configuración]&lt;br /&gt;
&lt;br /&gt;
= Instalación de Vagrant Ansible =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instrucciones para instalar sobre Ubuntu 20.04&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install vagrant ansible virtualbox&lt;br /&gt;
&lt;br /&gt;
#Para probar que funciona&lt;br /&gt;
vagrant init ubuntu/trusty32&lt;br /&gt;
vagrant up&lt;br /&gt;
#Suele tardar varios minutos&lt;br /&gt;
vagrant ssh -c 'hostnamectl'   &lt;br /&gt;
#Comparar que devuelve el comando con respecto a ejecutar hostnamectl en local&lt;br /&gt;
vagrant destroy #Para eliminar la imagen y liberar espacio&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uso sobre máquinas virtuales (desaconsejado) ==&lt;br /&gt;
'''Es altamente recomendable realizar esta práctica en un sistema Linux NO VIRTUALIZADO, es decir, instalado directamente en el equipo (por ejemplo, en una partición).'''&lt;br /&gt;
'''En caso contrario, los más probable es que no llegue a funcionar la práctica.  Raramente, llegará a funcionar pero con un rendimiento muy bajo (las instrucciones tardan mucho en ejecutarse).'''&lt;br /&gt;
Si decides continuar usando máquinas virtuales, lee este texto hasta el final. Tanto el uso dentro de virtualbox como en WSL requieren de bastante configuración.&lt;br /&gt;
&lt;br /&gt;
En caso de usar máquina virtual hay que habilitar la virtualización anidada y asegurarse de tener suficiente espacio en disco. &lt;br /&gt;
* [https://www.raulprietofernandez.net/blog/virtualizacion/como-redimensionar-un-disco-virtual-en-virtualbox Espacio en disco]. &lt;br /&gt;
* [https://www.zonasystem.com/2019/02/habilitar-virtualizacion-anidada-vt-x-amd-v-virtualbox.html Virtualización anidada]&lt;br /&gt;
En caso de usar WSL teneis el [https://www.vagrantup.com/docs/other/wsl tutorial de la propia Vagrant].&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9456</id>
		<title>Prácticas - 22/23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9456"/>
				<updated>2022-11-09T09:06:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]]&lt;br /&gt;
&lt;br /&gt;
* Práctica 1: [[Instalación de Decide 22-23 | Instalación de Decide]]&lt;br /&gt;
* Práctica 2: [[Pruebas de software 22-23 | Pruebas de Software]]&lt;br /&gt;
* Práctica 3: [[Gestión de Código Fuente e Integración Continua 22-23 | Gestión de Código Fuente e Integración Continua]]&lt;br /&gt;
* Práctica 4: [[Despliegue de aplicaciones: Contenedores 22-23 | Despliegue de aplicaciones: Contenedores ]]&lt;br /&gt;
* Práctica 5: [[Despliegue de aplicaciones: Máquinas virtuales 22-23|Despliegue de aplicaciones: Máquinas virtuales]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:04-Docker_22.pdf&amp;diff=9444</id>
		<title>Archivo:04-Docker 22.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:04-Docker_22.pdf&amp;diff=9444"/>
				<updated>2022-10-24T16:05:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_Contenedores_22-23&amp;diff=9443</id>
		<title>Despliegue de aplicaciones: Contenedores 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_Contenedores_22-23&amp;diff=9443"/>
				<updated>2022-10-24T16:05:11Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
&lt;br /&gt;
* [https://videos.us.es/media/P4-+Contenedores/1_1mkxtw14 Vídeo explicando la instalación docker y docker-compose]&lt;br /&gt;
&lt;br /&gt;
== Instalación Docker ==&lt;br /&gt;
Instrucciones para instlar sobre Ubuntu 20.04&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
#Desinstalamos versiones antiguas:&lt;br /&gt;
sudo apt-get remove docker docker-engine docker.io containerd runc&lt;br /&gt;
&lt;br /&gt;
#Instalamos dependencias&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
&lt;br /&gt;
sudo apt-get install \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    curl \&lt;br /&gt;
    gnupg \&lt;br /&gt;
    lsb-release&lt;br /&gt;
&lt;br /&gt;
# Instalamos llave de cifrado&lt;br /&gt;
sudo mkdir -p /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo \&lt;br /&gt;
  &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(lsb_release -cs) stable&amp;quot; | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Instalamos docker&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install docker-ce docker-ce-cli containerd.io &lt;br /&gt;
&lt;br /&gt;
# Instalamos docker compose&lt;br /&gt;
sudo apt-get install docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
# Añadimos nuestro usuario al grupo docker&lt;br /&gt;
sudo usermod -aG docker $USER&lt;br /&gt;
newgrp docker&lt;br /&gt;
&lt;br /&gt;
# Tenemos que salir de la sesión y volver a entrar para que los cambios tomen efecto&lt;br /&gt;
&lt;br /&gt;
# Probamos que fundiona con:&lt;br /&gt;
docker run hello-world&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Ordenes para docker =&lt;br /&gt;
&lt;br /&gt;
* [[Lanzando un hola mundo 21-22 |Lanzando un hola mundo]]&lt;br /&gt;
* [[Operando con las imagenes]]&lt;br /&gt;
* [[Operando con los contenedores]]&lt;br /&gt;
* [[Modificando una imagen]]&lt;br /&gt;
&lt;br /&gt;
= Ejemplos  =&lt;br /&gt;
&lt;br /&gt;
* [https://docs.docker.com/compose/wordpress/ Para instalar WordPress y MySQL] &lt;br /&gt;
* [http://codeomitted.com/deploy-war-file-to-docker-image/ Para construir una imagen con Tomcat básica]&lt;br /&gt;
* [https://runnable.com/docker/java/dockerize-your-java-application Para construir una imagen Java muy personalizada].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Ejercicios=&lt;br /&gt;
* [[Ejercicio 0: Ejecutando comandos simples de docker 21-22| Ejercicio 0: Ejecutando comandos simples de docker]]&lt;br /&gt;
* [[Ejercicio 1: Creando mi propia imagen para una app python 22-23 | Ejercicio 1: Creando mi propia imagen para una app python]]&lt;br /&gt;
* [[Ejercicio 2: Ejecutando decide en docker-compose]]&lt;br /&gt;
----&lt;br /&gt;
[[Archivo:04-Docker 22.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Ejercicio_1:_Creando_mi_propia_imagen_para_una_app_python_22-23&amp;diff=9442</id>
		<title>Ejercicio 1: Creando mi propia imagen para una app python 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Ejercicio_1:_Creando_mi_propia_imagen_para_una_app_python_22-23&amp;diff=9442"/>
				<updated>2022-10-24T16:04:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «= Creando una imagen para una app Flask en python =  *Todo el código fuente está disponible en : https://github.com/EGCETSII/1920-Practica-1  Comenzamos creando nuestra a...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Creando una imagen para una app Flask en python =&lt;br /&gt;
&lt;br /&gt;
*Todo el código fuente está disponible en : https://github.com/EGCETSII/1920-Practica-1&lt;br /&gt;
&lt;br /&gt;
Comenzamos creando nuestra app en el arcvhivo holamundo.py&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from flask import Flask  &lt;br /&gt;
app = Flask(__name__) &lt;br /&gt;
@app.route('/') &lt;br /&gt;
def hello_world():     &lt;br /&gt;
    return 'Hello World' &lt;br /&gt;
@app.route('/hello/&amp;lt;name&amp;gt;')&lt;br /&gt;
def hello_name(name):&lt;br /&gt;
    return 'Hello %s!' % name&lt;br /&gt;
if __name__ == '__main__':      &lt;br /&gt;
    app.run(host=&amp;quot;0.0.0.0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Definimos las dependencias en el archivo requirements.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
Flask&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podemos usar la imagen de python3 existente en los repositorios de docker, y modificarla anadiendo la aplicacion que hemos desarrollado&lt;br /&gt;
&lt;br /&gt;
Para ello podemos crear un fichero Dockerfile que nos automatiza la creacion de una imagen modificada:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
# Base image &lt;br /&gt;
FROM python:3 &lt;br /&gt;
#copy the requirements txt file with all our dependencies&lt;br /&gt;
COPY requirements.txt ./ &lt;br /&gt;
#install the dependencies&lt;br /&gt;
RUN pip install --no-cache-dir -r requirements.txt  &lt;br /&gt;
#copy the app in the image&lt;br /&gt;
COPY holamundo.py ./  &lt;br /&gt;
#define a default command to execute&lt;br /&gt;
CMD [ &amp;quot;python&amp;quot;, &amp;quot;./holamundo.py&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Este fichero indica que docker tiene que descargar la imagen python en su tercera versión y tiene que añadir el fichero requirements a la carpeta de usuario de la imagen.&lt;br /&gt;
&lt;br /&gt;
Docker nos ofrece un lenguaje de scripting para automatizar la creacion de imagenes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
# docker build -t holamundo-flask .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Va a crear la imagen, tras esto podemos lanzar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
# docker run -p 8020:80 holamundo-flask&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tras esto, desde un navegador, abrimos la URI: http://localhost:8020/hello/&amp;quot;yourname&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9441</id>
		<title>Prácticas - 22/23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9441"/>
				<updated>2022-10-24T15:52:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]]&lt;br /&gt;
&lt;br /&gt;
* Práctica 1: [[Instalación de Decide 22-23 | Instalación de Decide]]&lt;br /&gt;
* Práctica 2: [[Pruebas de software 22-23 | Pruebas de Software]]&lt;br /&gt;
* Práctica 3: [[Gestión de Código Fuente e Integración Continua 22-23 | Gestión de Código Fuente e Integración Continua]]&lt;br /&gt;
* Práctica 4: [[Despliegue de aplicaciones: Contenedores 22-23 | Despliegue de aplicaciones: Contenedores ]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_Contenedores_22-23&amp;diff=9437</id>
		<title>Despliegue de aplicaciones: Contenedores 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Despliegue_de_aplicaciones:_Contenedores_22-23&amp;diff=9437"/>
				<updated>2022-10-20T10:51:29Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Página_Principal -&amp;gt; 2022/2023 -&amp;gt; Prácticas - 22/23  = Prerequisitos =  * [https://videos.us.es/media/P4-+Contenedores/1_1mkxtw14 Vídeo explicando la instalac...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerequisitos =&lt;br /&gt;
&lt;br /&gt;
* [https://videos.us.es/media/P4-+Contenedores/1_1mkxtw14 Vídeo explicando la instalación docker y docker-compose]&lt;br /&gt;
&lt;br /&gt;
== Instalación Docker ==&lt;br /&gt;
Instrucciones para instlar sobre Ubuntu 20.04&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line='line'&amp;gt;&lt;br /&gt;
#Desinstalamos versiones antiguas:&lt;br /&gt;
sudo apt-get remove docker docker-engine docker.io containerd runc&lt;br /&gt;
&lt;br /&gt;
#Instalamos dependencias&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
&lt;br /&gt;
sudo apt-get install \&lt;br /&gt;
    ca-certificates \&lt;br /&gt;
    curl \&lt;br /&gt;
    gnupg \&lt;br /&gt;
    lsb-release&lt;br /&gt;
&lt;br /&gt;
# Instalamos llave de cifrado&lt;br /&gt;
sudo mkdir -p /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg&lt;br /&gt;
&lt;br /&gt;
# Añadimos el repositorio&lt;br /&gt;
echo \&lt;br /&gt;
  &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(lsb_release -cs) stable&amp;quot; | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Instalamos docker&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install docker-ce docker-ce-cli containerd.io &lt;br /&gt;
&lt;br /&gt;
# Instalamos docker compose&lt;br /&gt;
sudo apt-get install docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
# Añadimos nuestro usuario al grupo docker&lt;br /&gt;
sudo usermod -aG docker $USER&lt;br /&gt;
newgrp docker&lt;br /&gt;
&lt;br /&gt;
# Tenemos que salir de la sesión y volver a entrar para que los cambios tomen efecto&lt;br /&gt;
&lt;br /&gt;
# Probamos que fundiona con:&lt;br /&gt;
docker run hello-world&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=GithubActions_2022&amp;diff=9423</id>
		<title>GithubActions 2022</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=GithubActions_2022&amp;diff=9423"/>
				<updated>2022-10-11T08:00:34Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: /* Nociones básicas sobre GitHub Actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Nociones básicas sobre GitHub Actions==&lt;br /&gt;
Dentro de cada .yml de la carpeta .github/worflows se define un:&lt;br /&gt;
# '''workflow''' el cuál se dispara al recibir un evento de GitHub. &lt;br /&gt;
# Estos '''eventos''' puede ser desde un push hasta la creación de una issue. Cada workflow permite correr jobs.&lt;br /&gt;
# Los '''jobs''' son secuencias de pasos. Cada uno de estos jobs se ejecutan dentro de un entorno llamado runner.&lt;br /&gt;
# Los '''runners''' son máquinas virtuales que se levantan para cada job. Todos los pasos de un job se ejecutan dentro del mismo runner, por lo que comparten recursos como los archivos y las carpetas.&lt;br /&gt;
# Los '''pasos''' de un job pueden ser simples instrucciones de shell, o utilizar funciones más concretas llamadas '''actions''' como, por ejemplo, hacer un clone.&lt;br /&gt;
&lt;br /&gt;
El siguiente workflow tiene como nombre 'GitHub Actions Demo' y se dispara al hacer un push. Únicamente define un job llamado 'Explore-GitHub-Actions' dentro de un runner de tipo ubuntu-latest. Casi todos los pasos son de tipo shell salvo uno que utiliza la acción actions/checkout@v1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: GitHub Actions Demo&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  Explore-GitHub-Actions:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;🎉 The job was automatically triggered by a ${{ github.event_name }} event.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}.&amp;quot;&lt;br /&gt;
      - name: Check out repository code&lt;br /&gt;
        uses: actions/checkout@v1&lt;br /&gt;
      - run: echo &amp;quot;💡 The ${{ github.repository }} repository has been cloned to the runner.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🖥️  The workflow is now ready to test your code on the runner.&amp;quot;&lt;br /&gt;
      - name: List files in the repository&lt;br /&gt;
        run: |&lt;br /&gt;
          ls ${{ github.workspace }}&lt;br /&gt;
      - run: echo &amp;quot;🍏 This job's status is ${{ job.status }}.&amp;quot;&lt;br /&gt;
      - name: Contains expresion in a step&lt;br /&gt;
        run: echo &amp;quot;Is this branch master or develop? ${{ contains('refs/heads/master refs/heads/develop',github.ref)}}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Añade un archivo con este contenido a tu proyecto en GitHub y comprueba su estado en la pestaña Actions:&lt;br /&gt;
* ¿Cuántos Worflows, jobs, steps se lanzan?&lt;br /&gt;
* ¿Entiendes todo lo que hacen las expresiones ${{ &amp;lt;expresion&amp;gt; }}?&lt;br /&gt;
Para consultar la lista completa de expressiones, visita este [[https://docs.github.com/en/actions/learn-github-actions/expressions  link]].&lt;br /&gt;
&lt;br /&gt;
Para consultar la lista completa de contextos (e.g., github.&amp;lt;&amp;gt;, job.&amp;lt;&amp;gt; o runner.&amp;lt;&amp;gt;), visita este otro [[https://docs.github.com/en/actions/learn-github-actions/contexts link]].&lt;br /&gt;
&lt;br /&gt;
Para consultar la lista completa de acciones, visita el [[https://github.com/marketplace?type=actions link]].&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:03-Codigo_y_GActions.pdf&amp;diff=9422</id>
		<title>Archivo:03-Codigo y GActions.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:03-Codigo_y_GActions.pdf&amp;diff=9422"/>
				<updated>2022-10-11T07:30:45Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9421</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9421"/>
				<updated>2022-10-11T07:30:20Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P3-+GIT+y+Codacy/1_vr2tpcm0 aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Git =&lt;br /&gt;
&lt;br /&gt;
[[Uso_de_git | Para repasar y aprender más]]&lt;br /&gt;
== Ejercicio 1. git branch -d ==&lt;br /&gt;
Para preparar el entorno de decide en vuestro GitHub, es recomendable limpiar el proyecto quedarnos únicamente con las ramas relevantes para el desarrollo.&lt;br /&gt;
# Visualiza las ramas desde tu repositorio local. ¿Cómo mostramos las ramas que están en el repositorio remoto (GitHub)?.&lt;br /&gt;
# Borra una rama diferente a la de master y comprueba que se ha borrado en GitHub.&lt;br /&gt;
# Haz lo mismo con todas las ramas que no creas útiles. Puedes automatizar esta tarea haciendo uso de instrucciones de Linux como &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cut&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;xargs&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. git rebase y git merge ==&lt;br /&gt;
# Trabajando en local, crea una rama con el objetivo de desarrollar alguna nueva funcionalidad. Haz algunos commits ahí.&lt;br /&gt;
# Muevete a la rama master y haz algún commit más.&lt;br /&gt;
# Ahora quieres subir los cambios al servidor remoto con push, pero no te interesa que la rama que has creado exista en el remoto, ya que era algo local tuyo. ¿Qué consideras más oportuno antes de hacer un push? ¿Rebase ó Merge hacia master? &lt;br /&gt;
# ¿Qué diferencias habría en la rama master?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3. git cherry-pick ==&lt;br /&gt;
# Trabajando en local, crea una rama y haz varios commits.&lt;br /&gt;
# Vuelve a la rama master.&lt;br /&gt;
# De todos los commits que has hecho en la rama anterior, sólo te interesa uno o dos de ellos, pero no la rama entera, ¿cómo puedes traerte esos cambios a la rama master?&lt;br /&gt;
# ¿Crees que es buena práctica usarlo?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 4. git reset ==&lt;br /&gt;
# Trabajando en local, haz varios commits sobre la rama master pero no lo subas al servidor remoto.&lt;br /&gt;
# Suponiendo que los cambios de código que has hecho están bien, pero que los commits y sus mensaje no te parecen tan correctos, ¿cómo deshacemos esos commits sin perder el código fuente?&lt;br /&gt;
# Y, si quieres desahacer también los cambios hechos en el código, ¿cómo podemos hacerlo?&lt;br /&gt;
# ¿Podemos hacer esto con commits que hayan sido enviados al servidor remoto? ¿Por qué? ¿Qué habría que hacer entonces si quiere revertir cambios en el servidor remoto?&lt;br /&gt;
&lt;br /&gt;
== [[Ejercicios_de_git|Más ejercicios de Git aquí]] ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Github Actions =&lt;br /&gt;
&lt;br /&gt;
Revisa antes los [[ GithubActions_2022 | Conceptos básicos]] para poder usar Github Actions.&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. CI/CD de decide ==&lt;br /&gt;
Siguiendo [[CI de decide 22|estas instrucciones]]:&lt;br /&gt;
# Revisa que al hacer push se lanza el worflow de integración continua de decide.&lt;br /&gt;
# Crea una rama donde reduciremos la carga de tests. Comentaremos los tests de mixnet y el test_complete_voting del módulo Voting.&lt;br /&gt;
# Crea un pull-request siguiendo [https://help.github.com/articles/creating-a-pull-request/#creating-the-pull-request estas instrucciones] (Fíjate bien que la pull request la haces a la rama &amp;lt;code&amp;gt;master&amp;lt;/code&amp;gt; de tu repositorio y no a otro repositorio ni a &amp;lt;code&amp;gt;EGCETSI/decide&amp;lt;/code&amp;gt;).&lt;br /&gt;
# Si abres la pull request que se ha creado, podrás observar abajo cómo se ejecuta el workflow de  Github Actions con la pull request. &lt;br /&gt;
# ¿Es exitoso o fallido? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 6. Matriz con diferentes versiones de python==&lt;br /&gt;
Siguiendo [[Matrices en Github Actions 22 |estas instrucciones]]:&lt;br /&gt;
# Configura el workflow para que lanze las pruebas en varias versiones de Python y Django.&lt;br /&gt;
# ¿Cuántos jobs se están lanzando?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 7. Badges de workflows ==&lt;br /&gt;
&lt;br /&gt;
Siguiendo [[Badges en Actions 22 |estas instrucciones]]&lt;br /&gt;
# Configura el README.md de tu proyecto para que muestre una imagen con el estado de la construcción.&lt;br /&gt;
# Si tienes varios workflow, ¿puede generarse un badge general o tiene que generarse un badge para cada workflow?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8. Reutilización de workflows y creación de releases ==&lt;br /&gt;
Siguiendo [[Reutilización de workflows y creación de releases 23 |estas instrucciones]]:&lt;br /&gt;
# Crea un nuevo workflow con una etapa de buildTest, (que invoque al workflow django.yml) y otro job de release. &lt;br /&gt;
# Haga que este workflow se dispare sólo cuando se cree un tag.&lt;br /&gt;
# Haga que el workflow django.yml sea &amp;quot;invocable&amp;quot; requiriendo el parámetro de secrets CODACY_PROJECT_TOKEN.&lt;br /&gt;
# Cree un tag.&lt;br /&gt;
# ¿Cuántos workflows se disparan?&lt;br /&gt;
# ¿Cuántos jobs se ejecutan del nuevo workflow?&lt;br /&gt;
# ¿Se crea correctamente la release? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
= Uso de Codacy =&lt;br /&gt;
== Ejercicio 9. Calidad de código ==&lt;br /&gt;
# Analiza el reporte de Codacy para el proyecto. &lt;br /&gt;
# ¿Crees que el estado de los problemas (Issues), cobertura y duplicidad de decide son importantes?&lt;br /&gt;
# Siguiendo [https://docs.codacy.com/repositories/badges/  estas instrucciones] configura el README.md de tu proyecto para que muestre el estado de la calidad del proyecto y su análisis de cobertura de tests.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Archivo:03-Codigo_y_GActions.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Reutilizaci%C3%B3n_de_workflows_y_creaci%C3%B3n_de_releases_23&amp;diff=9417</id>
		<title>Reutilización de workflows y creación de releases 23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Reutilizaci%C3%B3n_de_workflows_y_creaci%C3%B3n_de_releases_23&amp;diff=9417"/>
				<updated>2022-10-09T15:42:57Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con « = Reutilización de workflows y creación de releases =  En GitHub puede hacerse crearse una Release de un repositorio en https://github.com/&amp;lt;tu org&amp;gt;/&amp;lt;tu repo&amp;gt;/releases....»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Reutilización de workflows y creación de releases =&lt;br /&gt;
&lt;br /&gt;
En GitHub puede hacerse crearse una Release de un repositorio en https://github.com/&amp;lt;tu org&amp;gt;/&amp;lt;tu repo&amp;gt;/releases. &lt;br /&gt;
Para automatizar el proceso de generación de una release a partir de un tag (siempre y cuando dicho código haya pasado las pruebas) podemos combinar el workflow django.yml con un pasos posterior de release. Para ello:&lt;br /&gt;
&lt;br /&gt;
# Cree un nuevo workflow en la carpeta de los workflows con el siguiente contenido:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: release&lt;br /&gt;
&lt;br /&gt;
on:&lt;br /&gt;
  push: &lt;br /&gt;
    tags:&lt;br /&gt;
      - '*'&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  buildTest:&lt;br /&gt;
    uses: &amp;lt;tu org&amp;gt;/&amp;lt;tu repo&amp;gt;/.github/workflows/django.yml@master&lt;br /&gt;
    secrets: &lt;br /&gt;
      CODACY_PROJECT_TOKEN: ${{secrets.CODACY_PROJECT_TOKEN}}&lt;br /&gt;
     &lt;br /&gt;
  release:&lt;br /&gt;
    needs: buildTest&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: Checkout&lt;br /&gt;
        uses: actions/checkout@v2&lt;br /&gt;
      - name: Release&lt;br /&gt;
        uses: softprops/action-gh-release@v1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Dado que las variables de entorno y secrets no se comparten entre workflows, hay que pasarlos explicitamente de un worflow al workflow reutilizable. Para convertir el workflow django.yml en reutilizable tenemos que modifcarlo añadiendo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
on:&lt;br /&gt;
  push:&lt;br /&gt;
     branches:&lt;br /&gt;
	   - master&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    secrets:&lt;br /&gt;
      CODACY_PROJECT_TOKEN:&lt;br /&gt;
        required: true&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para crear un nuevo tag hagamos:&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git tag -a v1.0.0 -m “mensaje para añadir al tag que también aparecerá en la release”&lt;br /&gt;
git push origin v1.0.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9416</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9416"/>
				<updated>2022-10-09T15:41:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: /* Ejercicio 7. Badges de workflows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P3-+GIT+y+Codacy/1_vr2tpcm0 aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Git =&lt;br /&gt;
&lt;br /&gt;
[[Uso_de_git | Para repasar y aprender más]]&lt;br /&gt;
== Ejercicio 1. git branch -d ==&lt;br /&gt;
Para preparar el entorno de decide en vuestro GitHub, es recomendable limpiar el proyecto quedarnos únicamente con las ramas relevantes para el desarrollo.&lt;br /&gt;
# Visualiza las ramas desde tu repositorio local. ¿Cómo mostramos las ramas que están en el repositorio remoto (GitHub)?.&lt;br /&gt;
# Borra una rama diferente a la de master y comprueba que se ha borrado en GitHub.&lt;br /&gt;
# Haz lo mismo con todas las ramas que no creas útiles. Puedes automatizar esta tarea haciendo uso de instrucciones de Linux como &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cut&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;xargs&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. git rebase y git merge ==&lt;br /&gt;
# Trabajando en local, crea una rama con el objetivo de desarrollar alguna nueva funcionalidad. Haz algunos commits ahí.&lt;br /&gt;
# Muevete a la rama master y haz algún commit más.&lt;br /&gt;
# Ahora quieres subir los cambios al servidor remoto con push, pero no te interesa que la rama que has creado exista en el remoto, ya que era algo local tuyo. ¿Qué consideras más oportuno antes de hacer un push? ¿Rebase ó Merge hacia master? &lt;br /&gt;
# ¿Qué diferencias habría en la rama master?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3. git cherry-pick ==&lt;br /&gt;
# Trabajando en local, crea una rama y haz varios commits.&lt;br /&gt;
# Vuelve a la rama master.&lt;br /&gt;
# De todos los commits que has hecho en la rama anterior, sólo te interesa uno o dos de ellos, pero no la rama entera, ¿cómo puedes traerte esos cambios a la rama master?&lt;br /&gt;
# ¿Crees que es buena práctica usarlo?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 4. git reset ==&lt;br /&gt;
# Trabajando en local, haz varios commits sobre la rama master pero no lo subas al servidor remoto.&lt;br /&gt;
# Suponiendo que los cambios de código que has hecho están bien, pero que los commits y sus mensaje no te parecen tan correctos, ¿cómo deshacemos esos commits sin perder el código fuente?&lt;br /&gt;
# Y, si quieres desahacer también los cambios hechos en el código, ¿cómo podemos hacerlo?&lt;br /&gt;
# ¿Podemos hacer esto con commits que hayan sido enviados al servidor remoto? ¿Por qué? ¿Qué habría que hacer entonces si quiere revertir cambios en el servidor remoto?&lt;br /&gt;
&lt;br /&gt;
== [[Ejercicios_de_git|Más ejercicios de Git aquí]] ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Github Actions =&lt;br /&gt;
&lt;br /&gt;
Revisa antes los [[ GithubActions_2022 | Conceptos básicos]] para poder usar Github Actions.&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. CI/CD de decide ==&lt;br /&gt;
Siguiendo [[CI de decide 22|estas instrucciones]]:&lt;br /&gt;
# Revisa que al hacer push se lanza el worflow de integración continua de decide.&lt;br /&gt;
# Crea una rama donde reduciremos la carga de tests. Comentaremos los tests de mixnet y el test_complete_voting del módulo Voting.&lt;br /&gt;
# Crea un pull-request siguiendo [https://help.github.com/articles/creating-a-pull-request/#creating-the-pull-request estas instrucciones] (Fíjate bien que la pull request la haces a la rama &amp;lt;code&amp;gt;master&amp;lt;/code&amp;gt; de tu repositorio y no a otro repositorio ni a &amp;lt;code&amp;gt;EGCETSI/decide&amp;lt;/code&amp;gt;).&lt;br /&gt;
# Si abres la pull request que se ha creado, podrás observar abajo cómo se ejecuta el workflow de  Github Actions con la pull request. &lt;br /&gt;
# ¿Es exitoso o fallido? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 6. Matriz con diferentes versiones de python==&lt;br /&gt;
Siguiendo [[Matrices en Github Actions 22 |estas instrucciones]]:&lt;br /&gt;
# Configura el workflow para que lanze las pruebas en varias versiones de Python y Django.&lt;br /&gt;
# ¿Cuántos jobs se están lanzando?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 7. Badges de workflows ==&lt;br /&gt;
&lt;br /&gt;
Siguiendo [[Badges en Actions 22 |estas instrucciones]]&lt;br /&gt;
# Configura el README.md de tu proyecto para que muestre una imagen con el estado de la construcción.&lt;br /&gt;
# Si tienes varios workflow, ¿puede generarse un badge general o tiene que generarse un badge para cada workflow?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8. Reutilización de workflows y creación de releases ==&lt;br /&gt;
Siguiendo [[Reutilización de workflows y creación de releases 23 |estas instrucciones]]:&lt;br /&gt;
# Crea un nuevo workflow con una etapa de buildTest, (que invoque al workflow django.yml) y otro job de release. &lt;br /&gt;
# Haga que este workflow se dispare sólo cuando se cree un tag.&lt;br /&gt;
# Haga que el workflow django.yml sea &amp;quot;invocable&amp;quot; requiriendo el parámetro de secrets CODACY_PROJECT_TOKEN.&lt;br /&gt;
# Cree un tag.&lt;br /&gt;
# ¿Cuántos workflows se disparan?&lt;br /&gt;
# ¿Cuántos jobs se ejecutan del nuevo workflow?&lt;br /&gt;
# ¿Se crea correctamente la release? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
= Uso de Codacy =&lt;br /&gt;
== Ejercicio 9. Calidad de código ==&lt;br /&gt;
# Analiza el reporte de Codacy para el proyecto. &lt;br /&gt;
# ¿Crees que el estado de los problemas (Issues), cobertura y duplicidad de decide son importantes?&lt;br /&gt;
# Siguiendo [https://docs.codacy.com/repositories/badges/  estas instrucciones] configura el README.md de tu proyecto para que muestre el estado de la calidad del proyecto y su análisis de cobertura de tests.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Badges_en_Actions_22&amp;diff=9415</id>
		<title>Badges en Actions 22</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Badges_en_Actions_22&amp;diff=9415"/>
				<updated>2022-10-09T15:41:02Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con « = Badge de worflows de GitHub Actions  = Podemos añadir badges a nuestro README.md relacionados con el estado de un worflow.  Para ello: # Accede a la pestaña Actions. #...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Badge de worflows de GitHub Actions  =&lt;br /&gt;
Podemos añadir badges a nuestro README.md relacionados con el estado de un worflow. &lt;br /&gt;
Para ello:&lt;br /&gt;
# Accede a la pestaña Actions.&lt;br /&gt;
# Accede a uno de los Workflows.&lt;br /&gt;
# Pulsa el botón ... y genera el badge.&lt;br /&gt;
# Incluye el contenido de dicho badge en tu README.MD&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Matrices_en_Github_Actions_22&amp;diff=9414</id>
		<title>Matrices en Github Actions 22</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Matrices_en_Github_Actions_22&amp;diff=9414"/>
				<updated>2022-10-09T15:40:02Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con « = Build matrix en GitHub Actions  =  Podemos indicarle a GitHub que ciertos steps se ejecuten en paralelo. Para ello, hemos de definir una &amp;quot;estrategria&amp;quot; a nivel de job.  P...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Build matrix en GitHub Actions  =&lt;br /&gt;
&lt;br /&gt;
Podemos indicarle a GitHub que ciertos steps se ejecuten en paralelo. Para ello, hemos de definir una &amp;quot;estrategria&amp;quot; a nivel de job. &lt;br /&gt;
Para indicar varias versiones de python a utilizar en el step de &amp;quot;setup-python&amp;quot;, incluiremos lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
build:&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        pyversion: ['3.5','3.8']&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez hecho eso, podremos usar el contexto &amp;quot;matrix&amp;quot; en cualquiera de los steps de este job. En este caso lo usaremos en en el siguiente step:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
- name: Set up Python ${{matrix.pyversion}}&lt;br /&gt;
  uses: actions/setup-python@v1&lt;br /&gt;
  with:&lt;br /&gt;
    python-version: ${{matrix.pyversion}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haz un push y observa la ejecución del workflow.&lt;br /&gt;
&lt;br /&gt;
¿Qué tendríamos que hacer para probar ampliar el build matrix con las versiones de postress 12 y 10.8? ¿Cuántos jobs se ejecutarían?&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=CI_de_decide_22&amp;diff=9413</id>
		<title>CI de decide 22</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=CI_de_decide_22&amp;diff=9413"/>
				<updated>2022-10-09T15:33:42Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «= Decide con GitHub Actions =  El archivo django.yml ofrecido prepara el entorno, prueba decide y reporta a Codacy. Está compuesto por un job: &amp;quot;build&amp;quot;.  En el job &amp;quot;build&amp;quot;...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Decide con GitHub Actions =&lt;br /&gt;
&lt;br /&gt;
El archivo django.yml ofrecido prepara el entorno, prueba decide y reporta a Codacy. Está compuesto por un job: &amp;quot;build&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En el job &amp;quot;build&amp;quot; se especifica que el servicio de base de datos tendrá que estar disponible en el runner de este job. Se le especifica información de healthchek para verificar que el servicio está correctamente levantado antes de continuar con los pasos del job. Para que este job funcione se tendrá que comprobar que:&lt;br /&gt;
# La configuración completa ha de estar en el local_settings.gactions.py. &lt;br /&gt;
# Como no es necesario crear la base de datos de &amp;quot;producción&amp;quot; la parte del &amp;quot;migrate&amp;quot; no haría falta realizarla.&lt;br /&gt;
# Hay un test que puede fallar llamado &amp;quot;test_multiple_auths_mock&amp;quot; dentro del módulo Mixnet. Si falla, debería anularse ese test.&lt;br /&gt;
	&lt;br /&gt;
Haz un push y observa la ejecución del workflow.&lt;br /&gt;
* ¿Se lanzan el job? ¿Por qué?&lt;br /&gt;
* ¿Está correctamente subido el informe de cobertura a Codacy? ¿Por qué?&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=GithubActions_2022&amp;diff=9412</id>
		<title>GithubActions 2022</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=GithubActions_2022&amp;diff=9412"/>
				<updated>2022-10-09T15:29:17Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «== Nociones básicas sobre GitHub Actions== Dentro de cada .yml de la carpeta .github/worflows se define un: # '''workflow''' el cuál se dispara al recibir un evento de Gi...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Nociones básicas sobre GitHub Actions==&lt;br /&gt;
Dentro de cada .yml de la carpeta .github/worflows se define un:&lt;br /&gt;
# '''workflow''' el cuál se dispara al recibir un evento de GitHub. &lt;br /&gt;
# Estos '''eventos''' puede ser desde un push hasta la creación de una issue. Cada workflow permite correr jobs.&lt;br /&gt;
# Los '''jobs'' son secuencias de pasos. Cada uno de estos jobs se ejecutan dentro de un entorno llamado runner.&lt;br /&gt;
# Los '''runners''' son máquinas virtuales que se levantan para cada job. Todos los pasos de un job se ejecutan dentro del mismo runner, por lo que comparten recursos como los archivos y las carpetas.&lt;br /&gt;
# Los '''pasos''' de un job pueden ser simples instrucciones de shell, o utilizar funciones más concretas llamadas '''actions''' como, por ejemplo, hacer un clone.&lt;br /&gt;
&lt;br /&gt;
El siguiente workflow tiene como nombre 'GitHub Actions Demo' y se dispara al hacer un push. Únicamente define un job llamado 'Explore-GitHub-Actions' dentro de un runner de tipo ubuntu-latest. Casi todos los pasos son de tipo shell salvo uno que utiliza la acción actions/checkout@v1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;YAML&amp;quot;&amp;gt;&lt;br /&gt;
name: GitHub Actions Demo&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  Explore-GitHub-Actions:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;🎉 The job was automatically triggered by a ${{ github.event_name }} event.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}.&amp;quot;&lt;br /&gt;
      - name: Check out repository code&lt;br /&gt;
        uses: actions/checkout@v1&lt;br /&gt;
      - run: echo &amp;quot;💡 The ${{ github.repository }} repository has been cloned to the runner.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🖥️  The workflow is now ready to test your code on the runner.&amp;quot;&lt;br /&gt;
      - name: List files in the repository&lt;br /&gt;
        run: |&lt;br /&gt;
          ls ${{ github.workspace }}&lt;br /&gt;
      - run: echo &amp;quot;🍏 This job's status is ${{ job.status }}.&amp;quot;&lt;br /&gt;
      - name: Contains expresion in a step&lt;br /&gt;
        run: echo &amp;quot;Is this branch master or develop? ${{ contains('refs/heads/master refs/heads/develop',github.ref)}}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Añade un archivo con este contenido a tu proyecto en GitHub y comprueba su estado en la pestaña Actions:&lt;br /&gt;
* ¿Cuántos Worflows, jobs, steps se lanzan?&lt;br /&gt;
* ¿Entiendes todo lo que hacen las expresiones ${{ &amp;lt;expresion&amp;gt; }}?&lt;br /&gt;
Para consultar la lista completa de expressiones, visita este [[https://docs.github.com/en/actions/learn-github-actions/expressions  link]].&lt;br /&gt;
&lt;br /&gt;
Para consultar la lista completa de contextos (e.g., github.&amp;lt;&amp;gt;, job.&amp;lt;&amp;gt; o runner.&amp;lt;&amp;gt;), visita este otro [[https://docs.github.com/en/actions/learn-github-actions/contexts link]].&lt;br /&gt;
&lt;br /&gt;
Para consultar la lista completa de acciones, visita el [[https://github.com/marketplace?type=actions link]].&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9411</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9411"/>
				<updated>2022-10-09T15:28:17Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P3-+GIT+y+Codacy/1_vr2tpcm0 aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Git =&lt;br /&gt;
&lt;br /&gt;
[[Uso_de_git | Para repasar y aprender más]]&lt;br /&gt;
== Ejercicio 1. git branch -d ==&lt;br /&gt;
Para preparar el entorno de decide en vuestro GitHub, es recomendable limpiar el proyecto quedarnos únicamente con las ramas relevantes para el desarrollo.&lt;br /&gt;
# Visualiza las ramas desde tu repositorio local. ¿Cómo mostramos las ramas que están en el repositorio remoto (GitHub)?.&lt;br /&gt;
# Borra una rama diferente a la de master y comprueba que se ha borrado en GitHub.&lt;br /&gt;
# Haz lo mismo con todas las ramas que no creas útiles. Puedes automatizar esta tarea haciendo uso de instrucciones de Linux como &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cut&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;xargs&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 2. git rebase y git merge ==&lt;br /&gt;
# Trabajando en local, crea una rama con el objetivo de desarrollar alguna nueva funcionalidad. Haz algunos commits ahí.&lt;br /&gt;
# Muevete a la rama master y haz algún commit más.&lt;br /&gt;
# Ahora quieres subir los cambios al servidor remoto con push, pero no te interesa que la rama que has creado exista en el remoto, ya que era algo local tuyo. ¿Qué consideras más oportuno antes de hacer un push? ¿Rebase ó Merge hacia master? &lt;br /&gt;
# ¿Qué diferencias habría en la rama master?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 3. git cherry-pick ==&lt;br /&gt;
# Trabajando en local, crea una rama y haz varios commits.&lt;br /&gt;
# Vuelve a la rama master.&lt;br /&gt;
# De todos los commits que has hecho en la rama anterior, sólo te interesa uno o dos de ellos, pero no la rama entera, ¿cómo puedes traerte esos cambios a la rama master?&lt;br /&gt;
# ¿Crees que es buena práctica usarlo?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 4. git reset ==&lt;br /&gt;
# Trabajando en local, haz varios commits sobre la rama master pero no lo subas al servidor remoto.&lt;br /&gt;
# Suponiendo que los cambios de código que has hecho están bien, pero que los commits y sus mensaje no te parecen tan correctos, ¿cómo deshacemos esos commits sin perder el código fuente?&lt;br /&gt;
# Y, si quieres desahacer también los cambios hechos en el código, ¿cómo podemos hacerlo?&lt;br /&gt;
# ¿Podemos hacer esto con commits que hayan sido enviados al servidor remoto? ¿Por qué? ¿Qué habría que hacer entonces si quiere revertir cambios en el servidor remoto?&lt;br /&gt;
&lt;br /&gt;
== [[Ejercicios_de_git|Más ejercicios de Git aquí]] ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Uso de Github Actions =&lt;br /&gt;
&lt;br /&gt;
Revisa antes los [[ GithubActions_2022 | Conceptos básicos]] para poder usar Github Actions.&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 5. CI/CD de decide ==&lt;br /&gt;
Siguiendo [[CI de decide 22|estas instrucciones]]:&lt;br /&gt;
# Revisa que al hacer push se lanza el worflow de integración continua de decide.&lt;br /&gt;
# Crea una rama donde reduciremos la carga de tests. Comentaremos los tests de mixnet y el test_complete_voting del módulo Voting.&lt;br /&gt;
# Crea un pull-request siguiendo [https://help.github.com/articles/creating-a-pull-request/#creating-the-pull-request estas instrucciones] (Fíjate bien que la pull request la haces a la rama &amp;lt;code&amp;gt;master&amp;lt;/code&amp;gt; de tu repositorio y no a otro repositorio ni a &amp;lt;code&amp;gt;EGCETSI/decide&amp;lt;/code&amp;gt;).&lt;br /&gt;
# Si abres la pull request que se ha creado, podrás observar abajo cómo se ejecuta el workflow de  Github Actions con la pull request. &lt;br /&gt;
# ¿Es exitoso o fallido? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 6. Matriz con diferentes versiones de python==&lt;br /&gt;
Siguiendo [[Matrices en Github Actions 22 |estas instrucciones]]:&lt;br /&gt;
# Configura el workflow para que lanze las pruebas en varias versiones de Python y Django.&lt;br /&gt;
# ¿Cuántos jobs se están lanzando?&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 7. Badges de workflows ==&lt;br /&gt;
&lt;br /&gt;
Siguiendo [[Badges en Actions 22 |estas instrucciones]]&lt;br /&gt;
# Configura el README.md de tu proyecto para que muestre una imagen con el estado de la construcción.&lt;br /&gt;
&lt;br /&gt;
== Ejercicio 8. Reutilización de workflows y creación de releases ==&lt;br /&gt;
Siguiendo [[Reutilización de workflows y creación de releases 23 |estas instrucciones]]:&lt;br /&gt;
# Crea un nuevo workflow con una etapa de buildTest, (que invoque al workflow django.yml) y otro job de release. &lt;br /&gt;
# Haga que este workflow se dispare sólo cuando se cree un tag.&lt;br /&gt;
# Haga que el workflow django.yml sea &amp;quot;invocable&amp;quot; requiriendo el parámetro de secrets CODACY_PROJECT_TOKEN.&lt;br /&gt;
# Cree un tag.&lt;br /&gt;
# ¿Cuántos workflows se disparan?&lt;br /&gt;
# ¿Cuántos jobs se ejecutan del nuevo workflow?&lt;br /&gt;
# ¿Se crea correctamente la release? ¿Por qué?&lt;br /&gt;
&lt;br /&gt;
= Uso de Codacy =&lt;br /&gt;
== Ejercicio 9. Calidad de código ==&lt;br /&gt;
# Analiza el reporte de Codacy para el proyecto. &lt;br /&gt;
# ¿Crees que el estado de los problemas (Issues), cobertura y duplicidad de decide son importantes?&lt;br /&gt;
# Siguiendo [https://docs.codacy.com/repositories/badges/  estas instrucciones] configura el README.md de tu proyecto para que muestre el estado de la calidad del proyecto y su análisis de cobertura de tests.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9410</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9410"/>
				<updated>2022-10-08T13:17:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: /* Prerrequisitos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P3-+GIT+y+Codacy/1_vr2tpcm0 aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;br /&gt;
Puedes utilizar este repositorio para basarte: [https://github.com/AndresJR/decide-23 Repo con Actions]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9409</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9409"/>
				<updated>2022-10-07T18:27:45Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: /* Prerrequisitos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P3-+GIT+y+Codacy/1_vr2tpcm0 aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3_22-23&amp;diff=9408</id>
		<title>ConfPreviasPractica3 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3_22-23&amp;diff=9408"/>
				<updated>2022-10-07T16:14:40Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Configuración de GitHub&lt;br /&gt;
# Crea una cuenta en http://github.com&lt;br /&gt;
# Desde un terminal crear un par de clave pública y privada SSH:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%  ssh-keygen -t ed25519 -C &amp;quot;your_email@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Esto genera un par de claves pública y privada en la carpeta /home/USUARIO/.ssh/. El fichero /home/usuario/.ssh/id_ed25519.pub contiene la clave pública.&lt;br /&gt;
# Carga la clave pública SSH a github (Arriba a la derecha: zona de usuario -&amp;gt; 'settings' -&amp;gt; SSH keys). Basta con copia el contenido de /home/usuario/.ssh/id_ed25519.pub en el formulario que aparece en github.&lt;br /&gt;
Recuerda: Con una clave pública por ordenador personal que tienes es suficiente. Por tanto, no hace falta que crees un par de claves pública y privada SSH cada vez que comiences un nuevo proyecto, puedes usar la misma siempre que nadie te robe tu clave privada.&lt;br /&gt;
&lt;br /&gt;
La clave pública se almacena dentro de la carpeta .ssh en el home del usuario, tiene una apariencia similar a la siguiente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
% cd .ssh&lt;br /&gt;
% cat id_ed25519.pub &lt;br /&gt;
ssh-ed25519 AAAAB3NzaC1yc2EAAAADAQABAAABAQDrd[... bytes omitidos intencionadamente ...]BDA3z1C1 profesor@pc-14-142&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para saber más: [https://docs.github.com/es/authentication/connecting-to-github-with-ssh]&lt;br /&gt;
&lt;br /&gt;
Por cierto, github permite crear organizaciones en las que participan múltiples usuarios.&lt;br /&gt;
# Por último, Git necesita que se le especifique el nombre y el email del autor del cambio. Esto se hace con las siguientes órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email you@example.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto genera un fichero en /home/usuario/.gitconfig con tus preferencias de usuario. Puede ser modificado con un editor de texto.&lt;br /&gt;
&lt;br /&gt;
Para l@s curios@s, las órdenes de arriba crean un fichero .gitconfig en la carpeta local del usuari@ con este contenido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cat .gitconfig &lt;br /&gt;
[user]&lt;br /&gt;
	name = Profe EGC&lt;br /&gt;
	email = profeegc@gmail.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Prueba a clonar tu proyecto y hacer un push con algún cambio.&lt;br /&gt;
&lt;br /&gt;
* Configuración de Codacy&lt;br /&gt;
# Usando tu cuenta de GitHub entra en https://app.codacy.com y acepta la confirmación de permisos de GitHub.&lt;br /&gt;
# Obtener la Project API del repositorio dentro de Codacy.&lt;br /&gt;
[[Archivo:codacy_api.png|500px]]]&lt;br /&gt;
# En Github, editar las propiedades del proyecto y añade la variable de entorno (secrets) &amp;quot;CODACY_PROJECT_TOKEN&amp;quot;&lt;br /&gt;
[[Archivo:ghSecrets.png|500px]]&lt;br /&gt;
# Trás realizar esto, ya podemos ver que el build termina correctamente y que envia los datos a codacy:&lt;br /&gt;
[[Archivo:codacyOK.png|500px]]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;diff=9407</id>
		<title>ConfPreviasPractica3</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;diff=9407"/>
				<updated>2022-10-07T16:14:24Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Configuración de GitHub&lt;br /&gt;
# Crea una cuenta en http://github.com&lt;br /&gt;
# Desde un terminal crear un par de clave pública y privada SSH:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
% ssh-keygen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Esto genera un par de claves pública y privada en la carpeta /home/USUARIO/.ssh/. El fichero /home/usuario/.ssh/id_rsa.pub contiene la clave pública.&lt;br /&gt;
# Carga la clave pública SSH a github (Arriba a la derecha: zona de usuario -&amp;gt; 'settings' -&amp;gt; SSH keys). Basta con copia el contenido de /home/usuario/.ssh/id_rsa.pub en el formulario que aparece en github.&lt;br /&gt;
Recuerda: Con una clave pública por ordenador personal que tienes es suficiente. Por tanto, no hace falta que crees un par de claves pública y privada SSH cada vez que comiences un nuevo proyecto, puedes usar la misma siempre que nadie te robe tu clave privada.&lt;br /&gt;
&lt;br /&gt;
La clave pública se almacena dentro de la carpeta .ssh en el home del usuario, tiene una apariencia similar a la siguiente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
% cd .ssh&lt;br /&gt;
% cat id_rsa.pub &lt;br /&gt;
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDrd[... bytes omitidos intencionadamente ...]BDA3z1C1 profesor@pc-14-142&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para saber más: [https://git-scm.com/book/es/v2/Git-en-el-Servidor-Generando-tu-clave-p%C3%BAblica-SSH]&lt;br /&gt;
&lt;br /&gt;
Por cierto, github permite crear organizaciones en las que participan múltiples usuarios.&lt;br /&gt;
# Por último, Git necesita que se le especifique el nombre y el email del autor del cambio. Esto se hace con las siguientes órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email you@example.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto genera un fichero en /home/usuario/.gitconfig con tus preferencias de usuario. Puede ser modificado con un editor de texto.&lt;br /&gt;
&lt;br /&gt;
Para l@s curios@s, las órdenes de arriba crean un fichero .gitconfig en la carpeta local del usuari@ con este contenido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cat .gitconfig &lt;br /&gt;
[user]&lt;br /&gt;
	name = Profe EGC&lt;br /&gt;
	email = profeegc@gmail.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Prueba a clonar tu proyecto y hacer un push con algún cambio.&lt;br /&gt;
&lt;br /&gt;
* Configuración en Travis&lt;br /&gt;
# Usando tu cuenta de GitHub entra en https://travis-ci.com y acepta la confirmación de permisos de GitHub.&lt;br /&gt;
# Una vez que estés logueado en Travis CI y se hayan sincronizado tus repositorios de GitHub, ve a tu perfil y activa el repositorio que quieras construir.&lt;br /&gt;
# Confirma que el &amp;lt;code&amp;gt;.travis.yml&amp;lt;/code&amp;gt; existe en la raiz del repositorio. Éste indica a Travis CI lo que tiene que hacer. &lt;br /&gt;
# Haz commit y push del &amp;lt;code&amp;gt;.travis.yml&amp;lt;/code&amp;gt; para iniciar una build de Travis CI o Lanza el build con la opción &amp;quot;Trigger Build&amp;quot; desde Travis CI.&lt;br /&gt;
# Comprueba en la [https://travis-ci.com/ página de estado de la construcción] si tu build ha pasado o falla.&lt;br /&gt;
# En principio, es normal obtener un error de &amp;quot;CODACY_PROJECT_TOKEN missing&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Configuración de Codacy&lt;br /&gt;
# Usando tu cuenta de GitHub entra en https://app.codacy.com y acepta la confirmación de permisos de GitHub.&lt;br /&gt;
# Obtener la Project API del repositorio dentro de Codacy.&lt;br /&gt;
[[Archivo:codacy_api.png|500px]]]&lt;br /&gt;
# En Travis, editar las propiedades del build y añadir la variable de entorno &amp;quot;CODACY_PROJECT_TOKEN&amp;quot;&lt;br /&gt;
[[Archivo:codacy.png|500px]]&lt;br /&gt;
# Trás realizar esto, ya podemos ver que el build termina correctamente y que envia los datos a codacy:&lt;br /&gt;
[[Archivo:codacy_success.png|500px]]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3_22-23&amp;diff=9406</id>
		<title>ConfPreviasPractica3 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3_22-23&amp;diff=9406"/>
				<updated>2022-10-07T16:13:44Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;amp;action=edit  * Configuración de GitHub # Crea una cuenta en http://github.com # Desde un terminal crea...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;amp;action=edit&lt;br /&gt;
&lt;br /&gt;
* Configuración de GitHub&lt;br /&gt;
# Crea una cuenta en http://github.com&lt;br /&gt;
# Desde un terminal crear un par de clave pública y privada SSH:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%  ssh-keygen -t ed25519 -C &amp;quot;your_email@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Esto genera un par de claves pública y privada en la carpeta /home/USUARIO/.ssh/. El fichero /home/usuario/.ssh/id_ed25519.pub contiene la clave pública.&lt;br /&gt;
# Carga la clave pública SSH a github (Arriba a la derecha: zona de usuario -&amp;gt; 'settings' -&amp;gt; SSH keys). Basta con copia el contenido de /home/usuario/.ssh/id_ed25519.pub en el formulario que aparece en github.&lt;br /&gt;
Recuerda: Con una clave pública por ordenador personal que tienes es suficiente. Por tanto, no hace falta que crees un par de claves pública y privada SSH cada vez que comiences un nuevo proyecto, puedes usar la misma siempre que nadie te robe tu clave privada.&lt;br /&gt;
&lt;br /&gt;
La clave pública se almacena dentro de la carpeta .ssh en el home del usuario, tiene una apariencia similar a la siguiente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
% cd .ssh&lt;br /&gt;
% cat id_ed25519.pub &lt;br /&gt;
ssh-ed25519 AAAAB3NzaC1yc2EAAAADAQABAAABAQDrd[... bytes omitidos intencionadamente ...]BDA3z1C1 profesor@pc-14-142&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para saber más: [https://docs.github.com/es/authentication/connecting-to-github-with-ssh]&lt;br /&gt;
&lt;br /&gt;
Por cierto, github permite crear organizaciones en las que participan múltiples usuarios.&lt;br /&gt;
# Por último, Git necesita que se le especifique el nombre y el email del autor del cambio. Esto se hace con las siguientes órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email you@example.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto genera un fichero en /home/usuario/.gitconfig con tus preferencias de usuario. Puede ser modificado con un editor de texto.&lt;br /&gt;
&lt;br /&gt;
Para l@s curios@s, las órdenes de arriba crean un fichero .gitconfig en la carpeta local del usuari@ con este contenido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cat .gitconfig &lt;br /&gt;
[user]&lt;br /&gt;
	name = Profe EGC&lt;br /&gt;
	email = profeegc@gmail.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Prueba a clonar tu proyecto y hacer un push con algún cambio.&lt;br /&gt;
&lt;br /&gt;
* Configuración de Codacy&lt;br /&gt;
# Usando tu cuenta de GitHub entra en https://app.codacy.com y acepta la confirmación de permisos de GitHub.&lt;br /&gt;
# Obtener la Project API del repositorio dentro de Codacy.&lt;br /&gt;
[[Archivo:codacy_api.png|500px]]]&lt;br /&gt;
# En Github, editar las propiedades del proyecto y añade la variable de entorno (secrets) &amp;quot;CODACY_PROJECT_TOKEN&amp;quot;&lt;br /&gt;
[[Archivo:ghSecrets.png|500px]]&lt;br /&gt;
# Trás realizar esto, ya podemos ver que el build termina correctamente y que envia los datos a codacy:&lt;br /&gt;
[[Archivo:codacyOK.png|500px]]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;diff=9405</id>
		<title>ConfPreviasPractica3</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=ConfPreviasPractica3&amp;diff=9405"/>
				<updated>2022-10-07T16:13:14Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Configuración de GitHub&lt;br /&gt;
# Crea una cuenta en http://github.com&lt;br /&gt;
# Desde un terminal crear un par de clave pública y privada SSH:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%  ssh-keygen -t ed25519 -C &amp;quot;your_email@example.com&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Esto genera un par de claves pública y privada en la carpeta /home/USUARIO/.ssh/. El fichero /home/usuario/.ssh/id_ed25519.pub contiene la clave pública.&lt;br /&gt;
# Carga la clave pública SSH a github (Arriba a la derecha: zona de usuario -&amp;gt; 'settings' -&amp;gt; SSH keys). Basta con copia el contenido de /home/usuario/.ssh/id_ed25519.pub en el formulario que aparece en github.&lt;br /&gt;
Recuerda: Con una clave pública por ordenador personal que tienes es suficiente. Por tanto, no hace falta que crees un par de claves pública y privada SSH cada vez que comiences un nuevo proyecto, puedes usar la misma siempre que nadie te robe tu clave privada.&lt;br /&gt;
&lt;br /&gt;
La clave pública se almacena dentro de la carpeta .ssh en el home del usuario, tiene una apariencia similar a la siguiente.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
% cd .ssh&lt;br /&gt;
% cat id_ed25519.pub &lt;br /&gt;
ssh-ed25519 AAAAB3NzaC1yc2EAAAADAQABAAABAQDrd[... bytes omitidos intencionadamente ...]BDA3z1C1 profesor@pc-14-142&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para saber más: [https://docs.github.com/es/authentication/connecting-to-github-with-ssh]&lt;br /&gt;
&lt;br /&gt;
Por cierto, github permite crear organizaciones en las que participan múltiples usuarios.&lt;br /&gt;
# Por último, Git necesita que se le especifique el nombre y el email del autor del cambio. Esto se hace con las siguientes órdenes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email you@example.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto genera un fichero en /home/usuario/.gitconfig con tus preferencias de usuario. Puede ser modificado con un editor de texto.&lt;br /&gt;
&lt;br /&gt;
Para l@s curios@s, las órdenes de arriba crean un fichero .gitconfig en la carpeta local del usuari@ con este contenido:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cat .gitconfig &lt;br /&gt;
[user]&lt;br /&gt;
	name = Profe EGC&lt;br /&gt;
	email = profeegc@gmail.com&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Prueba a clonar tu proyecto y hacer un push con algún cambio.&lt;br /&gt;
&lt;br /&gt;
* Configuración de Codacy&lt;br /&gt;
# Usando tu cuenta de GitHub entra en https://app.codacy.com y acepta la confirmación de permisos de GitHub.&lt;br /&gt;
# Obtener la Project API del repositorio dentro de Codacy.&lt;br /&gt;
[[Archivo:codacy_api.png|500px]]]&lt;br /&gt;
# En Github, editar las propiedades del proyecto y añade la variable de entorno (secrets) &amp;quot;CODACY_PROJECT_TOKEN&amp;quot;&lt;br /&gt;
[[Archivo:ghSecrets.png|500px]]&lt;br /&gt;
# Trás realizar esto, ya podemos ver que el build termina correctamente y que envia los datos a codacy:&lt;br /&gt;
[[Archivo:codacyOK.png|500px]]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:GhSecrets.png&amp;diff=9404</id>
		<title>Archivo:GhSecrets.png</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:GhSecrets.png&amp;diff=9404"/>
				<updated>2022-10-07T16:12:48Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:CodacyOK.png&amp;diff=9403</id>
		<title>Archivo:CodacyOK.png</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Archivo:CodacyOK.png&amp;diff=9403"/>
				<updated>2022-10-07T16:12:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9402</id>
		<title>Gestión de Código Fuente e Integración Continua 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Gesti%C3%B3n_de_C%C3%B3digo_Fuente_e_Integraci%C3%B3n_Continua_22-23&amp;diff=9402"/>
				<updated>2022-10-07T16:04:22Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Página_Principal -&amp;gt; 2022/2023 -&amp;gt; Prácticas - 22/23  = Prerrequisitos =  * Ver video de presentación aquí: [aquí] * ConfPreviasPractica3 22-23 | Configura...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [aquí]&lt;br /&gt;
* [[ConfPreviasPractica3 22-23 | Configuraciones Previas]]&lt;br /&gt;
* [https://thucnc.medium.com/how-to-show-current-git-branch-with-colors-in-bash-prompt-380d05a24745 Cómo mostrar la rama de Git en el promt de Bash]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9401</id>
		<title>Prácticas - 22/23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9401"/>
				<updated>2022-10-07T16:03:41Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]]&lt;br /&gt;
&lt;br /&gt;
* Práctica 1: [[Instalación de Decide 22-23 | Instalación de Decide]]&lt;br /&gt;
* Práctica 2: [[Pruebas de software 22-23 | Pruebas de Software]]&lt;br /&gt;
* Práctica 3: [[Gestión de Código Fuente e Integración Continua 22-23 | Gestión de Código Fuente e Integración Continua]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9400</id>
		<title>Prácticas - 22/23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pr%C3%A1cticas_-_22/23&amp;diff=9400"/>
				<updated>2022-10-07T16:02:20Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]]&lt;br /&gt;
&lt;br /&gt;
* Práctica 1: [[Instalación de Decide 22-23 | Instalación de Decide]]&lt;br /&gt;
* Práctica 2: [[Pruebas de software 22-23 | Pruebas de Software]]&lt;br /&gt;
* Práctica 3: [[Gestión de Código Fuente e Integración Continua 23-23 | Gestión de Código Fuente e Integración Continua]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Link1&amp;diff=9390</id>
		<title>Link1</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Link1&amp;diff=9390"/>
				<updated>2022-10-04T08:16:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;‎&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class VotingModelTestCase(BaseTestCase):&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        &lt;br /&gt;
        q = Question(desc='Descripcion')&lt;br /&gt;
        q.save()&lt;br /&gt;
        &lt;br /&gt;
        opt1 = QuestionOption(question=q, option='opcion 1')&lt;br /&gt;
        opt1.save()&lt;br /&gt;
        opt1 = QuestionOption(question=q, option='opcion 2')&lt;br /&gt;
        opt1.save()&lt;br /&gt;
&lt;br /&gt;
        self.v = Voting(name='Votacion', question=q)&lt;br /&gt;
        self.v.save()&lt;br /&gt;
        super().setUp()&lt;br /&gt;
&lt;br /&gt;
    def tearDown(self):&lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.v = None&lt;br /&gt;
&lt;br /&gt;
    def testExist(self):&lt;br /&gt;
        v=Voting.objects.get(name='Votacion')&lt;br /&gt;
        self.assertEquals(v.question.options.all()[0].option, &amp;quot;opcion 1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
‎&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_del_Modelo_22-23&amp;diff=9389</id>
		<title>Pruebas del Modelo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_del_Modelo_22-23&amp;diff=9389"/>
				<updated>2022-10-04T08:14:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Como vimos en las clase de teoría, para poder probar los elementos persistentes disponemos de las pruebas CRUD. &lt;br /&gt;
Es importante conocer que en Django los tests no se ejecutan sobre la misma base de datos que la que usamos en producción, por lo que los elementos que creemos no permanecerán en nuestra instalación de producción.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def setUp(self):&lt;br /&gt;
        super().setUp()&lt;br /&gt;
        self.census = Census(voting_id=1, voter_id=1)&lt;br /&gt;
        self.census.save()&lt;br /&gt;
&lt;br /&gt;
def tearDown(self):&lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.census = None&lt;br /&gt;
&lt;br /&gt;
def test_store_census(self):&lt;br /&gt;
        self.assertEqual(Census.objects.count(), 1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
También hay otros métodos que se definen en los modelos y que puede tener sentido quere probar aunque no persistan datos, como por ejempo __str__ de voting. El siguiente método lo podemos añadir dentro de la clase de test de Voting y utilizar sus métodos auxiliares como el &amp;quot;create_voting()&amp;quot;. Es método añade varias opciones con el nombre &amp;quot;opción ''i'' (''i+1'')&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_Voting_toString(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        self.assertEquals(str(v),&amp;quot;test voting&amp;quot;)&lt;br /&gt;
        self.assertEquals(str(v.question),&amp;quot;test question&amp;quot;)&lt;br /&gt;
        self.assertEquals(str(v.question.options.all()[0]),&amp;quot;option 1 (2)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación con una pregunta y dos opciones de respuesta.&lt;br /&gt;
&lt;br /&gt;
[[link1]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_carga_22-23&amp;diff=9388</id>
		<title>Pruebas de carga 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_carga_22-23&amp;diff=9388"/>
				<updated>2022-10-03T10:38:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Las pruebas de carga se usan para simular cómo responde un software ante una serie de usuarios concurrentes que la usan.  Son especialmente útiles cuando estimamos que pu...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Las pruebas de carga se usan para simular cómo responde un software ante una serie de usuarios concurrentes que la usan. &lt;br /&gt;
Son especialmente útiles cuando estimamos que pueden existir picos de uso de una aplicación (p.e. Amazon en Black friday). &lt;br /&gt;
&lt;br /&gt;
Este pudiese ser el caso de decide. Para observar como responde vamos a usar locust, una aplicación python que esta dirigida a efectuar este tipo de operaciones.&lt;br /&gt;
&lt;br /&gt;
=  Test de estrés con Locust = &lt;br /&gt;
Antes de empezar, hay que entender para qué sirven las pruebas de estrés. A veces necesitamos soportar que nuestra aplicación ofrezca una cantidad de peticiones por segundo porque habrá muchos usuarios entrando a la misma vez y, ante este estrés, tenemos que comprobar cómo se comporta nuestra aplicación.&lt;br /&gt;
&lt;br /&gt;
No es lo mismo que cuando la estresemos nos de un error 500 a que nos devuelva la petición de otro usuario. Con estos test conseguiremos comprobar cuál es ese comportamiento y, quizás, entender cómo mejorar la velocidad de procesamiento de las peticiones para permitir más peticiones por segundo.&lt;br /&gt;
&lt;br /&gt;
Para ejecutar los test de estrés utilizando locust, necesitaremos tener instalado locust:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ pip install locust&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Una vez instalado, necesitaremos tener un fichero locustfile.py donde tengamos la configuración de lo que vamos a ejecutar. En nuestro caso, tenemos hecho dos ejemplos dentro de decide/loadtest/locustfile.py:&lt;br /&gt;
&lt;br /&gt;
*Visualizer: Simula un usuario que entra en el visualizador de una votación.&lt;br /&gt;
&lt;br /&gt;
Para ejecutar el test de Visualizer, tenemos que tener en cuenta que entra en la votación 1, por lo que necesitaremos tenerla creada para que funcione correctamente, una vez hecho esto, podemos comenzar a probar con el siguiente comando (dentro de la carpeta loadtest):&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ locust Visualizer&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Esto abrirá un servidor que podremos ver en el navegador, el mismo comando nos dirá el puerto. Cuando se abra, nos preguntará cuantos usuarios queremos que hagan peticiones a la vez y cómo queremos que vaya creciendo hasta llegar a ese número. Por ejemplo, si ponemos 100 y 5, estaremos creando 5 nuevos usuarios cada segundo hasta llegar a 100.&lt;br /&gt;
&lt;br /&gt;
*Voters: Simula un usuario cuando va a votar, por lo que con este ejemplo estaremos comprobando cuantas votaciones podemos hacer por segundo. A nivel de locust, esos usuarios hacen la secuencia de peticiones REST: login, getuser y store. Para ello, este test utilizar cuentas de usuarios previamente creada.&lt;br /&gt;
&lt;br /&gt;
Para ejecutar el test de Voter, necesitaremos realizar varios pasos previos.&lt;br /&gt;
# Necesitaremos la votación 1 abierta.&lt;br /&gt;
# Necesitaremos crear una serie de usuarios en el censo de esta votación, para que cuando hagamos el test, estos usuario puedan autenticarse y votar correctamente. Para facilitar esta tarea, hay creado un script de python gen_census.py, con el cual se crean los usuarios que tenemos dentro del fichero voters.json y se añaden al censo utilizando la librería requests. Para que este script funcione, necesitaremos tener instalado request:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ pip install requests&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una vez instalado, ejecutamos el script:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ python gen_census.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Nota:''' habrá que editar el contenido de gen_census.py para configurar la cuenta de usuario administrador para crear estos usuarios y su censo.&lt;br /&gt;
&lt;br /&gt;
Tras esto, ya podremos comenzar el test de estrés de votantes:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ locust Voters&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Importante mirar bien el fichero locustfile.py, donde existen algunas configuraciones que podremos cambiar, dependiendo del HOST donde queramos hacer las pruebas y del id de la votación.&lt;br /&gt;
&lt;br /&gt;
A tener en cuenta:&lt;br /&gt;
&lt;br /&gt;
*En un servidor local, con un postgres que por defecto nos viene limitado a 100 usuarios concurrentes, cuando pongamos más de 100, lo normal es que empiecen a fallar muchas peticiones.&lt;br /&gt;
*Si hacemos las pruebas en local, donde tenemos activado el modo debug de Django, lo normal es que las peticiones tarden algo más y consigamos menos RPS (Peticiones por segundo).&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_22-23&amp;diff=9387</id>
		<title>Pruebas de las Vistas 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_22-23&amp;diff=9387"/>
				<updated>2022-10-03T10:36:19Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que of...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que ofrecen. Otrás, sin embargo, ofrecen una vista HTML que tendremos que probar con otros frameworks como Selenium.&lt;br /&gt;
&lt;br /&gt;
= Pruebas de APIs =&lt;br /&gt;
Decide tiene implementada una clase para usar como base a la hora de implementar los test de interacción con APIs, BaseTestCase. Esa clase nos ofrece un ''client'' para hacer llamadas REST además de métodos de ''login'' y ''logout'' para simular el ingreso de un usuario en el sistema.&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo podemos ver como se realizar una prueba donde se intenta realizar una acción nula sobre una votación ya creada. El resultado esperado es un 400.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_update_voting_400(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        data = {} #El campo action es requerido en la request&lt;br /&gt;
        self.login()&lt;br /&gt;
        response = self.client.put('/voting/{}/'.format(v.pk), data, format= 'json')&lt;br /&gt;
        self.assertEquals(response.status_code, 400)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación a através de su API y la recupere del modelo.&lt;br /&gt;
&lt;br /&gt;
[[link2]]&lt;br /&gt;
&lt;br /&gt;
= Pruebas de navegación =&lt;br /&gt;
&lt;br /&gt;
Selenium es un framework para testing y automatización de acciones web en general que nos permite simular como actuaría un usuario frente a nuestra aplicación[[https://www.seleniumhq.org/]]&lt;br /&gt;
&lt;br /&gt;
En nuestro caso usaremos selenium dada la dificultad de probar las vistas en django. Estas vistas, normalmente, tienen que lidiar con dependencias AJAX, Javascript, etc. para poder ejecutarse normalmente. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo podemos probar si el acceso a la web de login es correcto o no. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Instalamos selenium &lt;br /&gt;
&amp;lt;source&amp;gt; $ pip install selenium &amp;lt;/source&amp;gt;&lt;br /&gt;
Instalamos, si no lo hemos hecho ya, chromiun y el driver para chromium que se encargará de reproducir el código dentro del navegador&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finalmente, escribimos el código de nuestro test. &lt;br /&gt;
Los test de Selenium requerirán que django levante el servidor durante las pruebas. Estos casos de prueba deberan extender de StaticLiveServerTestCase para que funcione correctamente. Sí, además, queremos hacer uso de la funcionalidad que nos daba BaseTestCase, crearemos un atrbuto para ello:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = True&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se ha marcado la opcion ''headless'' para que Chrome no se abra visualmente y así pueda ser ejecutado en servidores sin interfaz gráfica. Si eliminamos esa línea, veremos como Chrome se abre y se navega por el sistema decide.&lt;br /&gt;
&lt;br /&gt;
Un método para comprobar que un login es correcto, sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[link3]]&lt;br /&gt;
* '''Importante''' estos tests los podemos ejecutar desde dentro del propio sistema django o bien implementarlos para ejecutarlos de manera autonoma&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para comprobar el correcto funcionamiento al introducir un login incorrecto&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 4'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para crear una pregunta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 5'''&lt;br /&gt;
&lt;br /&gt;
Para crear scripts con navegaciones más largas y complejas, podemos descargar e instalar la extensión de selenium para nuestro navegador y registrar así los diferentes pasos de nuestra prueba y, posteriormente, integrarlo dentro de nuestra prueba en Python:&lt;br /&gt;
&lt;br /&gt;
* [[Archivo:selenium-ide.png||500px]]&lt;br /&gt;
* Grabar una prueba para realizar un login correcto. &lt;br /&gt;
[[Archivo:selenium-record.png||500px]]&lt;br /&gt;
* Replicar la prueba&lt;br /&gt;
&lt;br /&gt;
* Integrarlo dentro de nuestra clase en Python&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_del_Modelo_22-23&amp;diff=9386</id>
		<title>Pruebas del Modelo 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_del_Modelo_22-23&amp;diff=9386"/>
				<updated>2022-10-03T10:35:59Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con « Las pruebas unitarias están destinadas a identificar errores en partes pequeñas de código con la idea de maximizar la cobertura de nuestros tests. Recordar que la funci...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Las pruebas unitarias están destinadas a identificar errores en partes pequeñas de código con la idea de maximizar la cobertura de nuestros tests. Recordar que la función de cobertura de las pruebas es algo que debemos decidir. Los tests de cada módulo se implementan en archivos python que comienzan por test*&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Lo primero que vamos a hacer es crear un nuevo test para el modulo de autenticación de decide donde en vez de probar la aplicación, comprobaremos que la suma de dos enteros es correcta. &lt;br /&gt;
'''Nota''' esta prueba es para familiarizarnos con el framework. Aquí no estamos probando nuestra app Django. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
class SimpleTest(TestCase):&lt;br /&gt;
def test_basic_addition(self):&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 Tests that 1 + 1 always equals 2.&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 self.assertEqual(1 + 1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para ejecutar los tests deberemos ejecutar ./manage.py test authentication.&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Para probar la cobertura de nuestras pruebas usaremos la aplicación coverage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ pip install coverage&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para lanzar el analisis de cobertura:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
coverage run --source . ./manage.py test -v 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Añadimos la opción &amp;quot;--source .&amp;quot; para sólo analizar nuestro código de decide pero no las bibliotecas incluidas.&lt;br /&gt;
Añadimos la opción &amp;quot;-v 2&amp;quot; para hacer la salida más verbosa, es decir, ver más información sobre los tests.&lt;br /&gt;
Podemos añadir la opción &amp;quot;--keepdb&amp;quot; para evitar que la base de datos de prueba se borre al finalizar. Entre otras cosas, eso evitará que se tenga que crear la base de datos la próxima vez que vayan a correrse los test.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
coverage html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Finalmente podemos ver el contenido del html abriendo &amp;quot;decide/htmlcov/index.html&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
Pensar los tests que necesitaremos para nuestro proyecto decide.&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_unitarias_22-23&amp;diff=9385</id>
		<title>Pruebas unitarias 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_unitarias_22-23&amp;diff=9385"/>
				<updated>2022-10-03T10:35:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con « Las pruebas unitarias están destinadas a identificar errores en partes pequeñas de código con la idea de maximizar la cobertura de nuestros tests. Recordar que la funci...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Las pruebas unitarias están destinadas a identificar errores en partes pequeñas de código con la idea de maximizar la cobertura de nuestros tests. Recordar que la función de cobertura de las pruebas es algo que debemos decidir. Los tests de cada módulo se implementan en archivos python que comienzan por test*&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Lo primero que vamos a hacer es crear un nuevo test para el modulo de autenticación de decide donde en vez de probar la aplicación, comprobaremos que la suma de dos enteros es correcta. &lt;br /&gt;
'''Nota''' esta prueba es para familiarizarnos con el framework. Aquí no estamos probando nuestra app Django. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
class SimpleTest(TestCase):&lt;br /&gt;
def test_basic_addition(self):&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 Tests that 1 + 1 always equals 2.&lt;br /&gt;
 &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 self.assertEqual(1 + 1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para ejecutar los tests deberemos ejecutar ./manage.py test authentication.&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Para probar la cobertura de nuestras pruebas usaremos la aplicación coverage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
$ pip install coverage&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para lanzar el analisis de cobertura:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
coverage run --source . ./manage.py test -v 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Añadimos la opción &amp;quot;--source .&amp;quot; para sólo analizar nuestro código de decide pero no las bibliotecas incluidas.&lt;br /&gt;
Añadimos la opción &amp;quot;-v 2&amp;quot; para hacer la salida más verbosa, es decir, ver más información sobre los tests.&lt;br /&gt;
Podemos añadir la opción &amp;quot;--keepdb&amp;quot; para evitar que la base de datos de prueba se borre al finalizar. Entre otras cosas, eso evitará que se tenga que crear la base de datos la próxima vez que vayan a correrse los test.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
coverage html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Finalmente podemos ver el contenido del html abriendo &amp;quot;decide/htmlcov/index.html&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
Pensar los tests que necesitaremos para nuestro proyecto decide.&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_software_22-23&amp;diff=9384</id>
		<title>Pruebas de software 22-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_software_22-23&amp;diff=9384"/>
				<updated>2022-10-03T10:35:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P2-+Pruebas/1_kj0hbxrx aquí]&lt;br /&gt;
* Instrucciones para la descarga Chrome y el webdriver de Chrome:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt-get install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Código del script de Python para probar el funcionamiento de Selenium:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
&lt;br /&gt;
options = webdriver.ChromeOptions()&lt;br /&gt;
options.headless = True&lt;br /&gt;
driver = webdriver.Chrome(options=options)&lt;br /&gt;
driver.get(&amp;quot;https://www.google.com/&amp;quot;)&lt;br /&gt;
print('Title: %s' % driver.title)&lt;br /&gt;
driver.quit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ajustes en la base de datos -&amp;gt; [[Tips and tricks]]&lt;br /&gt;
&lt;br /&gt;
= Automatizando Pruebas =&lt;br /&gt;
La estructura de Django se divide en vistas, modelos, plantillas principalmente. En esta práctica veremos como testear cada una de las partes de django así como ejecutar las pruebas de carga del mismo. Para lanzar las pruebas Django utiliza el framework de pruebas unittest el cual esta inspirado en Junit. Estas pruebas se ejecutarán con el comando:&lt;br /&gt;
&lt;br /&gt;
[[Archivo:django-arch.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre todos los tests disponibles&lt;br /&gt;
$./manage.py test&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre los tests dentro de “voting”&lt;br /&gt;
$./manage.py test voting&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Pruebas unitarias 22-23 | Pruebas unitarias]]&lt;br /&gt;
* [[Pruebas del Modelo 22-23 | Pruebas del Modelo]]&lt;br /&gt;
* [[Pruebas de las Vistas 22-23 | Pruebas de las Vistas]]&lt;br /&gt;
* [[Pruebas de carga 22-23 | Pruebas de carga]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Archivo:02-Decide-Test_2021.pdf]]&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Link2&amp;diff=9383</id>
		<title>Link2</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Link2&amp;diff=9383"/>
				<updated>2022-10-03T10:34:02Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def testCreateVotinAPI(self):&lt;br /&gt;
        self.login()&lt;br /&gt;
        data = {&lt;br /&gt;
            'name': 'Example',&lt;br /&gt;
            'desc': 'Description example',&lt;br /&gt;
            'question': 'I want a ',&lt;br /&gt;
            'question_opt': ['cat', 'dog', 'horse']&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        response = self.client.post('/voting/', data, format='json')&lt;br /&gt;
        self.assertEqual(response.status_code, 201)&lt;br /&gt;
&lt;br /&gt;
        voting = Voting.objects.get(name='Example')&lt;br /&gt;
        self.assertEqual(voting.desc, 'Description example')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Link3&amp;diff=9382</id>
		<title>Link3</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Link3&amp;diff=9382"/>
				<updated>2022-10-03T10:33:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; from pyexpat import model from django.test import TestCase from django.contrib.staticfiles.testing import StaticLiveServerTestCase  from sel...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from pyexpat import model&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
from voting.models import Question, Voting&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = False&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
        &lt;br /&gt;
    def test_simpleVisualizer(self):        &lt;br /&gt;
        q = Question(desc='test question')&lt;br /&gt;
        q.save()&lt;br /&gt;
        v = Voting(name='test voting', question=q)&lt;br /&gt;
        v.save()&lt;br /&gt;
        response =self.driver.get(f'{self.live_server_url}/visualizer/{v.pk}/')&lt;br /&gt;
        vState= self.driver.find_element(By.TAG_NAME,&amp;quot;h2&amp;quot;).text&lt;br /&gt;
        self.assertTrue(vState, &amp;quot;Votación no comenzada&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9381</id>
		<title>Pruebas de las Vistas 21-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9381"/>
				<updated>2022-10-03T10:30:31Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que ofrecen. Otrás, sin embargo, ofrecen una vista HTML que tendremos que probar con otros frameworks como Selenium.&lt;br /&gt;
&lt;br /&gt;
= Pruebas de APIs =&lt;br /&gt;
Decide tiene implementada una clase para usar como base a la hora de implementar los test de interacción con APIs, BaseTestCase. Esa clase nos ofrece un ''client'' para hacer llamadas REST además de métodos de ''login'' y ''logout'' para simular el ingreso de un usuario en el sistema.&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo podemos ver como se realizar una prueba donde se intenta realizar una acción nula sobre una votación ya creada. El resultado esperado es un 400.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_update_voting_400(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        data = {} #El campo action es requerido en la request&lt;br /&gt;
        self.login()&lt;br /&gt;
        response = self.client.put('/voting/{}/'.format(v.pk), data, format= 'json')&lt;br /&gt;
        self.assertEquals(response.status_code, 400)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación a através de su API y la recupere del modelo.&lt;br /&gt;
&lt;br /&gt;
[[link2]]&lt;br /&gt;
&lt;br /&gt;
= Pruebas de navegación =&lt;br /&gt;
&lt;br /&gt;
Selenium es un framework para testing y automatización de acciones web en general que nos permite simular como actuaría un usuario frente a nuestra aplicación[[https://www.seleniumhq.org/]]&lt;br /&gt;
&lt;br /&gt;
En nuestro caso usaremos selenium dada la dificultad de probar las vistas en django. Estas vistas, normalmente, tienen que lidiar con dependencias AJAX, Javascript, etc. para poder ejecutarse normalmente. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo podemos probar si el acceso a la web de login es correcto o no. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Instalamos selenium &lt;br /&gt;
&amp;lt;source&amp;gt; $ pip install selenium &amp;lt;/source&amp;gt;&lt;br /&gt;
Instalamos, si no lo hemos hecho ya, chromiun y el driver para chromium que se encargará de reproducir el código dentro del navegador&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finalmente, escribimos el código de nuestro test. &lt;br /&gt;
Los test de Selenium requerirán que django levante el servidor durante las pruebas. Estos casos de prueba deberan extender de StaticLiveServerTestCase para que funcione correctamente. Sí, además, queremos hacer uso de la funcionalidad que nos daba BaseTestCase, crearemos un atrbuto para ello:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = True&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se ha marcado la opcion ''headless'' para que Chrome no se abra visualmente y así pueda ser ejecutado en servidores sin interfaz gráfica. Si eliminamos esa línea, veremos como Chrome se abre y se navega por el sistema decide.&lt;br /&gt;
&lt;br /&gt;
Un método para comprobar que un login es correcto, sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[link3]]&lt;br /&gt;
* '''Importante''' estos tests los podemos ejecutar desde dentro del propio sistema django o bien implementarlos para ejecutarlos de manera autonoma&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para comprobar el correcto funcionamiento al introducir un login incorrecto&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 4'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para crear una pregunta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 5'''&lt;br /&gt;
&lt;br /&gt;
Para crear scripts con navegaciones más largas y complejas, podemos descargar e instalar la extensión de selenium para nuestro navegador y registrar así los diferentes pasos de nuestra prueba y, posteriormente, integrarlo dentro de nuestra prueba en Python:&lt;br /&gt;
&lt;br /&gt;
* [[Archivo:selenium-ide.png||500px]]&lt;br /&gt;
* Grabar una prueba para realizar un login correcto. &lt;br /&gt;
[[Archivo:selenium-record.png||500px]]&lt;br /&gt;
* Replicar la prueba&lt;br /&gt;
&lt;br /&gt;
* Integrarlo dentro de nuestra clase en Python&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9380</id>
		<title>Pruebas de las Vistas 21-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9380"/>
				<updated>2022-10-03T10:30:10Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P2-+Pruebas/1_kj0hbxrx aquí]&lt;br /&gt;
* Instrucciones para la descarga Chrome y el webdriver de Chrome:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt-get install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Código del script de Python para probar el funcionamiento de Selenium:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
&lt;br /&gt;
options = webdriver.ChromeOptions()&lt;br /&gt;
options.headless = True&lt;br /&gt;
driver = webdriver.Chrome(options=options)&lt;br /&gt;
driver.get(&amp;quot;https://www.google.com/&amp;quot;)&lt;br /&gt;
print('Title: %s' % driver.title)&lt;br /&gt;
driver.quit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ajustes en la base de datos -&amp;gt; [[Tips and tricks]]&lt;br /&gt;
&lt;br /&gt;
= Automatizando Pruebas =&lt;br /&gt;
La estructura de Django se divide en vistas, modelos, plantillas principalmente. En esta práctica veremos como testear cada una de las partes de django así como ejecutar las pruebas de carga del mismo. Para lanzar las pruebas Django utiliza el framework de pruebas unittest el cual esta inspirado en Junit. Estas pruebas se ejecutarán con el comando:&lt;br /&gt;
&lt;br /&gt;
[[Archivo:django-arch.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre todos los tests disponibles&lt;br /&gt;
$./manage.py test&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre los tests dentro de “voting”&lt;br /&gt;
$./manage.py test voting&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Pruebas unitarias 21-23 | Pruebas unitarias]]&lt;br /&gt;
* [[Pruebas del Modelo 21-23 | Pruebas del Modelo]]&lt;br /&gt;
* [[Pruebas de las Vistas 21-23 | Pruebas de las Vistas]]&lt;br /&gt;
* [[Pruebas de carga 21-23 | Pruebas de carga]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Archivo:02-Decide-Test_2021.pdf]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------------------- VISTAS ----------------&lt;br /&gt;
&lt;br /&gt;
Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que ofrecen. Otrás, sin embargo, ofrecen una vista HTML que tendremos que probar con otros frameworks como Selenium.&lt;br /&gt;
&lt;br /&gt;
= Pruebas de APIs =&lt;br /&gt;
Decide tiene implementada una clase para usar como base a la hora de implementar los test de interacción con APIs, BaseTestCase. Esa clase nos ofrece un ''client'' para hacer llamadas REST además de métodos de ''login'' y ''logout'' para simular el ingreso de un usuario en el sistema.&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo podemos ver como se realizar una prueba donde se intenta realizar una acción nula sobre una votación ya creada. El resultado esperado es un 400.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_update_voting_400(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        data = {} #El campo action es requerido en la request&lt;br /&gt;
        self.login()&lt;br /&gt;
        response = self.client.put('/voting/{}/'.format(v.pk), data, format= 'json')&lt;br /&gt;
        self.assertEquals(response.status_code, 400)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación a através de su API y la recupere del modelo.&lt;br /&gt;
&lt;br /&gt;
[[link2]]&lt;br /&gt;
&lt;br /&gt;
= Pruebas de navegación =&lt;br /&gt;
&lt;br /&gt;
Selenium es un framework para testing y automatización de acciones web en general que nos permite simular como actuaría un usuario frente a nuestra aplicación[[https://www.seleniumhq.org/]]&lt;br /&gt;
&lt;br /&gt;
En nuestro caso usaremos selenium dada la dificultad de probar las vistas en django. Estas vistas, normalmente, tienen que lidiar con dependencias AJAX, Javascript, etc. para poder ejecutarse normalmente. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo podemos probar si el acceso a la web de login es correcto o no. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Instalamos selenium &lt;br /&gt;
&amp;lt;source&amp;gt; $ pip install selenium &amp;lt;/source&amp;gt;&lt;br /&gt;
Instalamos, si no lo hemos hecho ya, chromiun y el driver para chromium que se encargará de reproducir el código dentro del navegador&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finalmente, escribimos el código de nuestro test. &lt;br /&gt;
Los test de Selenium requerirán que django levante el servidor durante las pruebas. Estos casos de prueba deberan extender de StaticLiveServerTestCase para que funcione correctamente. Sí, además, queremos hacer uso de la funcionalidad que nos daba BaseTestCase, crearemos un atrbuto para ello:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = True&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se ha marcado la opcion ''headless'' para que Chrome no se abra visualmente y así pueda ser ejecutado en servidores sin interfaz gráfica. Si eliminamos esa línea, veremos como Chrome se abre y se navega por el sistema decide.&lt;br /&gt;
&lt;br /&gt;
Un método para comprobar que un login es correcto, sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[link3]]&lt;br /&gt;
* '''Importante''' estos tests los podemos ejecutar desde dentro del propio sistema django o bien implementarlos para ejecutarlos de manera autonoma&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para comprobar el correcto funcionamiento al introducir un login incorrecto&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 4'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para crear una pregunta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 5'''&lt;br /&gt;
&lt;br /&gt;
Para crear scripts con navegaciones más largas y complejas, podemos descargar e instalar la extensión de selenium para nuestro navegador y registrar así los diferentes pasos de nuestra prueba y, posteriormente, integrarlo dentro de nuestra prueba en Python:&lt;br /&gt;
&lt;br /&gt;
* [[Archivo:selenium-ide.png||500px]]&lt;br /&gt;
* Grabar una prueba para realizar un login correcto. &lt;br /&gt;
[[Archivo:selenium-record.png||500px]]&lt;br /&gt;
* Replicar la prueba&lt;br /&gt;
&lt;br /&gt;
* Integrarlo dentro de nuestra clase en Python&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9379</id>
		<title>Pruebas de las Vistas 21-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9379"/>
				<updated>2022-10-03T10:23:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que ofrecen. Otrás, sin embargo, ofrecen una vista HTML que tendremos que probar con otros frameworks como Selenium.&lt;br /&gt;
&lt;br /&gt;
= Pruebas de APIs =&lt;br /&gt;
Decide tiene implementada una clase para usar como base a la hora de implementar los test de interacción con APIs, BaseTestCase. Esa clase nos ofrece un ''client'' para hacer llamadas REST además de métodos de ''login'' y ''logout'' para simular el ingreso de un usuario en el sistema.&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo podemos ver como se realizar una prueba donde se intenta realizar una acción nula sobre una votación ya creada. El resultado esperado es un 400.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_update_voting_400(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        data = {} #El campo action es requerido en la request&lt;br /&gt;
        self.login()&lt;br /&gt;
        response = self.client.put('/voting/{}/'.format(v.pk), data, format= 'json')&lt;br /&gt;
        self.assertEquals(response.status_code, 400)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación a através de su API y la recupere del modelo.&lt;br /&gt;
&lt;br /&gt;
[[link2]]&lt;br /&gt;
&lt;br /&gt;
= Pruebas de navegación =&lt;br /&gt;
&lt;br /&gt;
Selenium es un framework para testing y automatización de acciones web en general que nos permite simular como actuaría un usuario frente a nuestra aplicación[[https://www.seleniumhq.org/]]&lt;br /&gt;
&lt;br /&gt;
En nuestro caso usaremos selenium dada la dificultad de probar las vistas en django. Estas vistas, normalmente, tienen que lidiar con dependencias AJAX, Javascript, etc. para poder ejecutarse normalmente. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo podemos probar si el acceso a la web de login es correcto o no. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Instalamos selenium &lt;br /&gt;
&amp;lt;source&amp;gt; $ pip install selenium &amp;lt;/source&amp;gt;&lt;br /&gt;
Instalamos, si no lo hemos hecho ya, chromiun y el driver para chromium que se encargará de reproducir el código dentro del navegador&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finalmente, escribimos el código de nuestro test. &lt;br /&gt;
Los test de Selenium requerirán que django levante el servidor durante las pruebas. Estos casos de prueba deberan extender de StaticLiveServerTestCase para que funcione correctamente. Sí, además, queremos hacer uso de la funcionalidad que nos daba BaseTestCase, crearemos un atrbuto para ello:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = True&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se ha marcado la opcion ''headless'' para que Chrome no se abra visualmente y así pueda ser ejecutado en servidores sin interfaz gráfica. Si eliminamos esa línea, veremos como Chrome se abre y se navega por el sistema decide.&lt;br /&gt;
&lt;br /&gt;
Un método para comprobar que un login es correcto, sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://hdvirtual.us.es/discovirt/index.php/s/3tg2CwNyT3X22nq test_selenium.py]&lt;br /&gt;
* '''Importante''' estos tests los podemos ejecutar desde dentro del propio sistema django o bien implementarlos para ejecutarlos de manera autonoma&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para comprobar el correcto funcionamiento al introducir un login incorrecto&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 4'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para crear una pregunta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 5'''&lt;br /&gt;
&lt;br /&gt;
Para crear scripts con navegaciones más largas y complejas, podemos descargar e instalar la extensión de selenium para nuestro navegador y registrar así los diferentes pasos de nuestra prueba y, posteriormente, integrarlo dentro de nuestra prueba en Python:&lt;br /&gt;
&lt;br /&gt;
* [[Archivo:selenium-ide.png||500px]]&lt;br /&gt;
* Grabar una prueba para realizar un login correcto. &lt;br /&gt;
[[Archivo:selenium-record.png||500px]]&lt;br /&gt;
* Replicar la prueba&lt;br /&gt;
&lt;br /&gt;
* Integrarlo dentro de nuestra clase en Python&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9378</id>
		<title>Pruebas de las Vistas 21-23</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-egc/index.php?title=Pruebas_de_las_Vistas_21-23&amp;diff=9378"/>
				<updated>2022-10-03T10:22:33Z</updated>
		
		<summary type="html">&lt;p&gt;Ajramirez: Página creada con «Página_Principal -&amp;gt; 2022/2023 -&amp;gt; Prácticas - 22/23  = Prerrequisitos =  * Ver video de presentación aquí: [https://videos.us.es/media/P2-+Pruebas/1_kj0hbxrx...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Página_Principal]] -&amp;gt; [[2022/2023]] -&amp;gt; [[Prácticas - 22/23]]&lt;br /&gt;
&lt;br /&gt;
= Prerrequisitos =&lt;br /&gt;
&lt;br /&gt;
* Ver video de presentación aquí: [https://videos.us.es/media/P2-+Pruebas/1_kj0hbxrx aquí]&lt;br /&gt;
* Instrucciones para la descarga Chrome y el webdriver de Chrome:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt-get install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Código del script de Python para probar el funcionamiento de Selenium:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
&lt;br /&gt;
options = webdriver.ChromeOptions()&lt;br /&gt;
options.headless = True&lt;br /&gt;
driver = webdriver.Chrome(options=options)&lt;br /&gt;
driver.get(&amp;quot;https://www.google.com/&amp;quot;)&lt;br /&gt;
print('Title: %s' % driver.title)&lt;br /&gt;
driver.quit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ajustes en la base de datos -&amp;gt; [[Tips and tricks]]&lt;br /&gt;
&lt;br /&gt;
= Automatizando Pruebas =&lt;br /&gt;
La estructura de Django se divide en vistas, modelos, plantillas principalmente. En esta práctica veremos como testear cada una de las partes de django así como ejecutar las pruebas de carga del mismo. Para lanzar las pruebas Django utiliza el framework de pruebas unittest el cual esta inspirado en Junit. Estas pruebas se ejecutarán con el comando:&lt;br /&gt;
&lt;br /&gt;
[[Archivo:django-arch.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre todos los tests disponibles&lt;br /&gt;
$./manage.py test&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
#Corre los tests dentro de “voting”&lt;br /&gt;
$./manage.py test voting&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Pruebas unitarias 21-23 | Pruebas unitarias]]&lt;br /&gt;
* [[Pruebas del Modelo 21-23 | Pruebas del Modelo]]&lt;br /&gt;
* [[Pruebas de las Vistas 21-23 | Pruebas de las Vistas]]&lt;br /&gt;
* [[Pruebas de carga 21-23 | Pruebas de carga]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Archivo:02-Decide-Test_2021.pdf]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----------------------- VISTAS ----------------&lt;br /&gt;
&lt;br /&gt;
Los módulos ofrecen funcionalidad en la vistas (views.py) que necesitan ser probadas. Algunas de esas vistas pueden ser probadas a través de llamada a las API REST que ofrecen. Otrás, sin embargo, ofrecen una vista HTML que tendremos que probar con otros frameworks como Selenium.&lt;br /&gt;
&lt;br /&gt;
= Pruebas de APIs =&lt;br /&gt;
Decide tiene implementada una clase para usar como base a la hora de implementar los test de interacción con APIs, BaseTestCase. Esa clase nos ofrece un ''client'' para hacer llamadas REST además de métodos de ''login'' y ''logout'' para simular el ingreso de un usuario en el sistema.&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo podemos ver como se realizar una prueba donde se intenta realizar una acción nula sobre una votación ya creada. El resultado esperado es un 400.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def test_update_voting_400(self):&lt;br /&gt;
        v = self.create_voting()&lt;br /&gt;
        data = {} #El campo action es requerido en la request&lt;br /&gt;
        self.login()&lt;br /&gt;
        response = self.client.put('/voting/{}/'.format(v.pk), data, format= 'json')&lt;br /&gt;
        self.assertEquals(response.status_code, 400)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 1'''&lt;br /&gt;
&lt;br /&gt;
Implemente una prueba que cree una votación a através de su API y la recupere del modelo.&lt;br /&gt;
&lt;br /&gt;
[[link2]]&lt;br /&gt;
&lt;br /&gt;
= Pruebas de navegación =&lt;br /&gt;
&lt;br /&gt;
Selenium es un framework para testing y automatización de acciones web en general que nos permite simular como actuaría un usuario frente a nuestra aplicación[[https://www.seleniumhq.org/]]&lt;br /&gt;
&lt;br /&gt;
En nuestro caso usaremos selenium dada la dificultad de probar las vistas en django. Estas vistas, normalmente, tienen que lidiar con dependencias AJAX, Javascript, etc. para poder ejecutarse normalmente. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo podemos probar si el acceso a la web de login es correcto o no. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 2'''&lt;br /&gt;
&lt;br /&gt;
Instalamos selenium &lt;br /&gt;
&amp;lt;source&amp;gt; $ pip install selenium &amp;lt;/source&amp;gt;&lt;br /&gt;
Instalamos, si no lo hemos hecho ya, chromiun y el driver para chromium que se encargará de reproducir el código dentro del navegador&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
sudo apt install chromium-browser chromium-chromedriver&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finalmente, escribimos el código de nuestro test. &lt;br /&gt;
Los test de Selenium requerirán que django levante el servidor durante las pruebas. Estos casos de prueba deberan extender de StaticLiveServerTestCase para que funcione correctamente. Sí, además, queremos hacer uso de la funcionalidad que nos daba BaseTestCase, crearemos un atrbuto para ello:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from django.test import TestCase&lt;br /&gt;
from django.contrib.staticfiles.testing import StaticLiveServerTestCase&lt;br /&gt;
&lt;br /&gt;
from selenium import webdriver&lt;br /&gt;
from selenium.webdriver.support.ui import WebDriverWait&lt;br /&gt;
from selenium.webdriver.common.by import By&lt;br /&gt;
from selenium.webdriver.support import expected_conditions as EC&lt;br /&gt;
from selenium.webdriver.common.keys import Keys&lt;br /&gt;
&lt;br /&gt;
from base.tests import BaseTestCase&lt;br /&gt;
&lt;br /&gt;
class AdminTestCase(StaticLiveServerTestCase):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def setUp(self):&lt;br /&gt;
        #Load base test functionality for decide&lt;br /&gt;
        self.base = BaseTestCase()&lt;br /&gt;
        self.base.setUp()&lt;br /&gt;
&lt;br /&gt;
        options = webdriver.ChromeOptions()&lt;br /&gt;
        options.headless = True&lt;br /&gt;
        self.driver = webdriver.Chrome(options=options)&lt;br /&gt;
&lt;br /&gt;
        super().setUp()            &lt;br /&gt;
            &lt;br /&gt;
    def tearDown(self):           &lt;br /&gt;
        super().tearDown()&lt;br /&gt;
        self.driver.quit()&lt;br /&gt;
&lt;br /&gt;
        self.base.tearDown()&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se ha marcado la opcion ''headless'' para que Chrome no se abra visualmente y así pueda ser ejecutado en servidores sin interfaz gráfica. Si eliminamos esa línea, veremos como Chrome se abre y se navega por el sistema decide.&lt;br /&gt;
&lt;br /&gt;
Un método para comprobar que un login es correcto, sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
	def test_simpleCorrectLogin(self):                    &lt;br /&gt;
        self.driver.get(f'{self.live_server_url}/admin/')&lt;br /&gt;
        self.driver.find_element(By.ID,'id_username').send_keys(&amp;quot;admin&amp;quot;)&lt;br /&gt;
        self.driver.find_element(By.ID,'id_password').send_keys(&amp;quot;qwerty&amp;quot;,Keys.ENTER)&lt;br /&gt;
        &lt;br /&gt;
        print(self.driver.current_url)&lt;br /&gt;
        #In case of a correct loging, a element with id 'user-tools' is shown in the upper right part&lt;br /&gt;
        self.assertTrue(len(self.driver.find_elements(By.ID,'user-tools'))==1) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://hdvirtual.us.es/discovirt/index.php/s/3tg2CwNyT3X22nq test_selenium.py]&lt;br /&gt;
* '''Importante''' estos tests los podemos ejecutar desde dentro del propio sistema django o bien implementarlos para ejecutarlos de manera autonoma&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 3'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para comprobar el correcto funcionamiento al introducir un login incorrecto&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 4'''&lt;br /&gt;
&lt;br /&gt;
Implementar un test para crear una pregunta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Ejercicio 5'''&lt;br /&gt;
&lt;br /&gt;
Para crear scripts con navegaciones más largas y complejas, podemos descargar e instalar la extensión de selenium para nuestro navegador y registrar así los diferentes pasos de nuestra prueba y, posteriormente, integrarlo dentro de nuestra prueba en Python:&lt;br /&gt;
&lt;br /&gt;
* [[Archivo:selenium-ide.png||500px]]&lt;br /&gt;
* Grabar una prueba para realizar un login correcto. &lt;br /&gt;
[[Archivo:selenium-record.png||500px]]&lt;br /&gt;
* Replicar la prueba&lt;br /&gt;
&lt;br /&gt;
* Integrarlo dentro de nuestra clase en Python&lt;/div&gt;</summary>
		<author><name>Ajramirez</name></author>	</entry>

	</feed>