CursosEmpresasBlogLiveConfPrecios

Contenido del curso

Introducción

  • 1
    Pruebas en Proyectos de Software con Vue y Automatización

    Pruebas en Proyectos de Software con Vue y Automatización

    01:03 min
  • 2
    Pruebas Unitarias e Integración en Desarrollo de Software

    Pruebas Unitarias e Integración en Desarrollo de Software

    03:29 min
  • 3
    Evolución de Pruebas de Software: De Turing a la Calidad Actual

    Evolución de Pruebas de Software: De Turing a la Calidad Actual

    02:16 min
  • 4
    Preparación para pruebas de proyectos Vue con NPM y Vue Test Utils

    Preparación para pruebas de proyectos Vue con NPM y Vue Test Utils

    01:11 min

Entendiendo las pruebas

  • 5
    Pruebas de Entradas y Salidas en Componentes Vue

    Pruebas de Entradas y Salidas en Componentes Vue

    01:44 min

Herramientas de desarrollo

  • 6
    Pruebas unitarias en Vue con Test Utils: Introducción práctica

    Pruebas unitarias en Vue con Test Utils: Introducción práctica

    02:51 min
  • 7
    Pruebas unitarias con Jest: detección de anomalías y defectos

    Pruebas unitarias con Jest: detección de anomalías y defectos

    03:55 min

Desarrollo de pruebas

  • 8
    Aplicar TDD en Vue: Desarrollo y Pruebas de Funcionalidades

    Aplicar TDD en Vue: Desarrollo y Pruebas de Funcionalidades

    02:15 min
  • 9
    Pruebas de Software con Mocking en Aplicaciones de JavaScript

    Pruebas de Software con Mocking en Aplicaciones de JavaScript

    03:05 min
  • 10
    Pruebas Unitarias con Jest y Vue Test Utils

    Pruebas Unitarias con Jest y Vue Test Utils

    04:42 min
  • 11
    Pruebas Unitarias y Asíncronas en Vue con $nextTick

    Pruebas Unitarias y Asíncronas en Vue con $nextTick

    Viendo ahora

Tips y buenas prácticas

  • 12
    Pruebas Unitarias y Mocking en Vue con Jest

    Pruebas Unitarias y Mocking en Vue con Jest

    02:38 min
Tomar examen

