Curso sobre IA Generativa para el Desarrollo de Software

Descripción

Este curso se centra en cómo la IA generativa puede mejorar la colaboración en el desarrollo de software, facilitando tareas como la prueba y depuración de código, la documentación y la gestión de dependencias. A través de ejemplos prácticos, se exploran las ventajas de utilizar modelos de lenguaje (LLMs) como compañeros de programación.

Contenidos del Curso

Temas Principales

  1. Pruebas y Depuración
  2. Ayuda en la escritura de casos de prueba.
  3. Facilita la entrega de casos de prueba al equipo de testing.

  4. Documentación

  5. Generación de comentarios adecuados en el código.
  6. Uso de herramientas de auto-documentación para crear documentación a partir de los comentarios.

  7. Gestión de Dependencias

  8. Integración de dependencias de terceros y de dentro de la empresa.
  9. Mejora en la comprensión de cómo manejar las dependencias en proyectos colaborativos.

Ejemplo Práctico

Reflexiones

Conclusiones

La IA generativa no solo ayuda a los desarrolladores a mejorar su propio código, sino que también facilita la colaboración y el trabajo en equipo. Al utilizar LLMs, los desarrolladores pueden convertirse en mejores programadores y compañeros de trabajo.

Tabla Resumen de Beneficios

Beneficio Descripción
Mejora en Pruebas Facilita la creación y entrega de casos de prueba.
Documentación Eficiente Genera documentación automáticamente a partir de comentarios en el código.
Gestión de Dependencias Ayuda a integrar y gestionar dependencias de manera efectiva.

Lista de Recursos

Con este curso, los participantes aprenderán a utilizar la IA generativa para optimizar su flujo de trabajo y mejorar la calidad del software que desarrollan.


La Importancia de las Pruebas de Software

Las pruebas de software son un paso fundamental en el proceso de desarrollo que garantiza el lanzamiento de productos de alta calidad y que funcionan correctamente, lo que resulta en grandes experiencias para los usuarios. Este documento resume los conceptos clave sobre la importancia de las pruebas de software y su implementación.

Descripción

El desarrollo de software sin pruebas adecuadas puede llevar a fallos impredecibles, frustración en los usuarios y pérdidas financieras. A lo largo de este curso, se explorarán diferentes tipos de pruebas y cómo implementarlas, incluyendo el uso de modelos de lenguaje (LLM) como aliados en el proceso.

Importancia de las Pruebas de Software

Ejemplo Notable de Fallo de Software

Un caso famoso de fallo de software es el del Mars Climate Orbiter, que en 1998, tras viajar más de 100 millones de kilómetros, falló en alcanzar su altitud orbital debido a un error de conversión de unidades entre equipos que usaban diferentes sistemas de medida (métrico e imperial). Este error resultó en la pérdida de una misión de $200,000,000 y años de descubrimientos científicos.

Contenido del Curso

A lo largo de los siguientes videos, se explorarán los siguientes temas:

  1. Tipos de Pruebas Manuales:
  2. Pruebas Exploratorias
  3. Pruebas Funcionales

  4. Implementación de Pruebas con LLM:

  5. Uso de modelos de lenguaje para facilitar la creación de scripts de prueba.

  6. Pruebas Automatizadas:

  7. Introducción a frameworks de pruebas automatizadas.
  8. Estrategias para reducir la carga cognitiva al trabajar con herramientas automatizadas.

  9. Pruebas de Rendimiento:

  10. Evaluación del rendimiento de la aplicación bajo diferentes condiciones y cargas.

  11. Identificación de Vulnerabilidades de Seguridad:

  12. Técnicas para usar LLM en la identificación y corrección de vulnerabilidades de seguridad.

Conclusión

Las pruebas de software son esenciales para el éxito de cualquier proyecto de desarrollo. Familiarizarse con las diferentes técnicas y herramientas disponibles, incluyendo la colaboración con modelos de lenguaje, puede mejorar significativamente la calidad del software y la experiencia del usuario.

¡Vamos al siguiente video y comencemos a explorar las estrategias de prueba!


Estrategias de Pruebas con LLM y Flask

Descripción

En este documento se presenta un resumen de un curso sobre cómo utilizar un modelo de lenguaje grande (LLM) para desarrollar estrategias de pruebas en una aplicación web simple construida con Flask. Se exploran conceptos clave, ejemplos de código y estrategias de prueba.

Introducción a Flask

