When I have been writing testing code, I have let the data be saved to the db. I know that this goes against the idea in unit testing that you test should have no side effects. And frameworks that have testing built in like RoR or Spring help make sure that your work doesn't have any side effects by rolling back the transaction when the test is done.
This helps make it so that your tests can run in any order, etc., but I don't really like that. Why? Because I have found more bugs with leaving data in the db than clearing it out all the time. My test data has some randomness to it (another no-no), but it helps show bugs. Like what happens if you have a first name in all CAPITALS? CamelCase? lowercase? What about accents?
Another benifit I have seen is when I use reflection to "fill" out a java object, save it, and then display it to the UI. I can find cut and paste errors of the html (struts) form fields or where you are displaying this data. This comes from the fact that I hate manual testing, espically creating the data.... I can't help it, I'm lazy. If I've already set up my test suite to create "valid" data, why can't I leverage that functionality? Maybe I can, but I don't see how to yet.
I'll post if I do find out how to do it. ;-)
It's true that RoR rolls back the database after the unit test method is finished BUT it doesn't roll it back to empty, it rolls it back to a known state full of data defined in your Rails "fixtures" (written in YAML).
ReplyDeleteSo you could easily define a database full of test data fixtures (like CAPITALS, CamelCase, lowercase, accents) and then run your test methods over it.
You can also use Ruby in the fixture code to generate ordered fixtures, or random fixtures, or fixtures based on today's date. There are lots of possibilities.
What I don't like about the dbUnit and (my first look at) Rails was that I would have to define my whole db state ahead of time. I prefer to put the data into the objects, and have that take care of where it gets put into the db.
ReplyDelete... maybe I have just gotten used to how I do it, doing it the "wrong" way. I'd be cool with Rails as long as I can (in some way) put in realistic data without having to keep on updating my test script.
To provide an example: I have a class that has Strings in it. I reflexivly fill out that object and I have a reflexive .equals hashcode and toString as well. When I update the model then my tests show that I can not getting the correct data back. Update the mapping, and now everything is all hooked in together. I have valid test data, and I don't have to update a test populate script as well. And I can view that data to see if it's populating the correct fields.
This couplies the read / write of the db, but I'm okay with that.
Reflection in Ruby is no problem. In fact, it's free -- no performance penalties. You can "reflexibly" create test fixture objects too.
ReplyDelete