Looks like Jason Seifer has put out a really great Rake Tutorial for those who aren’t 100% (read: me) on this whole “rake” thing
Archive for the ‘Testing’ Category
So the latest kerfuffle in the Rails world is DHH’s recent post, Testing like the TSA. In here he has a few non-controversial things to say about testing, and over-testing. IE:
But while all that nuance might have a place in a two-hour dinner conversation with enlightened participants, not so much in a blog post. So let me firebomb the debate with the following list of nuance-less opinions about testing your typical Rails application[...]
I had a great conversation with Dan here at my local Ruby on Rails group about this and while we didn’t see eye to eye, I think we came to the agreement that people are kinda crazy. On one hand, if you cargo cult all about testing you’ll end up with 30,000 lines of tests for 10 lines of code, or worse, fall into the trap of “ok, time to write my blog in 15 minutes… oh, I should test, what test framework, hmm… maybe I need to write my own, ok, lets start that, oh, how about a new DSL to support it, that’ll make it easier….” Case in point The Perfect Apostrophe cira 2006 from Merlin Mann. Or you go to rails looking to write a quick blog project and find that you have to learn RSPEC, Cucumber, Capistrano, WebRat, and 5 other new tools before you can even start writing your blog.
Of course as Dan said, if you come to just write code you’ll just write code, but honestly I think there are a lot of programmers in an influenceable stage and they come to Rails wanting to do the right thing and see the obsession with testing and maybe get sucked into, as DHH puts it, “fondling balls and confiscating nail clippers” instead of actually writing the code and creating the cool things they’re here to enjoy.
Obviously DHH has a lot of influence in the community, and there is danger of newbies seeing his post and saying “oh, well DHH said not to test so I’m not going to” (note: he never says don’t test). I think there might be more danger in scaring new members of the community away telling them (in a strong German accent of course) No you may not write ze code, YOU MUST TEST AND YOU MUST TEST ALLLLL ZEE TIME!
As always, this write endorses a middle ground, somewhere in between the extremes.
Potentially completely relevant is Google’s stance on test coverage.
Just awesome stuff, my favorite yet. Make sure you follow Aaron on Google+ as well, lots of cool Ruby and Rails related stuff there.
This is probably old news to everyone who reads this, but today I had a bit of an epiphany. I was watching Charles Max Wood’s excellent Teach Me To Code Screen-cast and realized (after watching two parts of his “building a blog” series) that he wasn’t ever actually looking at the output of his coding, at least in the traditional sense.
The way I’ve coded since, well, forever has been like this. I open up my editor window, and an output window. When I was writing C code back in the dot com days this was another terminal with a “make && ./app” in it, and in my newer web application days, a browser window with my mouse hand on the reload button. After a bit of code was written, I’d either hit “up-arrow enter” for C code or reload the browser, and see what’s happened.
Watching the screen-cast I realize that Charles was doing the following (as far as I can tell, as I’m pretty new to the whole TDD thing):
- Writing a scenario or feature (using cucumber)
- Using that to generate tests (with rspec, I think)
- Running the test, watching it fail
- Writing the code to make the test pass
- Running the test, watching it pass
Now the last four steps I do know about, those are standard TDD methodology, broken down into Red (write a failing test), Green (make it pass), Refactor (make the code better), but I was blown away with the realization that he wasn’t looking at the output of the code he was writing, but instead was letting the testing framework do the work, so instead of having to verify with your own eyes that the [insert web page you're interested in here] is showing properly, you have it checked programmatically, no browser needed (in fact, at the point in part two when the browser is needed, there’s that uncomfortable pause while FireFox groans and raises itself into a running state).
Is that what TDD is really about? I’ve always imagined it as an augmentation to the previously-described way I used to code in that before I coded and reloaded the browser window you’d write the test, then the code, then the browser reload, then the test again to make sure it passed.
This is a whole new world that’s frankly thrown me for a loop, and into a fervor of reading up on cucumber. I’m not sure how this will affect my code writing, but this makes the whole world of TDD a lot more interesting! Course, I’ll have to re-watch the two episodes to make sure I truly grok the tools that he’s using.
Further Reading / Links
The more alert among you will have noticed that my “work one day, post the next” regarding my new project has pretty much fallen dead. I’ve found this “testing” thing fairly difficult to get into. Part of it is just the syntax or rspec, some of it is just the mindset required to to Test Driven Development.
- RSpec syntax takes a bit to get used to
- RSpec philosphies take a bit to get used to…. understanding the :before block, lets, contexts, descriptions, and subjects are all great, but it’s even better to have an idea about the best practices associated with them
- The overall idea of TDD. Do you want to test the actions that a user is taking? IE: “Create an object”, “alter an object”. Or do you test each individual function in the system? IE: new() create() destroy(), etc. If the latter, are you expected to test all the functions you don’t create, ie: the built in object methods that you get when you have any class?
- How far do you take TDD if you’re just trying to get a 3 function class off the ground?
Luckily the test-driven @dkubb was there to help me out a bit, and gave me this nice setup to start with. This let me see the proper (or at least how Dan did it) setup for where a context/let/description/etc block goes. All good stuff.
Now I have a model (so to speak) I can work from, so now I can finally get off my ass and get some code written. Dan’s philosphy is that if you code for more than a few minutes at a time you’re doing something wrong, and you should be testing, coding, testing, coding and then doing some more testing before you do more coding.
This entry was almost titled “In Which it All Comes Apart” because lately I’ve felt like all my previous forward motion with my Rails project has come to a crashing halt. It seemed like the only time that I got work done was at the FV.rb meetups, but in the evenings I just didn’t have any drive to do anything, and on the weekend when I did, I’d think about the current couple of tasks on my plate and get… scared is about the only real word for it, and just go back to watching TV, websurfing, or whatever other thing that wasn’t programming Ruby and Rails. Not a good way to go.
Last night I finally broke through this a bit. Amidst my mother-in-law drilling and cutting (she’s helping my wife put up cabinets) and my brother-in-law on the couch oohing and awwing over heavy equipment ads on craigslist, I managed to get things done. I figure a bit of post-mortem might help me for the next time it happens.
The two things that I had on my plate were not, in fact, the only things needing to be done, but they were the two things that are fairly isolated and sort of simple.
The first was adding ‘areas’ to my referee site. Each club has many fields, each field has many games. I wanted to expand this so that each club has many areas, and each area has many fields, and so on. Basically this allows you to break up the “Langley” club into say, north south east and west, and assign users to various areas and make things a bit more manageable. IE: Assignor Bob manages the north zone, while Manager Sue takes care of South and East.
I think it might have come into the testing part again. Because I’d have to rearrange some of my queries to ensure that users get the right games from the right fields from the (now) right areas from (breath) the right club, having no testing set up means that I’d have to go to all the pages that access that code, redo the queries, re-test, etc. Ugh.
The second task that was a real stumbling block was the user and role management. I had set up user authentication a while back, and if you log in as one of two user types you’d end up being sent to the “correct” page, and the two different controllers (/bids and /assignments) are protected through a before_filter as well, but I hadn’t gotten around to “Management” stuff (editing games, fields, etc) yet.
The big mental block that I had in this area was that I had 3 fairly clearly defined roles, 4 if you include the “unauthenticated” users. I had
- Referee (can bid on games)
- Assignor (approves/edits referee bids)
- Club Admin (club management stuff)
All the stuff in the User model is geared towards these, a club_id is defined and required, email is required, etc.
The role that wasn’t so easily defined was the “master” admin. This is the main user that would manage the whole site, set up clubs, and basically have access to everything. I faced the challenge of either creating a new type of authentication and model (ignoring the DRY principle), putting a bunch of exceptions in (ie: requires validation of club_id unless this user has a role type of ‘masteradmin’) and making things ugly.
I managed to push through the first one, or at least start to. I’ve managed to get to the scaffolding part anyway. Also in my lunch hours I’ve started going at the failing tests too. That’s a whole other blog post though, probably involving me going back to the simplest cases that are in the Rails Tutorial book and figuring out how to deal with speccing out password protected pages