Flask es un marco de trabajo ligero para Python, ideal para crear aplicaciones web. En este curso, se utiliza una aplicación Flask que tiene un único endpoint API: /api/greet/<name>, que recibe un nombre como parámetro y devuelve un mensaje de saludo.

Ejemplo de Código

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/greet/<name>', methods=['GET'])
def greet(name):
    return jsonify(message=f"Hello, {name}!")

if __name__ == '__main__':
    app.run()

Ejecución en Entornos Compartidos

Si se ejecuta en un entorno compartido como Google Colab, es necesario modificar el código para usar hilos, ya que los notebooks finalizan la ejecución de la celda actual antes de pasar a la siguiente. Esto permite que el servidor API se ejecute en un hilo separado.

Llamadas a la API

Para llamar a la API, se puede utilizar cURL o la biblioteca requests de Python. Asegúrate de usar la dirección IP reportada por Colab si estás ejecutando el código allí.

Estrategias de Pruebas

Una vez que la API está en funcionamiento, se sugiere pausar y pensar en los casos de prueba que se podrían utilizar para verificar su correcto funcionamiento. Algunas preguntas a considerar son: - ¿Qué datos se pueden pasar para comprobar el comportamiento? - ¿Cómo se podría romper la API?

Uso de LLM para Generar Casos de Prueba

Se recomienda utilizar un LLM como GPT para generar casos de prueba. Al hacerlo, es importante seguir algunas mejores prácticas de prompting: 1. Ser específico: Proporcionar detalles y contexto sobre el problema. 2. Asignar un rol: Pedir al modelo que actúe como un experto en pruebas de software. 3. Interacción: Mantener un diálogo con el modelo para afinar la salida.

Ejemplo de Prompt

Como un experto en pruebas de software que está enseñando a una nueva persona a escribir casos de prueba, ¿puedes analizar este código y proporcionar un conjunto de casos de prueba explicando cada uno?

Casos de Prueba Sugeridos

Al utilizar el prompt anterior, se pueden obtener varios casos de prueba, tales como:

Caso de Prueba Descripción Salida Esperada
Saludo básico Probar el saludo básico con un nombre. JSON:
Manejo de codificación URL Probar con un nombre que contenga espacios (ej. "John Doe"). JSON:
Caracteres especiales Probar con nombres que contengan caracteres especiales. JSON:
Nombres vacíos Probar con un nombre vacío. JSON:
Entrada numérica Probar con un número como entrada. JSON:

Conclusión

El uso de LLMs puede ser una herramienta poderosa para generar casos de prueba y mejorar la calidad del software. En el siguiente video, se explorará más a fondo el concepto de pruebas exploratorias y cómo un LLM puede asistir en este proceso.


Resumen del Curso: Pruebas Exploratorias en Aplicaciones Python

Descripción

En este curso, se exploran las pruebas manuales, centrándose en las pruebas exploratorias como una estrategia clave para identificar errores en aplicaciones simples, como un endpoint de Flask. Se discute cómo trabajar con un modelo de lenguaje (LLM) puede facilitar el proceso de prueba y se presentan ejemplos prácticos utilizando una aplicación de lista de tareas en Python.

Contenido

1. Introducción a las Pruebas Manuales

2. Pruebas Exploratorias

3. Ejemplo Práctico: Aplicación de Lista de Tareas

Ejemplo de Uso

# Agregar tareas
add_task("Comprar groceries")
add_task("Leer un libro")

# Listar tareas
list_tasks()

# Eliminar una tarea
remove_task("Leer un libro")
list_tasks()

4. Casos de Prueba y Casos Límite

5. Uso de un LLM para Pruebas

6. Sugerencias de Mejora

7. Conclusiones

Tabla de Problemas Identificados y Sugerencias

Problema Identificado Sugerencia de Mejora
Uso de variables globales Evitar el uso de variables globales.
Tipos de retorno inconsistentes Unificar los tipos de retorno.
Duplicación de tareas Implementar verificación de duplicados.
Manejo de tareas vacías Prohibir la adición de tareas vacías.
Seguridad en hilos Implementar bloqueo de hilos.

Próximos Pasos

En el siguiente video, se explorará cómo un LLM puede ayudar a formalizar los resultados de las pruebas exploratorias en un conjunto de pruebas funcionales.


Resumen del Curso sobre Pruebas Funcionales

Descripción

