Testing: i understand it, but i don't get it (fully)

OK, for my second project i decided that i was going to implement nit-
and functional testing.

I get the theory but i don’t get a good feeling with it.
The given examples are mostly very simple and i can’t think of a good
example of where a unit-or functional test can detect that some code is
broken.

Is there somebody out there who is convinced of the usability of testing
and who is willing to share some real-life examples of tests and perhaps
and example of a case where a test discovered broken code?

perhaps this would help me to fully understand it.

thanks

ok, i understand, but that is not unit/functional testing, which for me
is harder to grasp

koloa wrote:

try looking at something called zentest…

i still havent yet written any tests but as far as i can tell, having
your test automated will save soooo much time during development. for
example, i created a craiglist style site with a bunch of forms that
users can fill out. after that was complete, i found myself manually
filling out those forms with different kinds of data to test the
outcome. this is taking up alot of unnecessay time. now from what i
assume, having zen test will save me from doing this. i think that as
you code and make changes to those forms/code, zen will automatically
run tests that you create. in my case, filling out those forms and
making sure nothing breaks etc…

try looking at something called zentest…

i still havent yet written any tests but as far as i can tell, having
your test automated will save soooo much time during development. for
example, i created a craiglist style site with a bunch of forms that
users can fill out. after that was complete, i found myself manually
filling out those forms with different kinds of data to test the
outcome. this is taking up alot of unnecessay time. now from what i
assume, having zen test will save me from doing this. i think that as
you code and make changes to those forms/code, zen will automatically
run tests that you create. in my case, filling out those forms and
making sure nothing breaks etc…

newbee wrote:

OK, for my second project i decided that i was going to implement nit-
and functional testing.

I get the theory but i don’t get a good feeling with it.
The given examples are mostly very simple and i can’t think of a good
example of where a unit-or functional test can detect that some code is
broken.

Is there somebody out there who is convinced of the usability of testing
and who is willing to share some real-life examples of tests and perhaps
and example of a case where a test discovered broken code?

perhaps this would help me to fully understand it.

thanks

Hi,

Suppose I have this big app I build without testing.
I tested in the browser over and over again.
I am happy it works.
This is not trivial if youre app is big.

Imagine a new version of Rails comes along :slight_smile:
If I don’t freeze my app but want to test it with,
the latest Rails I have to do all that clicking
in the browser again to make sure it works in
rais version 1.2.x
Not a happy prospect.

If I would have written test for my app I could
now sit back and enjoy an espresso.

Now what do you test for example?
A user logs in with name and password
You want those two fields not blank so you write a test.
If that works you somehow want to keep that user in a session.
So you test that the user is in the session.

You can also expand that and make sure certain snippets
of html with their values are on an actual html page you expect.
All off this is testable.

Hopes this helps

One good example of where tests are useful is, as a previous person
mentioned, if you want to upgrade rails, or a plugin, or whatever. You
can feel fairly confident that nothing obvious has broken. Also in a
large app, you can have whole sections that remain unchanged for
significant periods of time and some edit in a loosely related model
will break it. While this can be partially avoided by decoupling
things, it is not completely unavoidable. Running a suite of tests will
let know you if you broke something besides what you were working on
directly. Several times I have had some obscure functionality break in
an app and I didn’t know for days until someone complained. If I had had
tests for it, I would have known right away.

Personally, I find unit tests to be rather tedious. I mean, testing
whether or not an object gets saved to the database or an associated
model gets updates seems fairly trivial. Functional tests are much more
useful, I think, because you are testing all the way through to the
model.

Still, i find it difficult to actually get myself to write tests even
though I know how good they can be. Especially if I have a deadline. It
can be fairly tedious and repetitive. I have to learn to think more
long term. I like to compare it to playing pool. With pool, you are at
first only concerned about getting the immediate shot. But once you get
better, you start planning one, two, or even more shots ahead. That is
what testing is. It is being confident enough in your immediate task to
think in terms of the quality of the whole product.

-matthew

Matthew I. wrote:

Personally, I find unit tests to be rather tedious. I mean, testing
whether or not an object gets saved to the database or an associated
model gets updates seems fairly trivial. Functional tests are much more
useful, I think, because you are testing all the way through to the
model.

Try writing the test first, and never write production code until you
can get a test to fail.

You don’t write ActiveRecord::Base#save, so don’t bother testing it.
Any logic your models provide (maybe logic that could be refactored
out of the controllers) gets new tests in the model.

Come to think of it, I don’t test before adding has_many or similar.
Maybe I should; the feature that needs the has_many should itself have
a test that will fail if its not there…


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!

newbee wrote:

I get the theory but i don’t get a good feeling with it.
The given examples are mostly very simple and i can’t think of a good
example of where a unit-or functional test can detect that some code is
broken.

thanks

