linemanjs / lineman-angular-template

A Lineman Application Template using AngularJS
251 stars 88 forks source link

To jQuery or not to jQuery (specs) #24

Closed Foxandxss closed 10 years ago

Foxandxss commented 10 years ago

I want to open a discussion here.

The good part of angular is the freedom, you can do it like you want, but I think that there are some conventions that are good to follow.

I saw some different ways to test directives, there are people that like to test directives using e2e tests and others prefers unit tests.

Almost every directive test I saw uses the unit test approach. That approach uses jQuery.

Lets say that I have a calendar directive, it shows a calendar for a given month/year.

How could you test it?

For me, unit tests are to test a component in completely isolation and e2e to test everything working together.

Let's see the unit test approach.

I want to see that <calendar></calendar> generates the calendar for the current month.

To assert that (assuming that every day is a div) I could retrieve every day on the element that contains the ... day class. Then I assert I have 42 days (a 6-week calendar). I can only do that using jQuery because jQlite doesn't have class selectors.

I could assert that there is a day with the current class that marks 'today'. There is no way to do that with jQlite either.

Then I do the same tests with <calendar month="somemonth" year="someyear"></calendar> with valid values and also with invalid values.

What about e2e? e2e are for other kind of stuff. I would like to test there that if I go to: /calendar/2013/12 I get december 2013 calendar. I am testing the routing system there, I shouldn't test there that I have a 42 days calendar, that should be tested on the unit test.

Alright alright, you want to test your calendar with e2e where you can do some better selections...

Unit tests use a template made for the test element = '<calendar></calendar>' but the e2e tests will use the real template.

So if my real template has <calendar month="month" year="year"></calendar> how are you going to test the directive without attributes? You can't.

TL;DR;: I think that we should include jQuery in our spec helpers and load it before angular. Everybody seems to use jQuery to test their directives. You can check more examples on angular-ui bootstrap (where I consider that you could find the best made directives for angular).

Thoughts? :)

searls commented 10 years ago

I think I'm :-1: on this for now, but it's a worthwhile discussion to be having. 

A few of my thoughts:

  1. Most people coming to angular are testing novices. Many of them have never written tests at all prior to using angular. This has resulted in the typical learning curve (at community scale) of "what typifies a unit vs integration test" and "what value are we trying to get out of testing?" As a result, anything we do should be straightforward enough that it's unlikely to trip people up
  2. Re: the above, I worry that by leaving jquery in a spec helper, anybody test driving their code would be liable to accidentally take advantage of jquery features absent from jqlite, only to realize that their tests were lying to them when they went to look at the page. I could imagine this being notoriously difficult to debug if jquery showed up without user input. 
  3. Additionally, most angular apps I've seen in the wild are hybrids that include jquery anyway, so pulling in another version at spec-time brings with it more subtle bug risk and noConflict issues

I'm currently investing all of my testing time in node to figuring out a great way to drive browser interactions. I'll circle back and spend time improving angular test tools. I happen to be pretty critical of a lot of angular testing idioms (they're too integrated and aren't conducive to getting design feedback TDD), so I don't want to force us into prescribing an approach until we can really dive into it.

On Mon, Dec 9, 2013 at 9:16 AM, Foxandxss notifications@github.com wrote:

I want to open a discussion here. The good part of angular is the freedom, you can do it like you want, but I think that there are some conventions that are good to follow. I saw some different ways to test directives, there are people that like to test directives using e2e tests and others prefers unit tests. Almost every directive test I saw uses the unit test approach. That approach uses jQuery. Lets say that I have a calendar directive, it shows a calendar for a given month/year. How could you test it? For me, unit tests are to test a component in completely isolation and e2e to test everything working together. Let's see the unit test approach. I want to see that <calendar></calendar> generates the calendar for the current month. To assert that (assuming that every day is a div) I could retrieve every day on the element that contains the ... day class. Then I assert I have 42 days (a 6-week calendar). I can only do that using jQuery because jQlite doesn't have class selectors. I could assert that there is a day with the current class that marks 'today'. There is no way to do that with jQlite either. Then I do the same tests with <calendar month="somemonth" year="someyear"></calendar> with valid values and also with invalid values. What about e2e? e2e are for other kind of stuff. I would like to test there that if I go to: /calendar/2013/12 I get december 2013 calendar. I am testing the routing system there, I shouldn't test there that I have a 42 days calendar, that should be tested on the unit test. Alright alright, you want to test your calendar with e2e where you can do some better selections... Unit tests use a template made for the test element = '<calendar></calendar>' but the e2e tests will use the real template. So if my real template has <calendar month="month" year="year"></calendar> how are you going to test the directive without attributes? You can't. TL;DR;: I think that we should include jQuery in our spec helpers and load it before angular. Everybody seems to use jQuery to test their directives. You can check more examples on angular-ui bootstrap (where I consider that you could find the best made directives for angular).

Thoughts? :)

Reply to this email directly or view it on GitHub: https://github.com/testdouble/lineman-angular-template/issues/24