Este documento resume los conceptos clave sobre las pruebas funcionales, su importancia en el desarrollo de software y cómo se pueden implementar utilizando herramientas como LLM (Modelos de Lenguaje de Aprendizaje Automático). Se discuten ejemplos prácticos y se enfatiza la necesidad de mantener y actualizar los casos de prueba a medida que evoluciona la aplicación.

Contenidos

1. Introducción a las Pruebas Funcionales

Las pruebas funcionales son una extensión de las pruebas exploratorias manuales. Su objetivo es verificar que la funcionalidad de la aplicación cumpla con los requisitos predefinidos. Esto se logra mediante la creación de casos de prueba que aseguran que cada función del código funcione como se espera.

2. Importancia de las Pruebas Funcionales

3. Implementación de Pruebas Funcionales

Ejemplo de Código de Prueba

import unittest

class TestTodoList(unittest.TestCase):
    def setUp(self):
        self.todo_list = TodoList()

    def test_add_task(self):
        self.todo_list.add_task("Task 1")
        self.assertIn("Task 1", self.todo_list.tasks)

    def test_remove_task(self):
        self.todo_list.add_task("Task 1")
        self.todo_list.remove_task("Task 1")
        self.assertNotIn("Task 1", self.todo_list.tasks)

    def test_remove_nonexistent_task(self):
        result = self.todo_list.remove_task("Nonexistent Task")
        self.assertEqual(result, "Task not found")

    def test_list_tasks(self):
        self.todo_list.add_task("Task 1")
        self.assertEqual(self.todo_list.list_tasks(), ["Task 1"])

    def test_add_empty_task(self):
        result = self.todo_list.add_task("")
        self.assertEqual(result, "Task cannot be empty")

4. Consideraciones Importantes

5. Conclusiones

Las pruebas funcionales son esenciales para garantizar que las aplicaciones se comporten como se espera. Aunque los LLM son herramientas útiles para generar pruebas, es importante no depender completamente de ellos. La intervención humana sigue siendo crucial para asegurar la calidad del software.

6. Próximos Pasos

En el siguiente video, se explorará cómo los LLM pueden facilitar las pruebas automatizadas, lo que es fundamental para el mantenimiento de aplicaciones en producción.

Tabla de Resumen de Funciones de Prueba

Función de Prueba Descripción
test_add_task Verifica que una tarea se añade correctamente.
test_remove_task Verifica que una tarea se elimina correctamente.
test_remove_nonexistent_task Verifica el manejo de la eliminación de tareas no existentes.
test_list_tasks Verifica que la lista de tareas se devuelve correctamente.
test_add_empty_task Verifica que no se permite añadir una tarea vacía.

Lista de Recomendaciones

Este resumen proporciona una visión general de la importancia y la implementación de las pruebas funcionales en el desarrollo de software, así como el papel de los LLM en este proceso.


Resumen del Curso: Pruebas Automatizadas con Pytest

Descripción

Este documento resume los conceptos clave sobre las pruebas automatizadas en Python utilizando el marco de trabajo pytest. Se discuten las ventajas de las pruebas automatizadas, cómo implementarlas y se presentan ejemplos prácticos relacionados con una aplicación de lista de tareas.

Contenido

1. Introducción a las Pruebas Automatizadas

2. Uso de Pytest

3. Ejemplo Práctico: Lista de Tareas

Código de Pruebas con Pytest

def test_add_task():
    tasks = []
    tasks.append("Task 1")
    assert tasks == ["Task 1"]
    tasks.append("Task 2")
    assert tasks == ["Task 1", "Task 2"]
    tasks.append("Task 3")
    assert tasks == ["Task 1", "Task 2", "Task 3"]

def test_add_empty_task():
    with pytest.raises(ValueError):
        tasks.append("")  # Se espera un error al agregar una tarea vacía

4. Ejecución de Pruebas

5. Generación de Pruebas con LLM

6. Consideraciones Finales

7. Próximos Pasos: Pruebas de Rendimiento

Tabla Resumen de Ventajas de Pruebas Automatizadas

Ventaja Descripción
Ahorro de tiempo Realiza tareas repetitivas automáticamente.
Reducción de errores humanos Minimiza la intervención manual.
Retroalimentación rápida Permite detectar problemas en etapas tempranas.
Mantenimiento de calidad Asegura la confiabilidad del software a largo plazo.

Lista de Tareas para el Estudiante

