¿Cómo aplicar TDD en Vue?

8/12

Lectura

¿Cómo aplicar TDD en Vue?

Para esto, hay que entender primero qué es TDD y entender que se puede aplicar a cualquier desarrollo de software.

Siempre he dicho que el ejemplo es la madre de todas las enseñanzas y la práctica el padre. Así que vamos a agregar la funcionalidad a nuestro proyecto de que, cada vez que le den click al botón, cambie un elemento de data y se le sume 1 a su valor.

TDD o Test-Driven Development es un paradigma de desarrollo que consiste en cinco etapas.

DIAGRAMA DE LAS FASES
DiagramaClase8.png

1) Escribir la prueba

En esta primera etapa lo que se hace es, en el archivo de pruebas se piensa en cómo se debe comportar la aplicación con la nueva feature (requisito nuevo) que se va a integrar.

Y con eso en mente se debe de crear la prueba.

Con lo que comentamos anteriormente, vamos a escribir nuestra prueba.

Empezamos pensando en la funcionalidad. Requerimos cambiar una propiedad de data cada vez que demos click al botón.

Entonces la prueba debe de primero probar que se hizo click.

Para esto, usaremos dos métodos de Vue Test Utils:

  • find()

Recibe un string o un componente y regresa el primer elemento que encuentra con ese selector.

  • trigger()

Lanza un evento del elemento que se seleccionó.

Recibe un string con el nombre del evento.

Estos métodos los vamos a usar para simular un click en nuestro botón, de la siguiente manera.

wrapper.find('button').trigger('click')

Ya que simulamos el botón, solo hay que comprobar que se le sumó 1 al anterior valor, entonces vamos a guardar el valor anterior y compararlo con el valor después del click, resultando en esto.

describe('Probar que se cambió la propiedad changeTest ', () => {

    test('should click a button', () => {

    const lastValue = wrapper.vm.changeTest

    wrapper.find('button').trigger('click')

    expect(wrapper.vm.changeTest).toBe(lastValue+1)

  })

})

Listo.

2) La prueba falla

El siguiente paso es ver que la prueba falle y ver que se necesita hacer para que pase.

Cuando corremos la prueba, esto es lo que nos sale.

18.png

Así que lo que sigue es escribir el código para que esto no pase.

3) Escribir código

El primer error que notamos es que trata de buscar un elemento de data() que no existe, entonces crearemos el elemento.

Como es un tipo number, vamos a inicializarlo con algún número.

17.png

Lo siguiente es hacer que el valor si cambie cada vez que le damos un click. Para ellos debemos agregar una línea de código a nuestra funcion setData()

16.png

4) Pasar prueba

Ahora debemos ver si en realidad pasamos la prueba, así que corremos nuestras pruebas.

En efecto, con eso es suficiente.

15.png

5) Refactor de código

El último paso sería checar si nuestra implementación de la solución puede mejorarse, en caso de que no habremos terminado de añadir esa feature a nuestro código.

Puedes hacer eso con absolutamente todas las features que desees.

Esta forma de trabajar nos obliga a cumplir con un estándar no solamente cuando estamos haciendo código, sino también cuando estamos planeando como hacerlo.


¿Qué otra feature se te ocurre que le podamos agregar al proyecto de esta manera? Pónlo en los comentarios.

Aportes 10

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

No se entiende muy bien el codigo, por lo que tuve que investigar de otros lados. Les comparto como quedo.
example.spec.js

import { shallowMount } from "@vue/test-utils";
import Example from "@/components/Example.vue";

describe("Probar que se cambió la propiedad changeTest ", () => {
  test("should click a button", () => {
    const wrapper = shallowMount(Hola);
    const lastValue = wrapper.vm.changeTest;
    wrapper.find("button").trigger("click");

    expect(wrapper.vm.changeTest).toBe(lastValue + 1);
  });
});

Example.vue

<template>
  <div>
    <button @click="updateTest">Click to change</button>
  </div>
</template>

<script>
export default {
  name: "Hola",
  data() {
    return {
      changeTest: 0,
    };
  },
  methods: {
    updateTest() {
      this.changeTest += 1;
    },
  },
};
</script>

Luego ir a terminal y poner

yarn run test:unit

