Giter Site home page Giter Site logo

lmiller1990 / vue-testing-handbook Goto Github PK

View Code? Open in Web Editor NEW
869.0 25.0 160.0 23.88 MB

A guide on testing Vue components and applications

Home Page: https://lmiller1990.github.io/vue-testing-handbook/

JavaScript 43.92% HTML 0.86% Vue 48.69% Shell 0.25% Stylus 6.28%
tdd jest javascript-tests vue-test-utils vue vuejs vue-testing-handbook

vue-testing-handbook's Introduction

English | 日本語 | Русский | 简体中文

Vue Testing Handbook

Welcome to the Vue Testing Handbook!

What is this?

This is a collection of short, focused examples on how to test Vue components. It uses vue-test-utils, the official library for testing Vue components, and Jest, a modern testing framework. It covers the vue-test-utils API, as well as best practices and useful parts of the Jest API for testing Vue components. A working demo project with the examples is also included, which you can pull down and run yourself.

Languages

The handbook is written in English, but there are a number of translations. I prefer not to merge translations until the entire document is completed.

If you like an article, feel free to translate it and post it on your own blog. If you can leave a link to the original, that'd be great, too! Let's spread the good word of Vue.js component testing.

Contributing

Development

Vuepress is used to generate the static website. Articles are written in markdown.

Clone the repo and run yarn to install the dependencies. Then run yarn dev to open the dev server. Access it on localhost:8080.

To edit a guide, update the code in the src directory. The markdown files are converted to HTML when deployed – no need to edit those.

vue-testing-handbook's People

Contributors

aaronlamz avatar andrewgroe avatar axle07 avatar begueradj avatar bikingbadger avatar buntafujikawa avatar dependabot[bot] avatar elfalem avatar everttrollip avatar fanyu7 avatar junkim93 avatar kahirokunn avatar khsk avatar lmiller1990 avatar quannt avatar rogerlista avatar sethpoulin avatar shekeg avatar shinogasa avatar spencer1573 avatar steinrobert avatar superyusuke avatar suyanhanx avatar thomasan1999 avatar uxuf avatar vjoao avatar webistomin avatar wilmersondasilva avatar yinm avatar ykhirao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-testing-handbook's Issues

Write about propsData

https://github.com/lmiller1990/vue-testing-handbook/blob/master/docs/components-with-props.md

Write about propsData. Some ideas:

  • component receives and renders a prop. Show how to test that. Better yet, write the test first, and then the component, using the error messages to guide your development
  • factory functions. Often you end up with tests like this:
describe("Foo", () => {
  it("something", () => {
    const wrapper = mount(Foo, {
      propsData: {
        shouldShow: true,
        bar: 'foo'
    })
  })

 it("another thing", () => {
    const wrapper = mount(Foo, {
      propsData: {
        shouldShow: false,
        bar: 'foo'
    })
  })
})

We can introduce a factory function:

const factory = (propsData) => {
  return mount(Foo, {
    propsData: {
      bar: "foo",
      ...propsData
    }
  })
}

const wrapper = factory({ shouldShow: false })

const wrapper = factory({ shouldShow: true })

Bump versions

Should bump

  • versions of Vuepress
  • versions of vue, vue-test-utils etc in the demo app

Make headings and style consistent

Some pages use #h2, and some #3. All articles should follow the same style. This includes:

  • headings
  • common sections (such as conclusion, etc)
  • all link the the related tests

Guide on testing forms and inputs

There is a PR regarding this #37 in Japanese, but I think it's important to have it in English, too. We should have a guide about testing forms:

  • how to use setValue, setChecked etc for radio buttons/checkboxes
  • how to test select/option
  • how to test forms in general (find(Form).trigger('submit.prevent) etc
  • if the form is async (as most are) we need to use flushPromises and await maybe

etc.

how to test the watch?

what i want to know is that how can i test the watch with vue-test-utils and jest.
i had tried to do like this.
the code above is to featch data from the server,it will return a object of promise
this.$api.querySexListByGoodsCode(data)
appointment.js

watch: {
    addGoodsCodeList () {
      const data = {
        goodsCode: this.orderInfo.goodsCode,
        addGoodsCodes: this.addGoodsCodeListStr
      }
      console.log('========')
      console.log(this.$api.querySexListByGoodsCode)
      console.log('========')
      this.$api.querySexListByGoodsCode(data).then(res => {
        if (res.data.SZ_HEAD.RESP_CODE === 'S0000') {
          this.sexs = res.data.SZ_BODY.sexList
        } else if (['B0201', 'B0205', 'SE3006', 'SE1004'].includes(res.data.SZ_HEAD.RESP_CODE)) {
          this.$router.push({ name: 'login' })
        } else {
          this.$dialog.toast(res.data.SZ_HEAD.RESP_MSG)
        }
      })
    },

appointment.spec.js

it('this is what i did ', () => {
      let addGoodsCodeList
      wrapper.setData({
        orderInfo: {
          goodsCode: 'gds1213223'
        },
        addGoodsCodeListStr: 'gds1312331231'
      })
      addGoodsCodeList = jest.spyOn(api, 'querySexListByGoodsCode')
      wrapper.vm.$nextTick(() => {
        expect(addGoodsCodeList).toBeCalled()
        next()
      })
      addGoodsCodeList.mockClear()
    })

but ,i got the wrong message in my terminal
this is the wrong message :
[Vue warn]: Computed property "addGoodsCodeListStr" was assigned to but it has no setter.

found in

---> <Appointment>
       <Root>

console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
[Vue warn]: Error in nextTick: "Error: expect(jest.fn()).toBeCalled()

Expected mock function to have been called, but it was not called.

i hope to get the help to solve to this problem

New sections?

Some sections of Vue testing are not yet covered.

  1. Vue router
  2. functional components?
  3. plugins?
  4. snapshot testing?

Any ideas for new sections can be discussed here!

Improve deploy flow

  1. should deploy on merge to master (generate docs folder, etc)
  2. use Travis CI to lint the documentation/code, and run the tests.

How to fix doc?

Hi!

Thank you a good vue-testing-handbook!

I found typo in Japanese docs.
I want to fix it, but i don't know how to fix it.

Can i change html file direct? (ex:setting-up-for-tdd.html)
Or other way?
(Is there a tool to make document?)

thanks!


こんにちは!
素敵なテキストをありがとうございます!

日本語のドキュメントにタイポを見つけました.
修正しようと思ったのですが修正の仕方がわかりませんでした.

これは直接htmlファイルを修正して大丈夫でしょうか?
それとも他の方法で修正するのでしょうか?
(ドキュメント生成のためのツールが有るとか)

よろしく!

Section on factory function technique

Sometimes a component gets complex, eg:

const wrapper = mount(Comp, {
  // ... many options .......
})

Feels bad to copy paste it many times. You can use a factory function, which is discussed here. I think something like this would be useful, and we can go in depth with some interesting examples.

Improve contributions guidelines

The source files in the src directory are where the information is written, and the markdown files there are turned into HTML by Vuepress. This is not clear from the readme - we should include a section about how to contribute.

Mocks guide

Talk about how to use the mocks mounting object

Add Integration Tests Section with Vuex

Description

I have struggled a lot with testing in Vue.js due to a big lack of documentation from the Vue main page. I have found multiple very useful resources and this is actually one of them.
I just want to see how can I help you integrate an Integration Testing section, as I see it as a very powerful test that adds TONS of value at the moment of a complete validation of a feature. Just to make sure we are in the same channel, I'm referring to an Integration Test not to the Selenium tests that opens the browser and starts to do interactions with the app, but as a test that validates the functionality of a section of the application by running the complete flow of data and interactions

Let me put a small example. Let's suppose we have a web page that has a list of Pokemons. In the page, we have a Container Component that fetches the pokemons from an API, and then renders the pokemons in the screen.

containers/PokemonList.vue

<template>
  <div class="pokemon">
    <template v-for="pokemon in pokemons">
      <p class="pokemon__name">{ pokemon.name }</p>
    </template>
  </div>
</template>

<script>
export default {
  computed: {
    ...mapState({
       pokemons: state => state.pokemons
     })
  },
  methods: {
    ...mapActions(['fetchPokemons'])
  },
  mounted: function () {
    // assuming this is an store action that will fetch the pokemons and 
    // putting them into the Vuex store.
    this.fetchPokemons() 
  }
}
</script>
import { mount } from '@vue/test-utils'
import PokemonList from '@/containers/PokemonList.vue'

describe('Pokemon List', () => {
  it('should render the pokemon list', () => {
    axiosMocker
      .onGet('https://pokeapi.co/pokemons')
      .reply(200, [{ name: 'Pikachu' }, { name: 'Charmander' })

    const component = mount(PokemonList)
    
    await flushPromises() // wait for the action `fetchPokemons` to be executed

    const pokemons = component.findAll('.pokemon')
    expect(pokemons.length).toEqual(2)
    expect(pokemons.at(0).find('.pokemon__name')).toEqual('Pikachu')
    expect(pokemons.at(1).find('.pokemon__name')).toEqual('Charmander')
  })
})

Running that complete flow fits perfectly into an Integration test. I have had tons of struggles doing this kind of tests but it has been super satisfying to make them and I think your page should have a section for it. Let me know what you think!

Some of the resources I have found useful:

Write about `trigger`

Things to talk about:

  1. trigger
  2. testing async (API call)
  3. mocking the ajax lib
  4. flush-promises

Reorder pages

Setting up for TDD should come before two ways to render.

(ja) Add how to test input element

We should add a guide on testing forms and inputs. They are a common occurrence in almost all applications.

Talk about how to set a value using wrapper.find('input').element.value. Also the new APIs, setValue, setSelected, setChecked. https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value

We should support both English and Japanese.


エレメントへのアクセスはこちらが標準的 by vuejs/vue-test-utils#79

const value = wrapper.find('input').element.value

ただ setValue などでアクセスできるようになったのでその書き方も書いていく。

  • <input type="text">
  • <input type="radio">
  • ...others

などのテストを追加する

Routing guide

There is not much information anywhere about testing Vue router. I'll work on a guide for it.

I think we should discuss:

  1. use with an actual vue router instance
  2. use with a mock router
  3. e2e testing (you can write e2e like tests using Vue test utils, too). For example
wrapper = mount(Foo)

wrapper.vm.$router.push("/route")

// assert something happens when you visit `/route`

Sample Request: Component - Actions test sample with namespaced modules

Hello,

I wish to test Vuex store actions in components. The guide provided is very good:
https://github.com/lmiller1990/vue-testing-handbook/blob/master/src/vuex-in-components-mutations-and-actions.md

My problem is our Vuex store has a lot os namespaced modules, 50 aprox.

I cannot find the way to properly test the Component - Action connection without having the replicate the whole store namespace structure in the test, which makes it unmantainable.

Can someone provide light on this matter? add a namespaced module sample in https://github.com/lmiller1990/vue-testing-handbook/blob/master/src/vuex-in-components-mutations-and-actions.md?

Thanks a lot!
Francesc

Testing w/ TypeScript

TypeScript lets us be even more thorough with our testing. Might be useful to write a bit about it.

Vue Router > Component Guards > beforeRouteLeave doesnt call with "this"

The beforeRouteLeave in-component guard has access to this but the example doesn't pass in a context.

The example should probably be updated to do something like:

it("calls bustCache and next when leaving the route", () => {
  const wrapper = shallowMount(NestedRoute);
  const next = jest.fn()
  NestedRoute.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next)

  expect(mockModule.bustCache).toHaveBeenCalled()
  expect(next).toHaveBeenCalled()
})

and probably add an info box about routes that can use this

Wrong implementation in "Simulating user input"

In the "Simulating user input" page, the test still passes even if the submit event is not triggered.

Using v-show on div.message only acts on the CSS, keeping the element in the DOM. You should use v-if.

    <div 
      class="message" 
      v-show="submitted" <!-- should be v-if -->
    >

The implementation in the demo-app repo is correct but this is not the one used in the docs.

(ja) Unit test nearly e2e test

Please see this youtube

https://www.youtube.com/watch?v=OIpfWTThrK8&feature=youtu.be&t=7m47s

import Parent from "Parent.vue"
import Child from "Child.vue"

const ChildInstance = wrapper.find(Child)
Child.vm.$emit("submitted")

expect(parentMethodMock).toBeCalled()
// Child.vm.$options.methods.submitted.call(Child.vm)

子コンポーネントから$emitを呼び出して親コンポーネントのメソッドが発火されるかどうかのテストができる。

Unitテストというよりe2eテストに近くなっていますが、こんな書き方もあるのでこれについて記事を書く。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.