Pruebas Unitarias y Asíncronas en Vue con $nextTick

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

      Para las pruebas unitarias solamente revisaremos el cambio de los elementos por los eventos lanzados. Empezamos por crear otra carpeta llamada integration dentro de nuestra carpeta de pruebas.

      4.png

      Mientras estemos dentro de la carpeta de test/unit todos los archivos que terminen en spec.js se probarán.

      En esta carpeta crearemos un archivo llamado dataChange.spec.js.

      Importamos el módulo mount que, como recordarás, es para montar el componente con sus hijos, este módulo es muy importante para estas pruebas.

      NOTA: Si tienes muchos componentes hijos, prueba el padre sin los hijos (utiliza shallowMount) , así ya no tendrán que renderizarse en cada prueba, si requieres probar los hijos, trata de sólo montarlo una vez.

      Creamos un wrapper del padre:

      const wrapper = mount(App)

      Ahora, como vamos a probar los cambios debemos tener un estado inicial. Para eso vamos a sacar todos los valores de los elementos que buscamos, antes de hacer el click.

      Quedando de la siguiente manera:

      const nameTag = wrapper.find('.pokemon-name') const lastNameValue = nameTag.text() const imgTag = wrapper.find('img') const lastImgValue = imgTag.attributes().src const typeTag = wrapper.find('#type') const lastTypeValue = typeTag.text() const weightTag = wrapper.find('#weight') const lastWeightValue = weightTag.text() const heightTag = wrapper.find('#height') const lastHeightValue = heightTag.text() const abilitiesTag = wrapper.find('ul') const lastAbilitiesValue = abilitiesTag.text()

      Parecen muchas variables, pero en este caso es necesario. Puedes solucionar este problema recorriendo los diferentes tags que se repitan, pero aquí no va a ser necesario.

      Después de esto, sigue accionar el cambio. Todo esto va dentro de nuestro describe, no va dentro de ninguna prueba.

      El click lo vamos a hacer utilizando el método trigger(), que lo que hace es lanzar el evento que nosotros le pasemos como parámetro, quedando de la siguiente manera:

      const btn = wrapper.find('button') btn.trigger('click')

      Al hacer esto, ya es como si hubieras dado click en el botón.

      Ahora sí, empecemos con las pruebas:

      • Lo primero que vamos a poner dentro de nuestra prueba va a ser una comprobación de si se montó la aplicación y que cambiaron los valores de las variables predeterminados.

      • Lo segundo y_ más importante_, va a ser el uso del método $nextTick().

      $nextTick

      • Este método nos permite esperar al cambio de la aplicación.

      • Regresa una promesa, por lo cual debemos esperar a que se resuelva la promesa.

      • Se debe de tratar como método asíncrono.

      • No recibe parámetros, sino más bien un callback.

      El callback es una función que se ejecuta cuando ocurre un evento o si alguna parte del código se termina o se ha eliminado. Puede crear reglas dentro de otras funciones para usar en el futuro.

      Juntamos estas dos cosas y nos queda algo así:

      test('should change name', async () => { expect(nameTag.text()).not.toContain('name') await wrapper.vm.$nextTick() .then(()=>{expect(nameTag.text()).not.toBe(lastNameValue)}) })

      Esta prueba se va a repetir para todos los elementos que vamos a probar, quedándonos así:

      3.png

      Esta vez te toca escribirlos


      Sólo hace falta correr el script.

      npm run test:unit

      Puede que nos salgan algunos errores en el tiempo de compilación. No hay porque preocuparse por estos, siempre y cuando no impidan que pasen nuestras pruebas.

      Otra cosa que hay que tener en consideración es que estamos probando, en este caso, el servicioMock y estamos tomando datos al azar entre la respuesta. Puede que nuestras pruebas fallen porque nos sale un repetido. Lo único que debemos hacer es volverlo a intentar. Muchas veces se tiene como parámetro que falle, para sacar la concurrencia de algunos datos.

      Pero no es lo que buscamos aquí, solamente corre las pruebas de nuevo y si todo lo hicimos al pie de la letra, debemos obtener algo como esto:

      2.png

      Esto significa que todas las pruebas de todo nuestro código pasaron.

      ¡¡¡CON ESO HEMOS CONCLUIDO LAS PRUEBAS MÍNIMAS DE NUESTRO PROYECTO!!!.

      Pero aún hay más que aprender de todo este mundo… en la siguiente clase aprenderás cuáles son las mejores prácticas para hacer pruebas en Vue.


      ¿Qué otra solución le encontrarías al problema de tener muchas variables al principio? Compártela en los comentarios.

      Comentarios

      Juan Esteban Galvis

      Juan Esteban Galvis

      student•
      hace 6 años
        Carlos Eduardo Gomez García

        Carlos Eduardo Gomez García

        teacher•
        hace 6 años
        Angel Hernández Nava

        Angel Hernández Nava

        student•
        hace 6 años
      Sergio Guzmán Mayorga

      Sergio Guzmán Mayorga

      student•
      hace 5 años
      Jaime Ortiz

      Jaime Ortiz

      student•
      hace 5 años
        Stiven Castillo Montero

        Stiven Castillo Montero

        student•
        hace 5 años
      Julia Suárez

      Julia Suárez

      student•
      hace 5 años
        Añaqui Apolinar Morales

        Añaqui Apolinar Morales

        student•
        hace 5 años
        Julia Suárez

        Julia Suárez

        student•
        hace 5 años
      Carlos Eduardo Gomez García

      Carlos Eduardo Gomez García

      teacher•
      hace 6 años
        Arlex Felipe Llanos Betancourt

        Arlex Felipe Llanos Betancourt

        student•
        hace 6 años
        Carlos Eduardo Gomez García

        Carlos Eduardo Gomez García

        teacher•
        hace 6 años
      Jesús Alberto Martínez Hernández

      Jesús Alberto Martínez Hernández

      student•
      hace 6 años
      Angel Hernández Nava

      Angel Hernández Nava

      student•
      hace 6 años
      Jose Daniel Barría Reyes

      Jose Daniel Barría Reyes

      student•
      hace 6 años
      Añaqui Apolinar Morales

      Añaqui Apolinar Morales

      student•
      hace 5 años
        Victor Israel Torrecillas Garcia

        Victor Israel Torrecillas Garcia

        student•
        hace 5 años
      Oscar Gonzalez

      Oscar Gonzalez

      student•
      hace 5 años

      Excelente, comparto el código jaja principalmente para evitar que un compañero pueda cometer errores:

      describe('Validar Cambios', () => { const btn = wrapper.find('button') btn.trigger('click') test('should change name', async () => { expect(nameTag.text()).not.toContain('name') await wrapper.vm.$nextTick() .then( () => { expect(nameTag.text()).not.toBe(lastNameValue) }) }) test('should change name', async () => { expect(imgTag.attributes().src).not.toBe('') await wrapper.vm.$nextTick() .then( () => { expect(imgTag.attributes().src).not.toBe(lastImgValue) }) }) test('should change name', async () => { expect(typeTag.attributes().src).not.toBe('') await wrapper.vm.$nextTick() .then( () => { expect(typeTag.attributes().src).not.toBe(lastTypeValue) }) }) test('should change name', async () => { expect(weightTag.attributes().src).not.toBe(0) await wrapper.vm.$nextTick() .then( () => { expect(weightTag.attributes().src).not.toBe(lastWeightValue) }) }) test('should change name', async () => { expect(heightTag.attributes().src).not.toBe(0) await wrapper.vm.$nextTick() .then( () => { expect(heightTag.attributes().src).not.toBe(lastHeightValue) }) }) test('should change name', async () => { expect(abilitiesTag.attributes().src).not.toBe([]) await wrapper.vm.$nextTick() .then( () => { expect(abilitiesTag.attributes().src).not.toBe(lastAbilitiesValue) }) }) })

      Love you, lo único que te faltó fue cambiarle el nombre a las pruebas jaja, pero gracias:D!

      Debí haber checado primero los comentarios antes de tener que escribir todo eso jajaja

      ¿Por qué se usa el then junto con el await? El await ya espera a que la promesa se resuelva y lanza error si algo falla

      No me quedó claro algunas cosas:

      1. Dónde se usó shallowMount?
      2. Cuál es el callback que recibe $nextTick?
      3. Por qué se usa await y then juntos?
      4. Por qué comparan el componente con el valor del mismo componente vacío (expect(nameTag.text()).not.toBe(lastNameValue))?
      5. No veo la Integración de estas pruebas, parece más bien como si estuviera haciendo una prueba unitaria.

      ShallowMount se usó en el archivo dataTest.spec.js

      para las otras preguntas no tengo respuesta, también tengo las mismas dudas. await + then? xD

      Hola, no es necesario usar el then luego del nextThick pues al hacer await al promise puedes continuar usando matches sin necesidad de hacerlo dentro del callback del then y asi queda mas limpio el codigo

      Podrias poner un ejemplo? No entiendo el then y como funciona "con" o "sin el"

      Si claro, en resumidas cuentas queda algo asi:

      test('should change name', async () => { expect(nameTag.text()).not.toContain('name') await wrapper.vm.$nextTick(); expect(nameTag.text()).not.toBe(lastNameValue); })

      Lo que significa es que al hace rawait al nextTick automaticamente esperamos la siguiente renderizacion del componente de vue, por lo que podemos ejecutar cualquier expect para verificar que el componente se actualizo acorde a los cambios

      Hay solo ciertas partes que no entiendo, por ejemplo:

      1.- ¿Exactamente qué hace esto? expect(nameTag.text()).not.toContain('name') 2.- no entiendo muy bien por qué usar el $nextTick, es decir, no se supone que al llamar al trigger ya se hacen esos cambios?

      Hola,

      Para el punto 1, entiendo que la idea es verificar si los valores de las variables predeterminadas cambiaron, el cual ocurre cuando se ejecuta el método setData()

      data () { return { name: 'name', image: '', type: '', weight: 0, height: 0, abilities: [], changeTest: 0 } }

      Para el punto 2, si tengo también algo de duda, ya que solo puedo inferir que el trigger lanza el evento, pero las variables y componentes deben renderizar el cambio solicitado, de esta forma utilizando el ** $nextTick()**,esperamos que ocurra ese proceso para ahí si validar que realmente cada atributo haya cambiado su valor anterior, es lo que logré entender del proceso

      Va, eso tiene sentido jaja, gracias!

      Funciona correctamente el código, solo me marca warnings, buena clase :D

      La única duda que me quedó fué con el

      request.spec.js

      es el único que me marca error

      Muy buena clase!

      No entiendo el not que va antes del toBe()

      Solo es una negacion 'no deberia de ser'

      Esta es mi solución, si coloco el evento del click fuera del test me da error

      //Archivo para realizar pruebas de integracion import { mount } from '@vue/test-utils' import App from './../../src/App.vue' describe('Realizando pruebas de funcionamiento de la app', () => { //const createdSpy = jest.spyOn(App, 'created') const wrapper = mount(App) //Comprobando que la funcion created sea llamada por lo menos 1 vez /*test('Funcion created es llamada', ()=> { const createdSpy = jest.spyOn(App, 'created') const wrapper = mount(App) expect(createdSpy).toHaveBeenCalled() });*/ //Estado inicial de la aplicacion const nameTag = wrapper.find('.pokemon-name') const lastNameValue = nameTag.text() const imgTag = wrapper.find('img') const lastImgValue = imgTag.attributes().src const typeTag = wrapper.find('#type') const lastTypeValue = typeTag.text() const weightTag = wrapper.find('#weight') const lastWeightValue = weightTag.text() const heightTag = wrapper.find('#height') const lastHeightValue = heightTag.text() const abilitiesTag = wrapper.find('ul') const lastAbilitiesValue = abilitiesTag.text() /*const button = wrapper.find('button') button.trigger('click') console.log(wrapper.vm.data)*/ test('should change name', async () => { const button = wrapper.find('button') button.trigger('click') console.log(wrapper.vm.name) expect(nameTag.text()).not.toContain('name') wrapper.vm.$nextTick() expect(nameTag.text()).not.toBe(lastNameValue) }) test('should change image', async () => { const button = wrapper.find('button') button.trigger('click') console.log(wrapper.vm.name) expect(imgTag.attributes().src).not.toBe('') await wrapper.vm.$nextTick() expect(imgTag.attributes().src).not.toBe(lastImgValue) }) test('should change type', async () => { const button = wrapper.find('button') button.trigger('click') expect(typeTag.attributes().src).not.toBe('') await wrapper.vm.$nextTick() expect(typeTag.attributes().src).not.toBe(lastTypeValue) }) test('should change weight', async () => { const button = wrapper.find('button') button.trigger('click') expect(weightTag.attributes().src).not.toBe(0) await wrapper.vm.$nextTick() expect(weightTag.attributes().src).not.toBe(lastWeightValue) }) test('should change height', async () => { const button = wrapper.find('button') button.trigger('click') expect(heightTag.attributes().src).not.toBe(0) await wrapper.vm.$nextTick() expect(heightTag.attributes().src).not.toBe(lastHeightValue) }) test('should change abilities', async () => { const button = wrapper.find('button') button.trigger('click') expect(abilitiesTag.attributes().src).not.toBe([]) await wrapper.vm.$nextTick() expect(abilitiesTag.attributes().src).not.toBe(lastAbilitiesValue) }) })