![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
By way of
sfllaw, a development paradigm I had not previously known about, and tool for developing in this fashion. Holy shmoley. I agree with Bill Tozier, I want this for Python yesterday.
Behaviour-driven development is basically test-driven development on steroids: it takes the principle we like to cite, "write your man pages first!", and hooks it right into the test-driven development cycle, except now you're developing one behaviour at a time, so you can write your tests piece by piece and have individual chunks of the system piece by piece. I like TDD, but sometimes I have to write code fast (and yes, TDD always ends up saving me time in the end, but we've all had those projects where OMG EVERYTHING IS ON FIRE AND THERE'S NOT TIME TO DO IT RIGHT. Behaviour-driven development eliminates your excuses to not do it right: you're producing code as discrete functional units, complete with tests to prove that they are correctly functioning functional units, and you're producing it fast enough to keep management/the client happy. (Clients are sometimes not happy when the first week of work goes into building the unit test suite. Yes, yes, I know, that week of work saves a month or more later on down the line. Some of my clients are no longer my clients for a reason.)
Behaviour-driven development is also a great tool for the "design the UI first" school of programming, and any project that doesn't follow that school of programming is doing it wrong. (Think of it this way: if you're writing a library, design the API first -- that is to say, write the man page first. If you're writing a web application, mock up the user interface, figure out what the damn thing's going to look like and do all your changing-your-mind about how the UI is going to behave before you start laying down AJAX requests.)
Also courtesy
sfllaw, a talk by Ben Mabey explaining not only these ideas but the business decisions which motivate behaviour-driven development. This is a really great overview and I strongly encourage any programmer with a pragmatic spirit -- or, even better, an entrepreneurial one -- to block out half an hour of your time to watch it.
Alas and alack, Cucumber is not available for Python yet, and from what I've seen, I really like the way it works. It apparently can be used with PHP, but I really would prefer to avoid PHP if at all possible; my preferred style is just way too functional these days to blend well with PHP. (I've developed a thing for continuation-passing style in the last month or so.) This may end up being the thing that finally motivates me to learn Ruby. I have a little side project going on right now that has a web-application-framework-shaped hole in it, and I had been planning on using Django, but given that it's going to be a Javascript-heavy front end with likely a healthy dose of script.aculo.us, Rails could be a better tool for the job. I'll need to decide if I like how Rails talks to databases; I'm madly in love with the way Django does it and anything less will be a major disappointment, so this is definitely a factor to consider. (Current Rails devs, your input is welcome -- I know very little about your framework. I used to be cranky about the lack of integration with Apache, but there's mod_rails these days and I assume that removes a lot of the reasons I had for bitching.)
And I'd have real continuations. That's always a plus.
Decisions, decisions. But I do like the fact that tools like this exist at all; it's me who needs to get over my uncanny-valley problem with Ruby.
(
karnythia,
thewayoftheid,
tanyad, I'm not talking about the project I'm doing for y'all, this is a different project. So many irons in the fire!)
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Behaviour-driven development is basically test-driven development on steroids: it takes the principle we like to cite, "write your man pages first!", and hooks it right into the test-driven development cycle, except now you're developing one behaviour at a time, so you can write your tests piece by piece and have individual chunks of the system piece by piece. I like TDD, but sometimes I have to write code fast (and yes, TDD always ends up saving me time in the end, but we've all had those projects where OMG EVERYTHING IS ON FIRE AND THERE'S NOT TIME TO DO IT RIGHT. Behaviour-driven development eliminates your excuses to not do it right: you're producing code as discrete functional units, complete with tests to prove that they are correctly functioning functional units, and you're producing it fast enough to keep management/the client happy. (Clients are sometimes not happy when the first week of work goes into building the unit test suite. Yes, yes, I know, that week of work saves a month or more later on down the line. Some of my clients are no longer my clients for a reason.)
Behaviour-driven development is also a great tool for the "design the UI first" school of programming, and any project that doesn't follow that school of programming is doing it wrong. (Think of it this way: if you're writing a library, design the API first -- that is to say, write the man page first. If you're writing a web application, mock up the user interface, figure out what the damn thing's going to look like and do all your changing-your-mind about how the UI is going to behave before you start laying down AJAX requests.)
Also courtesy
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Alas and alack, Cucumber is not available for Python yet, and from what I've seen, I really like the way it works. It apparently can be used with PHP, but I really would prefer to avoid PHP if at all possible; my preferred style is just way too functional these days to blend well with PHP. (I've developed a thing for continuation-passing style in the last month or so.) This may end up being the thing that finally motivates me to learn Ruby. I have a little side project going on right now that has a web-application-framework-shaped hole in it, and I had been planning on using Django, but given that it's going to be a Javascript-heavy front end with likely a healthy dose of script.aculo.us, Rails could be a better tool for the job. I'll need to decide if I like how Rails talks to databases; I'm madly in love with the way Django does it and anything less will be a major disappointment, so this is definitely a factor to consider. (Current Rails devs, your input is welcome -- I know very little about your framework. I used to be cranky about the lack of integration with Apache, but there's mod_rails these days and I assume that removes a lot of the reasons I had for bitching.)
And I'd have real continuations. That's always a plus.
Decisions, decisions. But I do like the fact that tools like this exist at all; it's me who needs to get over my uncanny-valley problem with Ruby.
(
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
(no subject)
Date: 2009-05-29 01:22 am (UTC)We use JQuery and have lots of success.
(no subject)
Date: 2009-05-29 01:32 am (UTC)(no subject)
Date: 2009-05-29 01:45 am (UTC)But then again, I suppose it's a differing philosophy thing: http://lethain.com/entry/2008/sep/21/intro-to-unintrusive-javascript-with-django/
(no subject)
Date: 2009-05-29 02:06 am (UTC)(no subject)
Date: 2009-05-29 03:49 am (UTC)While Rails is very well integrated with Rails, they're not very tightly integrated. I was worried about that, but it turns out it's pretty easy to use other JavaScript frameworks with Rails; Rails doesn't give you any crap if you just drop in MooTools or jQuery instead.
(Plus, of course, jQuery does a bang-up job of cooperating with other JS frameworks. I was pretty impressed when I saw how easy it is to use jQuery alongside anything else.)
(no subject)
Date: 2009-05-29 04:15 am (UTC)(no subject)
Date: 2009-05-29 01:30 am (UTC)http://docs.python.org/reference/expressions.html#yield-expressions
(no subject)
Date: 2009-05-29 01:34 am (UTC)(no subject)
Date: 2009-05-29 01:40 am (UTC)(no subject)
Date: 2009-05-29 01:42 am (UTC)(no subject)
Date: 2009-05-29 06:51 am (UTC)The surprising thing is that it turns out to be possible to implement such a general construct efficiently.
(no subject)
Date: 2009-05-29 01:35 am (UTC)(no subject)
Date: 2009-05-29 01:40 am (UTC)(pardon the grey-on-white code on that,
If it can, well, then thanks for schooling me. :) I expect this interface to have dynamically generated Draggables and Sortables, so a programmatic interface to them will be a thing of Awesome.
(no subject)
Date: 2009-05-29 01:56 am (UTC)(no subject)
Date: 2009-05-29 02:01 am (UTC)(no subject)
Date: 2009-05-29 02:08 am (UTC)(no subject)
Date: 2009-05-29 02:10 am (UTC)http://www.djangosnippets.org/snippets/929/
(no subject)
Date: 2009-05-29 02:14 am (UTC)(no subject)
Date: 2009-05-29 02:19 am (UTC)(no subject)
Date: 2009-05-29 02:23 am (UTC)(no subject)
Date: 2009-05-29 02:16 am (UTC)There are a lot of things wrong with them, like the
{% if %}
tag, but looking and behaving like HTML is a very good thing.Also, I find it super trivial to implement extensions to the template language, which means that I can push complexity out of the templates and into tags, filters, forms, fields, special helper objects, or even the models themselves; depending on where this belongs.
(no subject)
Date: 2009-05-29 04:18 am (UTC)...I am ashamed to admit that I never even thought of that.
(no subject)
Date: 2009-05-29 02:11 am (UTC)In Django, we use various views that spit out partial results, which you would have to write anyway, and use jQuery for the loading and the effects.
For
rik's example of:
we'd write, by hand, using jQuery:Granted, that’s a lot more code, but there’s a lot less magic. You can, of course, implement a lot of this magic in template tags. Simple Googling shows that this has already been done, but rather poorly from my point of view.
The Django way should probably look like this:
using context variables with proper methods to render the JavaScript and some handy filters to add any effects.(no subject)
Date: 2009-05-29 02:17 am (UTC)(no subject)
Date: 2009-05-29 02:29 am (UTC)Also I think there might be generic views that output JSON anyways so you might not even have to go through the trouble of writing the views yourself.
(no subject)
Date: 2009-05-29 02:31 am (UTC)django.core.serializers.serialize("json", SomeModel.objects.all())
?(no subject)
Date: 2009-05-29 02:44 am (UTC)Now that I look there isn't one, but that's pretty close to generic as you can get. Writing a generic view to just wrap around a Model and return JSON would be super easy.
(no subject)
Date: 2009-05-29 02:21 am (UTC)Sigh. I miss Python.
(no subject)
Date: 2009-05-29 03:46 am (UTC)I was going to say "Imagine I just quoted your entire third paragraph here", but this comment is going to be so far down the page that making readers scroll back up, count, and then scroll back down would just be mean, so I will quote the whole damn thing:
This is very similar to some stuff I wrote a long time ago — particularly the last two paragraphs of the "Interface and Program Better Adapted to Users" subsection.
Needless to say, I completely agree with you. :)
Agile's whole attitude toward documentation (namely, that it's something optional) is one of the things that's always annoyed me about it. I think BDD is a little lightweight, as docs go, but it's damned well better than nothing.
As someone who's been flipping back and forth between PHP, Ruby/Rails, and JavaScript for the past few months: If your style's been going more and more functional, I agree that you should avoid PHP. It has a few sops toward functional programming, but they're pretty weak sauce. In fact, they're downright laughable. Perl's FP options are much better.
Ruby, on the other hand, rather likes FP. In fact, the way I started learning FP was in JavaScript, using Prototype and Scriptaculous... which in turn got all their FP-ness from Ruby and Rails. Ruby likes FP a lot. (Okay, not as much as it likes OO-ness... and one thing it inherited from Perl is that it doesn't enforce either of those things on you. If you want to write procedural Ruby, you actually can... you'll just be wasting most of the language. It'd be like driving a car and never getting past second gear.)
As for Rails and Apache: Phusion Passenger makes it dead easy. If Apache integration was your major stumbling block to Rails adoption, then OMG you have got to check that thing out. Passenger is mod_rails in the sense that it's as easy and tight as mod_perl or mod_php. (I think some other project has the actual "mod_rails" name, but Passenger leaves it in the dust.)
If you like Python, I suspect you will either like Ruby a lot, because there are so many similarities, or hate it, because it's so close and yet so different in so many details. But they occupy very mich the same ecological niche (and Perl used to occupy pretty much the same one, before it faded into the background).
(no subject)
Date: 2009-05-29 04:13 am (UTC)There are a bunch of considerations to take into account when deciding what fits best in that web-application-framework-shaped hole: what the team members are most experienced with ($collaborator knows no Python yet, but might know some Ruby; I know very little Ruby and buggerall about Rails, but there are tutorials), what will be the best tool for the job with respect to features, what will be the best tool for the job with respect to maintenance and the Next Jackass Problem, just how badly I want to use this BDD tool, &c.
(no subject)
Date: 2009-05-29 05:05 am (UTC)I can totally understand that. It's part of what I was getting at in my last paragraph. "Uncanny valley" is actually a pretty good phrase to describe how similar the two are (and yet how different).
Which one? Cucumber? It's available for Rails. (I'm misunderstanding, aren't I?)
(Oh, and as far as Ruby tutorials? If you're as much like me as I think you are, you'll find why's Poignant Guide to Ruby to be interesting, but quickly infuriating and not very useful. It's fun to read the first 2 or 3 chapters, but by the end of them, I was going, "That's amusing as all hell, and I love the cartoon foxes screaming about chunky bacon,, but it's not actually teaching me to program in this language nearly as quickly as a more left-brained guide would.")
(no subject)
Date: 2009-05-29 09:41 pm (UTC)Yes. :) "Compatible with Cucumber" is a plus for Ruby and a minus for Python. Though, looking further into the Cucumber docs, it looks like there's a way to use it with some other tools for language-agnostic, outside-in Web application development; I may end up trying this, and if I do, I'll report back what I find out.
Thanks for the tip on the tutorial, I'll have a look. :)
(no subject)
Date: 2009-05-29 06:56 am (UTC)(no subject)
Date: 2009-05-29 03:50 am (UTC)Yes, this. For some reason, it didn't occur to me that there is another way to do this until you pointed out that it's a good plan.
(no subject)
Date: 2009-05-29 04:01 am (UTC)(no subject)
Date: 2009-05-29 06:58 am (UTC)(no subject)
Date: 2009-05-29 04:22 am (UTC)System-type #1 is one where we're exploring a technical idea, and we don't know what's going to work or how or anything. So it's pure implementation. There's no "interface". It's a technical experiment. We write tests, and those are all hypotheses. Not "requirements".
System-type #2 is a language or machine tool of which there's a well understood set of requirements. They're expressed in terms of a very detailed spec and a ginormous testsuite (tens of thousands of cases), every one of which is completely non-negotiable. These systems typically acquire secondary testsuites as they mature -- the regression suite, the performance suite, etc. -- but again, there tends to be no room for misunderstanding: regression tests are bugs, performance tests are scalar measurements.
In both type of system, the implementation is the meat of the problem; the "surface area" (while typically infinite) is not something we spend any time with customers or "system-consumers" arguing over. So I think the brow-beating about using one or another "TDD methodology" variant ... is directed at a different kind of software?
(no subject)
Date: 2009-05-29 04:33 am (UTC)I know where I tend to get lazy in areas that may end up biting me later, and I think this approach will help lessen my laziness in such a way that I'm more productive with the lines of code I write. YMMV.
Note that most of what I write are either scientific libraries or user-facing applications.
(no subject)
Date: 2009-05-29 04:39 am (UTC)Do massive quantities of asserts count as TDD? :)
(no subject)
Date: 2009-05-29 07:04 am (UTC)They both tell you where the problem is when something goes wrong (but DBC is better at that).
They both provide documentation about how to call things (but BDD is better at that).
They both help you think out the requirements for what the code you're writing has to do (but BDD is better at that).
They both make your software more robust (but DBC is better at that, because it checks real values instead of fake ones).
They both reduce the effort of refactoring your software (but BDD is better at that).
They both reduce the time from when you write a bug to when you find it (although arguably BDD is better at that, because you don't have to test anything manually in order to make things blow up).
Unfortunately my experience with DBC (even in the informal sense you describe) is minimal. Anyone with experience with both who can confirm or deny?
(no subject)
Date: 2009-05-29 02:02 pm (UTC)I mean, that seems so obviously sensible. Why would anyone do it the other way? Do they not know any people?
And then it occurred to me that this explains Windows perfectly. Light bulb!
(no subject)
Date: 2009-05-29 09:52 pm (UTC)The world would be a better place if this were the case, but alas, no; far too much software is written from the perspective of "Algorithm Foo provides an excellent solution to Problem Bar; let's implement it! Oh, I guess we'll have to slap a UI on it to turn it into a tool..."
I am being rather generic in my use of the term "user interface"; by this I mean "whatever the user of the software actually has to touch." For a web browser, a music player, an email application, &c, this is the GUI. For a library, it's the API ("application programming interface", or set of functions which the library makes available for you to use). For a command-line tool, like 'ftp' or 'cd' or 'wget' or whatever, it's the arguments and flags that the user includes when invoking the command, and any special magic about them (cf. my brainfart last week about the ordering of libraries in an 'ld' command). For a programming language, it's the syntax of the language itself.
Another reason for things being done in clunky ways is "well, it's what people are used to, we can't just go reinvent the wheel." For all that C is annoyingly difficult to read, for instance, it's the one programming language that every competent programmer is expected to know. As such, many languages are rather C-like in their syntax, because if you know C, then you can pick up $foo fairly quickly. Java may well be replacing C, given the way that schools teach their CS curricula these days, but apart from the object-orientation and the lack of pointers, Java owes a lot to C syntax-wise as well. It's like we just can't get rid of this legacy that we don't want.
Python port
Date: 2009-05-29 05:26 pm (UTC)Re: Python port
Date: 2009-05-29 09:42 pm (UTC)