When/How to Unit Test CRUD applications?
I've been hearing alot about unit testing lately.
What I'm trying to understand is how would one / should one go about unit testing a cruddy business app? (basically an app that writes data in / reads dat开发者_StackOverflowa out of a database).
Is unit testing even worth it in that scenerio or do you usually unit test more complicated things?
Thanks
Unit testing is about testing discrete units of code - a single method, no more.
The moment you go into CRUD, you are talking about testing network, IO, database and other things - this is beyond what unit testing is about. In this case, this is called integration testing (you are testing how your code integrates with other code/systems).
There is place for both types of testing (and other types - regression, performance etc...) in any software project, CRUD application or not.
If all your application does is CRUD, then there is no point in unit testing it. Now, if there is any kind of business logic manipulating the values as they come out of the db or validating them before them going in, yes, it is a good idea to build unit tests. Testing the CRUD part does not belong in unit testing IMO.
I know everybody goes on and on about how you should be test-first designing everything, but I tend to stick with unit testing more complicated things.
My rule of thumb is that I build automated tests for things that I actually expect to break with reguarlity, or things that I won't immediately notice are broken. And most of all, I want it to test things that I can't/won't thoroughy re-test myself.
For example, the "Calculate some big complicated thing using 47 different variables" module should have a bunch of tests that accomplish good code coverage and shoudl cover all possible code paths, but the code that actaully saves that result back to the database doesn't necessarily need a test, especially if it's doing simple CRUD work.
Also, I like to use automated UI tests (using WatiN or something similar) to build out regression tests for my sites, so that when I change some core components I can run a sanity check to make sure I didn't blow up some obsure corner of the site.
In the end, it's all about ROI. How much time are you putting into this, and how much are you getting out of it. If your unit tests are approaching 100% code coverage on some dumb data access layer of your CRUDy business app, you are wasting your time and your employer's money, plain and simple. But if you're building rocketships or medical devices or if you are a two-main shop that doesn't have the resources for a QA department, a lot of unit testing can save you a lot of time, money, and/or lives.
Cruddy apps seldomly stay cruddy. They eventually grow to include a business object layer.
So, yes, I would do unit testing. Even a basic cruddy app should be split into an interaction layer, a data access layer, and the incredibly simple UI (note that all UI state should be kept in the interaction layer). Eventually, you'll probably get a business object layer in-between the interaction and data access layers.
Test everything that could possibly break.
Of course you need to test your CRUD operations especially if you have data-oriented application. And from my expirience such kind of tests are very usefull tests, because they can caught lots of bugs in mappings, stored procedure logic, mistakes in data model, wrong data etc.
Unit testing is about testing SMALL simple bits of functionality. Usually you'd unit test the data layer of your application which would handle all the CRUD functionality. A test for an Create and Retrieve might look like this:
PrimaryKey = InsertObject(TestObject)
if PrimaryKey = 0 then
AssertTestFailed("Primary Key Not Returned.")
end if
NewInstanceOfObject = GetObject(PrimaryKey)
If NewInstanceOfObject <> TestObject then
AssertTestFailed("Record not located.")
else
AssertTestPassed("This Code is awesome UnitTest Passed.")
end if
CRUDdy apps are difficult to unit test, as @oded wrote: you usually do integration tests on these kinds of apps.
But, if you properly layer your code, you could isolate the business logic and unit test that.
For example, if you use the "clean architecture", then your api will be split into:
- handlers/controllers (which are the pieces of code that are activated by the routing component)
- services (which are the business logic component) that are injected to the handlers
- repositories (which are responsible for data access) that are injected in turn to the services.
In this structure, you can easily mock the repositories (which are the only part that handle state) and unit test the services.
The handlers themselves shouldn't contain any logic (they just validate input, pass it to the service, and display the response) and so would probably not be unit tested.
Hope that helps :-)
What I believe is that if you are using an ORM that is well tested by its community and follows a well defined pattern to implement CRUD operations then its of no use to write unit tests for that.
But, if you are using some low-level library to communicate with the database, then chances of error are high. In that case I myself write unit tests to make my code rigid and error proof. And writing these tests don't take a lot of time since it follows the same pattern for all classes.
There is a vast number of different Databases and their accompanying ORMs on web but things are limited on mobile platforms. And it rightly is since storing the data on mobile is not a very good idea but there are instances when you have to. When writing CRUDs on mobile platform, I write unit tests.
精彩评论