Is anything being done in core Vue to make unit testing easier?

I’ve been collaborating with Callum Macrae on vue-test to make some enhancements to be able to test emitted events. I’ve noticed that there are at least 2 other recent libs on github that have a similar goal to make unit testing easier: vue-testing and avoriaz.

My question is-- what if any work is going on in the core Vue project to ease unit testing? Would it make these types of libraries unnecessary?

Any guidance would be appreciate to eliminate duplicate or conflicting work.

Edit: I see “Component test utility” on the Vue roadmap, but I don’t know how to find out the details behind that.

Thanks!

5 Likes

There is not much work going on besides some experiments.

It’s on our roadmap, but so are many other things :stuck_out_tongue:

So by all means, go ahead. :slight_smile:

Hi @asselin, I’m the author of avoriaz.

Vue desperately needs an official test utility library, like react-addons-test-utils.

I’d like to start working on an official library. If you are interested, me, you and Callum could use our combined experience to start working on it.

The main things I think it needs:

  • Shallow rendering
  • A way to simulate mock events (including custom event object)
  • Find functions to traverse the virtual DOM tree

It should be it’s own repo on the vuejs github org.

Could a core team member create this repo, so we can start contributing? @evan

2 Likes

Hey! :slight_smile:

Thanks for the willingness to contribute in this way, and for your contributions so far with avoriaz!

I agree that Vue is really lacking in this area, and that we should be doing something, yet haven’t found the time to focus on this. So I think we will be open to contributions in this area.

Evan is not very active here. I will bring this up in our chat and ask him to chime in here or contact you by other means. Can you maybe leave your twitter handles?

2 Likes

@eddyerburgh

Yes, I’m definitely interested in collaborating. I think vue-test and avoriaz have similar enough designs that they could be merged. One of the things that it has that I think is beneficial are the Chai extensions.

I agree with the items on your list. IIRC, I think I committed code to vue-test for being able to fire a custom event to be able to test subcomponents. Supporting vuex should also probably be on that list too.

One more thing I’d like to add is IMO to be successful, we’ll need plenty of doc with examples that cover all the major use cases. There are still many engineers who need help with writing automated unit tests.

@LinusBorg My twitter is asselinps.

1 Like

Great @asselin!

Completely agree about docs.

Vue uses gitbooks, which is what I’m using in avoriaz at the moment.

Also agree about vuex and vue-router. You can test both with avoriaz (and I assume vue-test). But as they’re both maintained by the Vue org, it makes sense to add lightweight test utils for them both explicitly.

I don’t think we should merge the projects. I think we should start a fresh project using our experience. I’m also not sure we should follow similar APIs or not.

We can start a gitter channel to discuss design, although we’ll need help from a core member to do this.

Chai extensions are also great, but I think they should be a separate module. From what I’ve seen, ava is popular for testing. I went to a Vue meetup last night and everyone I spoke to about testing was using ava with require hooks. Chai extensions might not be useful to them, so having them as an optional module makes more sense I think.

Anyway, I’m really keen to start this conversation. I think we need a gitter chat and a repo.

Could you advise on how we can go about this @evan?

Hi,

I’d like to throw my hat in the ring as this is an area I’m particularly passionate about.

Like both of you I’ve been coming up with ways to make unit testing Vue easier and an official package would be awesome.

I’ve been working on vuenit which focuses more on the data manipulation and business logic side of vue components which, while completely different to the focus of avoriaz and vue-test, I think is just as important. It also comes with an extremely lightweight Vuex mock (as well a few other helpers) so I’m thinking that could form the basis for a Vuex utility.

I’m also the author of require-extension-hooks so if this is becoming an accepted way of setting up test environments I’d like to keep development of this module in line with any testing frameworks that get created.

1 Like

Hi Linus,

Only just seen this message!

My twitter handle is @eddyerburgh

Is there a development slack channel? Would be good to get the conversation started :slight_smile:

@LinusBorg It’s been a couple of weeks now, have you spoken to Evan?

Me and Jack have been talking on gitter, and it would be great to start building something :slight_smile:

Hey guys, really glad to see your efforts on this - I’m a bit swamped with conferences and ongoing work for 2.4 at the moment, but I do plan to give the testing story a proper look next week. Cheers!

6 Likes

Hey! Didn’t know about this thread.

Definitely interested in working together on this. Even if not as an official Vue thing, it doesn’t make sense to have multiple competing libraries doing the same thing - especially given how similar the vue-test and avoriaz APIs are!

@asselin @eddyerburgh @callumacrae thanks a lot for kicking off this conversation - I’ve wanted to work on some official test utilities for a while but I’m more than happy to see great solutions coming from the community.

I looked at Avoriaz and find it really well done (great job @eddyerburgh !). It also seems to be the most mature solution currently out there. If you are all ok with it, I’d love to adopt / improve upon it to create an official solution. If there’s anything from vue-test that avoriaz currently does not have, we can obviously pull it in.

I’ll be playing around with it in the next few days and in the meanwhile, let me know what is currently missing or hard to implement. (It seems shallow rendering is the primary need?)

5 Likes

@evan thanks :slight_smile:

I’m more than happy for avoriaz to be adopted and improved on for an official solution.

Shallow rendering is definitely the primary need.

Another pain point is that transitions are not supported in JSDOM, which is a popular way to test Vue components without a browser. This means getTransitionInfo throws an error when it tries to split transition CSS properties - https://github.com/vuejs/vue/blob/dev/src/platforms/web/runtime/transition-util.js#L113. Although this is JSDOM issue, it’s a fairly common problem for avoriaz users.

I was thinking about updating avoriaz to v2. The plan was to return a class of Wrappers from .find() instead of an array. This way it could default to using the first item for methods:

// Current
wrapper.find('div')[0].dispatch('click')
// Proposes
wrapper.find('div').dispatch('click')

And could throw an improved error message if no element is found:

// Current
wrapper.find('div')[0].is('div') // throws Uncaught TypeError: Cannot read property 'is' of undefined
// Proposed
wrapper.find('div').is('div') // throws Error, no div element was found 

The downside would be having to implement a custom array-like structure. This is similar to what enzyme does.

// Current
wrapper.find('div')[1].is('div')
// Proposed
wrapper.find('div').at(1).is('div')

I would also like to refactor the traversal implementation, and add the ability to use sibling selectors + and ~ in find. I was actually planning on doing that in the next fortnight.

To get around transition component issues in Vuenit, implementing shallow rendering did the trick, I just stubbed the transition component with a <slot> (so the inner content still displays)

For shallow rendering - it’s actually pretty simple to render a shallow VDOM tree of the current component (vm._render()) - this would also work even without JSDOM and can be cheaper/faster. The downside is we need to implement parallel traversal/assertion methods for the VDOM tree instead.

I completely agree with defaulting to the first item, would this be practical? This makes sense to me to provide an easy transition for those using the current API.

wrapper.find('div') - new behavior, yields the first item found like querySelector
wrapper.findAll('div') - old behavior, yields an array, e.g. - querySelectorAll

1 Like

@eddyerburgh @callumacrae
I would also be very happy to contribute to that.
I started a revue-testing package https://github.com/codebryo/revue mostly as I tried to follow the simplicity approach of Vue and make it nice to test with Jest.
I also think a common test solution that plays in nicely with the general Vue Syntax would be great and I am more than happy to contribute :slight_smile:

For all interested parties, kicking off a design issue here: https://github.com/vuejs/vue-test-utils/issues/1

5 Likes