Saltar a contenido

Usando TDD con la Ayuda de Flow

React / Next

Ejemplo de prompt:

Dada la funcionalidad de agregar un gerente a un usuario a través de un combobox de autocompletado seguido de un listado MUI donde se ubican los seleccionados, dame la prueba de integración de esta funcionalidad para React usando Vitest (testing library) siguiendo los principios de TDD.

El resultado es el siguiente:

// UserManager.test.jsx
import { render, fireEvent, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import UserManager from './UserManager'; // Importando el componente

describe('UserManager', () => {
  it('debe permitir que el usuario agregue un gerente y lo muestre en la lista', async () => {
    render(<UserManager />);

    // Paso 1: Interactuar con el combobox
    const input = screen.getByRole('combobox');
    fireEvent.change(input, { target: { value: 'Gerente A' } });

    // Paso 2: Verificar si aparecen las sugerencias
    const suggestion = await screen.findByText('Gerente A');
    expect(suggestion).toBeInTheDocument();

    // Paso 3: Seleccionar el gerente
    fireEvent.click(suggestion);

    // Paso 4: Verificar si el gerente seleccionado aparece en la lista
    const selectedManager = screen.getByText('Gerente A');
    expect(selectedManager).toBeInTheDocument();
  });
});

Este prompt es eficiente por varias razones:

  1. Claridad en el Objetivo Especificaste claramente que deseas una prueba de integración para una funcionalidad específica en una aplicación de React. Esto ayuda a centrarse en la tarea sin ambigüedad.

  2. Contexto Específico Al mencionar el uso de un "combobox de autocompletado" y un "listado MUI", se proporciona un contexto técnico que es crucial para entender las bibliotecas y componentes involucrados. Esto permite que la respuesta sea más relevante y dirigida.

  3. Enfoque en TDD Al solicitar una prueba que siga los principios de TDD (Test-Driven Development), indicas que estás interesado en un enfoque de desarrollo que prioriza la calidad del código y la validación continua. Esto dirige la respuesta para incluir buenas prácticas y estructuras de prueba que se alinean con esta metodología.

  4. Estructura de la Petición La estructura de tu petición es lógica y organizada. Pediste una prueba específica para una funcionalidad, lo cual es una práctica eficiente en TDD. Esto ayuda a evitar respuestas excesivamente generales y permite que la respuesta proporcione un ejemplo práctico y aplicable.

  5. Expectativas Claras Al especificar que deseas una prueba de integración, dejas claro que esperas un ejemplo que no solo verifique la funcionalidad de forma aislada, sino que también pruebe la interacción entre componentes, lo cual es fundamental en aplicaciones complejas.

  6. Uso de Terminología Técnica El uso de términos como "combobox", "autocomplete" y "MUI" demuestra un entendimiento del dominio, lo que permite que la respuesta sea más técnica y precisa, abordando aspectos que son relevantes para los desarrolladores familiarizados con estas tecnologías.

Problemas:

  1. En el caso del frontend, como no tenemos una base de datos, no tenemos la posibilidad de tener algo en memoria. Necesitamos hacer un mock o tener un stub para los entornos de prueba; sin embargo, la IA no nos entregó ninguno de los dos. Esto se debe a que pedimos una prueba de integración usando la filosofía de TDD; en este caso, deberíamos haber especificado que queríamos la creación de este mock. Esto contradice el ejemplo de backend utilizado a continuación, que en realidad necesita mencionar que no quiere los mocks. Tal vez este comportamiento conflictivo se deba a las fuentes de datos con las que se entrena la IA, donde la mayoría de los proyectos de backend siguen esta práctica incorrecta de mockear todo, y en el front, los desarrolladores tienen una idea más alineada con el TDD en líneas generales.

Java / Spring

Dada la funcionalidad de agregar un gerente a un usuario a través de un combobox de autocompletado seguido de un listado donde se ubican los seleccionados, dame la prueba de integración para el backend de esta funcionalidad usando Spring Test con MockMvc siguiendo los principios de TDD.

Resultado de este prompt

// UserControllerTest.java
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;

@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private UserService userService; // Suponiendo que tienes un servicio para la manipulación de usuarios

    @InjectMocks
    private UserController userController;

    private ObjectMapper objectMapper;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.openMocks(this);
        objectMapper = new ObjectMapper();
    }

    @Test
    public void debeAdicionarGerenteAoUsuario() throws Exception {
        // Datos de entrada
        Long userId = 1L;
        String managerName = "Gerente A";

        // Simulando el comportamiento del servicio
        when(userService.addManagerToUser(userId, managerName)).thenReturn(true);

        // Ejecutando la petición
        mockMvc.perform(post("/api/users/{userId}/managers", userId)
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(managerName)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.message").value("Gerente adicionado com sucesso"));
    }
}

Problemas

  1. Utilizó un mock del servicio de usuarios, un efecto contrario a la metodología de TDD donde las pruebas deben estar desacopladas de la implementación. No se puede deducir que se usará una capa de servicios. Además, la prueba de la funcionalidad en su conjunto abarcaría el uso de una base de datos en memoria.

  2. No creó las pruebas para el endpoint de búsqueda de gestores. La falta de mencionar que también se necesita hacer la prueba de este endpoint, aunque si se debe o no hacer esta prueba debería estar... [la frase parece incompleta en el original]

Conclusión

El uso de Inteligencia Artificial (IA) en el desarrollo de software, especialmente en prácticas como el Desarrollo Guiado por Pruebas (TDD), ofrece una oportunidad valiosa para optimizar y mejorar la eficiencia de los procesos de codificación y prueba. Como se ha discutido, los prompts bien estructurados que utilizan terminología técnica específica son esenciales para obtener respuestas más precisas y relevantes de la IA. El dominio del conocimiento técnico no solo mejora la calidad de las peticiones hechas a la IA, sino que también capacita a los desarrolladores para evaluar críticamente las soluciones generadas.

Sin embargo, es crucial ser consciente de las limitaciones que la IA puede presentar, especialmente en relación con la creación de pruebas que respeten las mejores prácticas de TDD. Ejemplos como la necesidad de mocks en un entorno de frontend o el uso de mocks de servicios en pruebas de backend muestran que la IA puede, a veces, seguir patrones que no se alinean perfectamente con las expectativas y filosofías de desarrollo. Esto refuerza la necesidad de un conocimiento técnico sólido, que posibilite al desarrollador identificar y corregir eventuales fallos en las respuestas generadas por la IA.