Este resumen proporciona una visión general de las pruebas automatizadas utilizando pytest, destacando su importancia y cómo implementarlas en un proyecto práctico.


Pruebas de Rendimiento en Aplicaciones

Descripción

Las pruebas de rendimiento son fundamentales para garantizar que las aplicaciones funcionen de manera eficiente en producción y puedan manejar la carga de usuarios esperada. Este documento resume los conceptos clave sobre la medición del tiempo de ejecución y la identificación de cuellos de botella en el rendimiento, utilizando bibliotecas específicas de Python.

Contenidos

1. Importancia de las Pruebas de Rendimiento

2. Aspectos Clave de las Pruebas de Rendimiento

3. Herramientas y Bibliotecas en Python

4. Ejemplo Práctico

Se presenta un código que encuentra números primos en un rango y calcula su suma. A continuación, se mide el tiempo de ejecución y se identifican cuellos de botella.

Código de Ejemplo

def is_prime(n):
    # Lógica para determinar si n es primo
    pass

def sum_of_primes_naive(limit):
    # Lógica para sumar números primos hasta el límite
    pass

Medición del Tiempo de Ejecución

5. Optimización del Código

Ejemplo de Optimización

def is_prime_optimized(n):
    # Lógica optimizada para determinar si n es primo
    pass

6. Lecciones Aprendidas

7. Conclusión

Las pruebas de rendimiento son un aspecto especializado del desarrollo de software. Al aplicar las mejores prácticas de consulta y proporcionar contexto, se puede mejorar significativamente la eficiencia del código. En el siguiente video, se explorará la importancia de las pruebas de seguridad.

Tabla Resumen de Herramientas

Herramienta Descripción
timeit Mide el tiempo de ejecución de fragmentos de código.
cProfile Analiza el tiempo en cada función para identificar cuellos de botella.

Lista de Pasos para Realizar Pruebas de Rendimiento

  1. Escribir el código que se desea probar.
  2. Utilizar timeit para medir el tiempo de ejecución.
  3. Implementar cProfile para identificar cuellos de botella.
  4. Consultar a un LLM para optimizar el código.
  5. Probar el código optimizado y comparar resultados.

Este documento proporciona una guía básica sobre cómo realizar pruebas de rendimiento en aplicaciones utilizando Python, destacando la importancia de la medición y la optimización del código.


Resumen del Módulo: Pruebas de Seguridad en Aplicaciones

Descripción

En este módulo se explora el concepto de pruebas de seguridad en aplicaciones, destacando la importancia de entender las vulnerabilidades de seguridad y cómo los modelos de lenguaje (LLM) pueden ser útiles, pero también limitados en este contexto.

Contenido

1. Introducción a las Pruebas de Seguridad

Las pruebas de seguridad son cruciales para proteger aplicaciones, especialmente aquellas que exponen activos a través de APIs en Internet. La seguridad es un campo en constante evolución, donde los atacantes y hackers están siempre buscando nuevas formas de explotar vulnerabilidades.

2. Limitaciones de los Modelos de Lenguaje

3. Uso de LLM en Seguridad

Los LLM pueden ser útiles para: - Iniciar conversaciones sobre seguridad en equipos de trabajo. - Proporcionar información general sobre prácticas de seguridad.

4. Ejemplo de Aplicación y Vulnerabilidades

Se presenta un ejemplo de una aplicación simple que utiliza un API REST para la gestión de usuarios. La estructura de un usuario en la base de datos incluye: - id - username - password

Código de Ejemplo

Un ejemplo de cómo se podría implementar un endpoint para obtener detalles de un usuario:

@app.route('/user/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = query_database(user_id)  # Consulta a la base de datos
    return jsonify(user)  # Retorna los detalles en formato JSON

5. Vulnerabilidad: Inyección SQL

Una de las vulnerabilidades más comunes es la inyección SQL. Esto ocurre cuando un atacante puede manipular una consulta SQL a través de parámetros de entrada. Por ejemplo, si un endpoint acepta un ID de usuario, un atacante podría inyectar código SQL malicioso.

Ejemplo de Inyección SQL

Si el código permite un input como user_id=1, un atacante podría enviar algo como:

1; DROP TABLE users; --

Esto podría resultar en la eliminación de la tabla de usuarios.

6. Ejercicio Opcional

Se sugiere a los participantes que utilicen el cuaderno proporcionado en los materiales del curso para experimentar con la aplicación y tratar de identificar vulnerabilidades de inyección SQL.

Conclusión

Las pruebas de seguridad son fundamentales en el desarrollo de aplicaciones. Aunque los LLM pueden ser herramientas útiles, es crucial tener un entendimiento profundo de la seguridad y contar con la ayuda de expertos en el área.


Análisis de una Aplicación Flask para Problemas de Seguridad

Descripción

Este documento resume un video que presenta una aplicación Flask y su análisis en busca de problemas de seguridad. Se explican los conceptos básicos de la aplicación, la configuración de la base de datos y las operaciones CRUD (Crear, Leer, Actualizar, Eliminar) que se pueden realizar sobre los usuarios.

Instalación de Dependencias

Para comenzar, es necesario instalar SQLAlchemy, que se utilizará para manejar la base de datos.

pip install SQLAlchemy

Estructura de la Aplicación

Configuración de la Base de Datos

La aplicación Flask se configura para utilizar una base de datos SQLite. La URI de la base de datos se establece de la siguiente manera:

DATABASE_URI = 'sqlite:///users.db'

Modelo de Usuario

Se define una clase User que representa a los usuarios en la base de datos. Esta clase incluye los siguientes atributos:

Rutas y Métodos HTTP

La aplicación define varias rutas para interactuar con los usuarios. A continuación se detallan las operaciones disponibles:

Método HTTP Ruta Descripción
GET /users Devuelve todos los usuarios en formato JSON.
GET /user/ Devuelve el usuario con el ID especificado.
POST /user Agrega un nuevo usuario con username y password.
PUT /user/ Actualiza el username y password del usuario.
DELETE /user/ Elimina el usuario con el ID especificado.

Ejemplo de Uso

  1. Listar Usuarios: Al realizar una solicitud GET a /users, se obtendrá una lista de todos los usuarios. Inicialmente, estará vacía.

  2. Buscar Usuario: Al realizar una solicitud GET a /user/1, se buscará el usuario con ID 1. Si no existe, se devolverá un mensaje de error 404.

  3. Agregar Usuario: Para agregar un nuevo usuario, se realiza una solicitud POST a /user con el siguiente JSON: json { "username": "test_user", "password": "secure_password" } Si se agrega correctamente, se recibirá un mensaje de éxito.

  4. Actualizar Usuario: Para actualizar la contraseña de un usuario, se realiza una solicitud PUT a /user/1 con el nuevo username y password.

  5. Eliminar Usuario: Para eliminar un usuario, se realiza una solicitud DELETE a /user/1. Se recibirá un mensaje de éxito si la operación se completa.

Conclusión

Este video proporciona una introducción a la creación de una aplicación Flask básica con operaciones CRUD. Se recomienda revisar el código de la aplicación en el laboratorio no calificado y continuar con el siguiente video para estrategias específicas de análisis de código.

Recursos Adicionales


Resumen del Módulo sobre Pruebas de Seguridad en Aplicaciones

Descripción

En este módulo, se exploran las mejores prácticas para identificar y mitigar vulnerabilidades de seguridad en el código utilizando modelos de lenguaje (LLM). Se enfatiza la importancia de realizar pruebas de seguridad de manera continua y colaborativa, involucrando a expertos en seguridad y utilizando herramientas adecuadas.

Contenido

Principios Generales

Pasos Recomendados

  1. Identificación de Vulnerabilidades:
  2. Utilizar el LLM para identificar posibles vulnerabilidades en el código.
  3. Generar casos de prueba para las vulnerabilidades detectadas.

  4. Ejemplo de Vulnerabilidades:

  5. Inyección SQL: Permite a un atacante ejecutar consultas maliciosas.
  6. Cross-Site Scripting (XSS): Permite a un atacante ejecutar código en el navegador de otro usuario.
  7. Almacenamiento inseguro de contraseñas: Almacenar contraseñas en texto plano.
  8. Acceso directo a registros de usuarios: Exposición de datos sensibles.

  9. Configuración del Entorno:

  10. Se recomienda configurar un entorno local de Python para realizar pruebas, ya que ejecutar pruebas en un notebook puede ser problemático.

Proceso de Pruebas

Ciclo de Mejora Continua

Importancia de la Documentación

Conclusiones

Recursos Adicionales


Este resumen proporciona una guía clara sobre cómo abordar las pruebas de seguridad en el desarrollo de software, destacando la importancia de la colaboración y el uso de herramientas avanzadas.