Some things that unit and functional tests really help with:

  • if you’re working as part of a group, your tests sort of become your
    “contract” with the rest of the group. They can look at your tests to
    see how you expect your code to be used, and you can use your tests to
    make sure when you change something you haven’t broken your contract.

  • if you’re working as part of a group, THEIR tests sort of become their
    contract with you. If they change something, they will run their tests,
    and fix anything that is broken. If the tests cover every aspect of how
    your stuff relies on their stuff, you won’t ever get a nasty surprise.
    If your stuff isn’t working because their stuff smells bad, you can
    augment one of their tests in a reasonable way that shows that their
    stuff is broken…then just submit the test and send them a polite email
    explaining that you have added some stuff to the test and would they
    kindly get the test to pass by “changing” their code. In other words,
    the test change you make clearly explains what you need their code to
    do.

  • if you’re working on your own and you realize that a particular idiom
    is coming up over and over again, the right thing to do is to refactor
    your code such that the repeating stuff is written once and called from
    all over. In a large and complex app, the thought of doing that is very
    scary, and usually is sufficient to keep you from improving the app as
    you go. If you have complete tests for all the parts of the app
    affected by the change, you can rip it all up and refactor it the night
    before a major release…no problem; the tests will tell you when you
    have it all working again.

  • if you already have a full suite of tests, but some section of the app
    is behaving strangely, and simple debugging techniques have failed to
    find the problem, another approach is to write more tests for the things
    that section relies on. This can both help you spot the offender, and
    also rule out sections that are well tested.

  • if you’re doing agile development, and you’re getting near the end of
    the project and the client is coming up with lots of small tweaks here
    and there all over the app as you near the big day when the site goes
    live…rather than get nervous each time you mess with something that
    “used to work”, just rip and tear and make the changes requested…then
    run the tests. Whew, we’re going live tomorrow but I don’t have to
    “play with the app all night” to make sure I didn’t just break it.

That said…it is a difficult habit to get into. Once you get used to
developing this way, it starts to weigh on you the other direction. “oh
man, I’ve just made three changes in a row without updating my tests.
I’ve got to get some testing done so I can take a much needed sigh of
relief.” If it isn’t tested, it doesn’t work. That’s not just a
plattitude, it’s how you start to feel once you feel the warm peaceful
fealing of ripping up a bunch of important code and then running all of
your tests. Ahhh, all is right with the world.

One suggestion. Start small. Pick one important module in your app and
test the ever living crap out of it. Write dozens of little tiny tests,
each one takes just a few seconds. Together they add up to certainty.
Once you have that one module fully tested, then watch how you feel
about that module compared to the others. Sure, you love all of your
children, but that one starts to be “special”. Once you’ve noticed that
difference, you will understand.

jp

newbee wrote:

OK, for my second project i decided that i was going to implement nit-
and functional testing.

I get the theory but i don’t get a good feeling with it.
The given examples are mostly very simple and i can’t think of a good
example of where a unit-or functional test can detect that some code is
broken.

They don’t. You could easily write the wrong code that passes any one
of those tests. All the tests together, in conjunction with code that
is not sabotage, will keep your train … on the rails.

Is there somebody out there who is convinced of the usability of testing
and who is willing to share some real-life examples of tests and perhaps
and example of a case where a test discovered broken code?

Write the tests at the same time as you write the code. Run the tests
after every few edits. If they fail unexpectedly, revert the code back
to the last state where all tests passed, and try again.

I have reverted more times than I care to admit, and sometimes I did
not give a darn what code broke. Maybe the test was simply
hyperactive. This is still better than debugging!


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!

The easy way to “get it” is to think of those 3:00 AM phone calls -
“D— I should have written a test case.”

I can regression test one application in about 8 minutes, and know
immediately if it’s broken. Many of my colleagues depend on hours of
manual testing, and still miss things that they broke in fixing
something else.

The rule of thumb for retrofitting testcases into a project is “if
it’s a problem, write the testcase first, prove it fails, correct the
code, and prove it passes.”

Does this help?

One thing that has been indirectly mentioned above, but that I find a
great thing when doing Test Assisted Development, is that writing
tests forced me to strongly decouple my code.

Suddenly, not only could i easily test things, but i could change
application architecture, change implementations of methods, and all
the other beautiful things that go with decoupling.

Testing drove the design in a much better direction.

J

As others noted, tests can become trivial to the extent of being useless
(if
you get too deep, it’s like documentation. It’s always out of date).
Tests can be very useful, for things you know they can brake.

For example I have this admin page that only admins can see.
Writing a test for the simple user (a simple user must never see the
admin
page), will make sure I’ll never have uninvited guests.
Same thing goes for models that perform calculations, as for example a
complex financial calculator or something like that.
A rule of thumb would be “If it’s a show stopper or serious defect,
write a
test for it”.
TDD is great in general, but in early development if you dig deep with
tests, you’ll just waste time on things that will change later on. ( I
know
because I wasted one month on this)
(like the example tutorials mention where you test [if flash[:notice] ==
“Not this button, stupid”] as if you’re dead sure about the warning
message).

From my experience, it’s very easy to do something bad with just a typo
(like <% instead of <%= and the link is broken), and usually developers
don’t test anything else than the obvious.

G.

johnmshea wrote:

One thing that has been indirectly mentioned above, but that I find a
great thing when doing Test Assisted Development, is that writing
tests forced me to strongly decouple my code.

Suddenly, not only could i easily test things, but i could change
application architecture, change implementations of methods, and all
the other beautiful things that go with decoupling.

Testing drove the design in a much better direction.

That is one of the most powerful ways that proactive testing improves
quality.

There are only so many ways to say this: If each function in your
program had two different kinds of callers, the functions would
strongly decouple from each other. We no longer write deep and tangled
associations. The test cases provide the second kind of caller.


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!