On Fri, Jan 27, 2012 at 05:22:03PM -0800, Kristján Pétursson wrote:
> Based on reading lots of frameworks and finding not a lot of conversation,
> if I were to start fresh I'd opt for the half-dozen tools TJ Holowaychuk
> has written for Node testing. Their ideals match Node's, they have active
> committers, and because they're under the same umbrella, they should work
> well together and improve in step. That path would boil down to:
Sounds solid.
> Unit and Functional testing with Mocha
> (http://visionmedia.github.com/mocha/). This is TJ's second take on
> testing Node, and presumably incorporates what he learned writing
> Expresso. It's straightforward and clean (though admittedly because I'm
> used to RSpec and they match), and comes with some nice bonuses in the
> reporting department. Converting from Vows to Mocha would make this:
> [...]
> It's more lines, but I find it far clearer what's going on. Again, it's
> particularly valuable that the second batch shares no state with the
> first—you
> are fully aware of and responsible for all initialization.
Looks more readable to me, though it'll be easier to tell with some
real-world locker tests converted.
> For functional testing (which I put at the level of verifying individual
> controller behavior), there's Tobi (https://github.com/LearnBoost/tobi),
> which has a representative example in the README that I won't replicate
> here. Tobi spins up your app, makes requests, and uses jsdom to let you
> examine everything.
Looks nice!
> For integration testing, I think we should ditch Capybera in favor of a
> Node solution so that there's only one language to worry about. If you're
> capable of coding the locker, you should be equally capable of testing it.
>
> There are two interesting tools here: Soda (
> https://github.com/learnboost/soda) and Zombie
> (https://github.com/assaf/zombie). Soda completes the top-to-bottom
> Holowaychuk hat trick as a Node adapter for Selenium, while Zombie appears
> to emulate the DOM, CSS, JS and browsing all on its own.
I didn't realize there were alternatives here, or I probably wouldn't have
spent time getting the existing front end stack running under Jenkins. ;-)
No worries, though. We should definitely choose the best tool available,
and I think ease of test development and maintenance are primary
considerations.
> Points for Soda are that in wraps a common and much-used tool (Selenium),
> has what looks to me like a more coherent DSL, and already integrates with
> Sauce Labs if we ever want to offload a monotonically slower integration
> suite.
>
> Zombie, on the other hand, looks like it may have fewer moving parts at
> the expense of a trickier install process (it's got an npm package, but
> actually compiles, where Soda just uses Selenium's .jar). Because it's not
> just a wrapper, one can mess a lot more with the tool itself. However,
> because it's younger than Selenium, one might /have/ to mess more with the
> tool itself.
>
> It's unclear to me whether one of Soda or Zombie would be faster than the
> other, which is a great feature when you want to run them locally.
Which one is nicer to write tests for? Sounds like maybe Soda?
If we need to improve the install process, we can do that with one-time
work, while we'll be writing tests for a long time to come, so I'd
prioritize features over packaging.
> Lastly, I happened upon some helper libraries that just look handy in
> general:
> . NodeReplay (https://github.com/assaf/node-replay) will catch and save HTTP
> requests for later playback. This makes it easy to run tests that rely on
> third parties once for real, then use their responses for the rest of your
> runs. One flag turns on real requests again when you want to run final
> acceptance on the API or just get a new set of recordings.
Nice find!
> . node-database-cleaner (https://github.com/emerleite/node-database-cleaner)
> gives you one line to obliterate your test data when you want to ensure
> isolation.
This reminds me, we should launch mongo with --noprealloc when running the
test suite, otherwise it's S-L-O-W to create the database. Currently, the
database gets reused (except under Jenkins where we clean everything up),
but it sounds like that's going to change.
> . Should (https://github.com/visionmedia/should.js) makes your tests read
> more like real sentences.
Looks Rubyish. :-)
> I haven't considered fixtures vs. factories yet, but in general prefer
> factories. As code bases expand, I find the fixtures become difficult to
> maintain, especially if they depend on each other. If someone feels
> strongly and can advise their development, chime in.
I'd lean toward factories, especially if it means we can keep the test data
closer to the test code. I'll yield to the folks writing tests, though.
> Still reading? Did you do it in one sitting? Kudos. Whaddaya think?
It sounds like there are better tools available than when we started, which
is great news.
Test coverage is not great at this point, but we should probably save that
for a follow-on project. It would be a success just to make the existing
tests (or those which are still valuable) a joy to use and extend.
--
- mdz
I'm looking into cleaning up the locker's test suite, and much feedback would beappreciated. For context, I've been in Rails-land for five years, which willcertainly influence my approach. If I'm trying to apply anything that doesn'tmesh with Node.
Capybara is agreat tool, but it sucks to make someone who wants to hack on locker write Rubyto do any full-stack work.
It's straightforward and clean (though admittedlybecause I'm used to RSpec and they match)
It's more lines, but I find it far clearer what's going on. Again, it'sparticularly valuable that the second batch shares no state with the first—youare fully aware of and responsible for all initialization.
For functional testing (which I put at the level of verifying individualcontroller behavior), there's Tobi (https://github.com/LearnBoost/tobi), whichhas a representative example in the README that I won't replicate here. Tobispins up your app, makes requests, and uses jsdom to let you examine everything.
For integration testing, I think we should ditch Capybera in favor of a Nodesolution so that there's only one language to worry about. If you're capable ofcoding the locker, you should be equally capable of testing it.
There are two interesting tools here: Soda (https://github.com/learnboost/soda)and Zombie (https://github.com/assaf/zombie). Soda completes the top-to-bottomHolowaychuk hat trick as a Node adapter for Selenium, while Zombie appears toemulate the DOM, CSS, JS and browsing all on its own.
It's unclear to me whether one of Soda or Zombie would be faster than the other,which is a great feature when you want to run them locally.
I haven't considered fixtures vs. factories yet, but in general preferfactories. As code bases expand, I find the fixtures become difficult tomaintain, especially if they depend on each other. If someone feels strongly andcan advise their development, chime in.
One sore point I got a bit grumpy on recently was the fixtures for the synclet testing, arguing that they're essentially useless as a representation of the APIs in the wild since the real APIs are both error prone and always a moving target, a fixture is a false sense of security and anyone touching synclet code knows they have to try it on the real API to actually know if it works anyway. It seems the only great way to get another layer of automated testing for these is probably having a CI service using legit auth tokens to hit the real apis :/
I've been super keen on the idea of each package having it's own tests (in it's own dir) as well, and probably a top-level batch tool that would test a given config and all the referenced package's tests. It'd be great to be dev'ing a collection or app and just run those locally while coding, and step up and run all before committing, etc.
If we need to improve the install process, we can do that with one-time
work, while we'll be writing tests for a long time to come, so I'd
prioritize features over packaging.
Which reminds me, have you run across anything like zentest while you were looking at frameworks? It can be a little finicky in the Ruby world, but when it was working, it was a very valuable utility for encouraging a BDD flow.
For functional testing (which I put at the level of verifying individualcontroller behavior), there's Tobi (https://github.com/LearnBoost/tobi), whichhas a representative example in the README that I won't replicate here. Tobispins up your app, makes requests, and uses jsdom to let you examine everything.
Would this mostly be for Integral? The locker core doesn't have a lot of controllers in the traditional sense, and it seems like Soda would work better with in-browser MVC-style "viewer" apps like the dashboard.
Did you run across Janky (https://github.com/github/janky) while you were looking at things? It doesn't sound like we'd have to make that many changes to Jenkins to get up and running with it, and I think we were talking about looking more closely at Hu-Bot anyway.
I still have a few tabs open to look at these projects in a bit more depth, but it's very interesting to me. I'm curious if people could expand more on why they prefer such heavy DSL like testing frameworks over something like node-unit with basic assertions. I would venture a guess related to those that came from TDD & BDD backgrounds, largely starting in the Ruby world vs say C++ world and more usage as unit and regression testing.
On another front, has anyone looked at PhantomJS as another headless, but actually rendering, option for visual integration testing? I've been using it heavily in a personal project and absolutely loving it.
I'm curious if people could expand more on why they prefer such heavy DSL like testing frameworks over something like node-unit with basic assertions. I would venture a guess related to those that came from TDD & BDD backgrounds, largely starting in the Ruby world vs say C++ world and more usage as unit and regression testing.
I'm glad everyone agrees that fixtures are suck. Anyone know of a good factory?
Core still has plenty of pieces that handle requests though. Tobi probably doesn't add much if all we're doing is verifying response codes and JSON blobs, but something should.
I do think Cucumber and that genre go too far and just produce an unnecessary layer of translation that's prone to bugs itself. As the saying goes, someone has a problem and decides to use regular expressions...