Espero que les haya funcionado.

También quiero dejar mi aporte a una manera más sencilla de explicar el TDD:

Básicamente Test Driven Development significa “Desarrollo Guiado por Pruebas” (literal, eso significa en español), y consiste en que primero programas la prueba y esperas a que te de un error, con base en ese error tu lo solucionas a través de código, y así hasta que hagas que esa prueba pase, con esto encapsulamos los 4 primeros conceptos.

El último concepto, que es el de refactorizado, nos ayuda a mejorar la calidad de nuestro código, es decir, buscar áreas de mejora y aplicarlas, por ejemplo, podemos reducir la cantidad de lineas de código de una función, refactorizar toda una clase, etc. Pero siempre procurando que el output final siempre sea el esperado, y es por eso que nuestras pruebas nos dirán si el código después de ese refactorizado aún funciona correctamente.

Vamos, te quitas el miedo y el estrés de pensar: “Ay pero es que si le muevo aquí y ya no funciona después… no, no, no yo este código no lo toco ahí se queda”

Pienso que esto no es un curso, es un manual. No está a la altura de los otros cursos que he tomado. Los contenidos no son malos, pero leer todo en un fondo oscuro con letras blancas es incómodo. Además, cuando algo no funciona, cuesta ver donde está el detalle. Lo bueno es que alguien más ya tuvo el problema y aporta rápidamente para solucionarlo, pero no debería ser ese el fin del curso. Los contenidos de Vue en Platzi son algo pobres y creo que deben mejorar partiendo por este curso y hacerlo con videos como corresponde.

Las funciones que utilizamos

find(string o component) regresa el primer elemento con ese selector 
trigger(event) lanza un evento del elemento que se selecciono
//ejemplo
wrapper.find('button').trigger('click')

Falta mas claridad en el curso ya que con lo que se mensiona no es posible hacer el proceso.

para que funcione lo puse asi:

import { mount } from '@vue/test-utils'
import Example from "@/components/Example.vue"

const wrapper = mount(Example)

const vm = wrapper.vm

describe('Probar la propiedad changeTest', () => {
  test("should click a button", () => {
    const lastValue = wrapper.vm.changeTest;
    wrapper.find('button').trigger('click')

    expect(wrapper.vm.changeTest).toBe(lastValue + 1);
  });
});

Example.vue

<template>
  <div>
    <button @click="updateTest">Click to change</button>
  </div>
</template>

<script>
export default {
  name: "Hola",
  data() {
    return {
      changeTest: 0,
    };
  },
  methods: {
    updateTest() {
      this.changeTest += 1;
    },
  },
};
</script>

En la parte 3) Escribir código:
ir al archivo App.vue y agregar en el objeto data changeTest: 0 y en la parte de los methods existe una función setData que solamente hay que agregar la linea this.changeTest += 1;

<code> data () {
	return {
		changeTest: 0,
		}
	},

methods: {
	setData(data) {
		this.changeTest += 1;
	}
}

Recién ahí cuando en la terminal corres el comando npm run test:unit va a salir el resultado esperado.

para que funcione tenemos que declarar la const wrapper que hace referencia al mount del componente App

import App from  '@/App.vue'
import { mount } from  '@vue/test-utils'

const wrapper = mount(App)

describe('Probar que se cambio la propieda changeTest', () => {
    test('should click a button', () => {
        const lastValue = wrapper.vm.changeTest;
        wrapper.find('button').trigger('click')
        expect(wrapper.vm.changeTest).toBe(lastValue+1)
    })
})

La explicación del punto 3 no es muy clara: 3) Escribir código

Pero a lo que se refiere es modificar el archivo App.vue verificar si existe data() y agregar agregar

this.changeTest += 1
en setData

setData (data) {
      try {
        this.changeTest += 1

Increíble, esto es una de las cosas que me gustan del TDD, que primero haces la prueba y luego el código, y es lo que comentaba en una lectura anterior, que realmente hacer las pruebas hasta el final es tedioso, así que esto es genial. Aunque es raro, aquí se mencionan 5 etapas pero en otros cursos solo se mencionan 3, pero realmente son lo mismo, digamos que en los otros cursos obviaron la parte de “Ver la prueba fallar” y “Escribir el código”