unit tests == ugly code?

J

Joe Van Dyk

I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.

Joe
 
J

Jim McMaster

I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next test.

In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.

Joe

As soon as the code passes the test, you should look for opportunities to
make your code better. Failing to do so is an option, but you should
recognize you are piling up a "technical debt" if you choose it. This debt
ultimately will cause you grief, just as piling up debt on a credit card
without paying will eventually cause you financial grief.
 
E

Eero Saynatkari

Joe said:
I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.

This is the whole 'design after' or 'refactoring' paradigm:
make it work, then implement a proper design and prettify.
Passing unit tests prove that nothing was broken :)


E
 
N

Nicholas Van Weerdenburg

------=_Part_28328_31625671.1135211465829
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

That's interesting.

On of the TDD pitches is that the tests present a constant design pressure
on the code encouraging refactoring as you go, the theory being bad code
isn't so testable.

My experience is limited, but I find this mostly true, and it helps me name
things since I'm writing code to a much clearer context then if I'm just
coding "in the wild" so to speak.

e.g.

def test_list_archived_articles
a=3DArticle.find_by_status "old"
# test here
end

My test to check if my list articles works shows some strange semantics, an=
d
I rewrite as:

def test_list_archived_articles
articles =3D Article.get_archived
# test here
end

and I update Article to encapsulate how archiving is implemented.

If you are writing tests and not refactoring, I think you are missing a mai=
n
point of TDD- design rather then QA.

Also, without the refactoring, your tests would likely become stranger as
your project gets bigger, getting to the point where you can't figure out
how to effectively test new features.

At least that's the theory.

Regards,
Nick

I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.

Joe

------=_Part_28328_31625671.1135211465829--
 
P

Patrick Gundlach

I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

How many tests/day do 'you' pass? ;-)
In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me?

Pretty much the opposite. When I do TDD, I am very careful about the
code I write. I work hard that my tests look good (so that I can see
what I meant when writing it) and robust. And I program so I can test
(less monolithic etc.). I should do *much* more TDD.

Patrick
 
D

Devin Mullins

Joe said:
I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.
Actually, my biggest problem for a long time was ugly *tests* (mostly
from a desire to mock _everything_, and never to inject), but I'm
getting better at that. No, you're going to have to stop, look at your
code, and say, "Is this readable? If not, how can I make it readable?"
Having passing tests will give you more freedom to do so, hopefully.

Devin
 
A

Adam Sroka

Joe said:
I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

In practice, this means that I'm using a lot of ugly regex's, poorly
named variables, and so on. I'd be more concerned about the
readability of the code if there wasn't unit tests behind it. I'm
generally in a rush to finish whatever I'm doing, and figure that
since I have a bunch of tests, refactoring stuff later won't be a big
deal.

Anyone else out there like me? Or should I be anal about writing good
code even with the tests? I guess that would be ideal, but I'd rather
get the functionality done first.

Joe
You have to remember that TDD was popularized by eXtreme Programming,
where it is combined with several other practices. There are few that
really help. First, continuous integration ensures that all your tests
are run frequently. Collective code ownership ensures that others on the
team get to smell your funky code (And give you a hard time about it.)
But, there are two that are really key: Merciless refactoring means that
any time there is an opportunity to improve your code you take it. And,
pair programming means that there is another person sitting next to you
who is able to slap you silly when you code badly. You can do TDD
without these other practices, but I'd advise that doing it without at
least doing merciless refactoring and continuous integration is a little
silly (But better than nothing.) Finally, if your code sucks you have no
one to blame but yourself, and it's certainly not TDD's fault :p
 
S

Steve Litt

This is the whole 'design after' or 'refactoring' paradigm:
make it work, then implement a proper design and prettify.
Passing unit tests prove that nothing was broken :)

I cannot in a million years imagine coding without design. I've
never coded tests first (I test each class after coding it), but I
can't imagine why writing the tests first would make one not
design. If it did make me not design, I wouldn't code test first --
I'd make test jigs after.

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 
J

James Britt

Steve said:
I cannot in a million years imagine coding without design. I've
never coded tests first (I test each class after coding it), but I
can't imagine why writing the tests first would make one not
design. If it did make me not design, I wouldn't code test first --
I'd make test jigs after.

I tend to sketch first, doodling out the initial pass at an app, trying
out stuff to test the waters and see if something that popped into my
head is [not as hard|as hard|much harder] than I thought it might be.

A lot of what I do is driven by a "Hmm, I wonder what *this* button does
..." mentality, and test-first can interfere with the interesting
accidents and failures.

But as apps grow, they can get gnarly, and unless the app is a toss-off
(though how can you tell?) I'll then go and rewrite it, but this time
using unit tests to avoid the nasty bits. And by that point I likely
have some general design to guide me.

James
--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools
 
B

Bil Kleb

Joe said:
I've found that when I write the tests first, and then write the code,
I'm not very concerned about what the code looks like. When the code
passes the test, I drink a beer and party, then move on to the next
test.

You've got the order right, you've just forgotten
the third step, and most important step to ensure
agility: refactor. The rhythm is Red-Green-Refactor.

Regards,
 
J

Joe Van Dyk

I cannot in a million years imagine coding without design. I've
never coded tests first (I test each class after coding it), but I
can't imagine why writing the tests first would make one not
design. If it did make me not design, I wouldn't code test first --
I'd make test jigs after.

Oh, I spend a lot of time on class designs (and how the various
objects interact with each other). I tend to follow the 'tracer
bullet' philosphy outline in the pragprog books.

It's just that, within the beautifully designed functions and classes,
lies unspeakable monsters. (ok, maybe not that bad)
 
J

John Wilger

I cannot in a million years imagine coding without design.

Neither can I -- which is precisely why I never write my classes
before my tests. Writing a class is _not_ design; that's called
"programming by intention". Figuring out what you need a class to do,
and then specifying the API is design. This is (part of) what the
tests do. They give you a chance to work with the interface as a
_client_ of that interface to see how things fit together _before_ you
commit yourself to the implimentaiton.
I've
never coded tests first (I test each class after coding it), but I
can't imagine why writing the tests first would make one not
design. If it did make me not design, I wouldn't code test first --
I'd make test jigs after.

--
Regards,
John Wilger
http://johnwilger.com

-----------
Alice came to a fork in the road. "Which road do I take?" she asked.
"Where do you want to go?" responded the Cheshire cat.
"I don't know," Alice answered.
"Then," said the cat, "it doesn't matter."
- Lewis Carrol, Alice in Wonderland
 
S

Steve Litt

Neither can I -- which is precisely why I never write my classes
before my tests. Writing a class is _not_ design; that's called
"programming by intention". Figuring out what you need a class to
do, and then specifying the API is design. This is (part of) what
the tests do. They give you a chance to work with the interface
as a _client_ of that interface to see how things fit together
_before_ you commit yourself to the implimentaiton.

Hi John,

How does coding your tests first affect your enjoyment of coding?

If you find out later that your (interface, not implementation)
design for a class wasn't exactly right, do you then recode your
tests first and then recode your class?

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top