开发者

Understanding unit testing

开发者 https://www.devze.com 2023-03-16 03:08 出处:网络
I\'m trying to understand how unit testing works. So far i understand you\'re testing the output of functions based on what you put in. Ok. Does that mean if your function has the only possibility of

I'm trying to understand how unit testing works. So far i understand you're testing the output of functions based on what you put in. Ok. Does that mean if your function has the only possibility of returning one datatype you only have to write one test for it? So say i write a function that only has the possibility of returning TRUE or FALSE, does that mean i would just be checking if the response is boolean?

And then also say i have a function that is pulling posts from a blog from a database. Say have the function set to: if number of rows = 0 return FALSE, else return the results. So i now i have the possibility of a function that could return a boolean value or an array. Ho开发者_如何学Gow the heck do you test that? The function now doesn't rely solely on the input, it relies on what's in the database.


A useful function does not return true or false randomly. It returns true under certain circumstances and false under other circumstances.

A unit test would therefore do three things (in that order):

  1. Create an environment from which you know whether the function should return true or false (this environment is called the test fixture).
  2. Run the function that is to be tested.
  3. Compare the result of the function with you expectations.

Obviously this cannot be done with all possible inputs (if it could be done, this would be a proof, not a test), so the art of unit testing is choosing appropriate test fixtures. There are two ways to go about this:

  • Black box testing looks at the specification of the function to choose the fixtures: what are the valid input values and how should they influence the output?
  • White box testing looks into the function and chooses fixtures such that every statement of the function is executed by at least one fixture.

... if number of rows = 0 return FALSE, else return the results.

If such a function directly sends a query to a database server by calling an API of the DBMS (e.g. mysql_query), the creation of the test fixture would include

  1. Setting up a database.
  2. Inserting rows into the database (or not, depending on whether the test should check that the results are returned properly or FALSE is returned properly).

If, on the other hand, that function calls a custom function (e.g. provided by an object-relational mapper), then the test fixture should provide a mock implementation of that custom function. Dependency injection helps to ensure lose coupling of caller and callee, so the real implementation can be replaced with the mock implementation at runtime.


You have the gist of it about right. If there are external depecnencies for the unit there are two approaches. creating a Mock class or using some kind of fixture.

Using your DB example if youre testing a class that has to call on a data access class to pull data from the database then you would typically Mock that data access class, making the methods you plan on calling from it return the response you expect.

If on the other hand you were actually testing the data access class itself then you would use a fixture - a test db filled with data you know. And then test that the data access class returned the right data.


I think you need to do a bit of reading about unit testing. To answer your first question about the cases you should test, I suggest you read up on Boundary-Value testing and equivalence partitioning. in your case, yes you assert that the output is true or false, but are there multiple pre-conditions that can lead to the same result? If so, these need testing.

Regarding your second question where the return value depends on the database. This is strictly not a unit test (i.e. it involves multiple units). I suggest you spend some time reading about mock objects.


Unit testing just means that you're getting the outputs you expect. Write a test for every conceivable, unique state your program could be in and ensure the output of your function is what you expect.

For example, you could test in the case that your database is empty, a few rows, or full.

Then for each state, give different inputs (a couple invalid, a couple valid).

Unit testing just breaks up your programs into units and makes sure each unit works as expected.

EDIT:

Wikipedia has a great article on unit testing.


For unit testing you are trying to isolate and test certain pieces of code. You do this by providing the inputs such that you know what the answer should be if the code is working properly. If you are testing whether a function returns a boolean correctly then you need to provide inputs that you know will evaluate to say "false", then check to ensure that the function did indeed return "false". You will also want to write a test that should evaluate to "true". In fact, write as many tests with as many different inputs as you like until you are convinced that the function is working as expected.

There seems to be mixed opinions when it comes to unit testing with a database. Some argue that if you are using a database that you are performing integration testing. Regardless, for a unit test you should know what the input is and know what the expected answer should be. Your explanation of what you want to test doesn't align with what unit testing is really for. Once suggestion would be to create a test database that always contains the same data each time you run the unit test. This way you always know what the input is and know what the output should be. You could accomplish this by creating an in-memory database such as Hypersonic.

Hope this helps!


If you allow me a suggestion, take this book: THE ART OF UNIT TESTING, by Roy Osherove. http://amzn.com/1933988274. It's not a huge weapon-massive-like book.

I had never read anything about UnitTesting prior to this book, but now it's very clear how UnitTest works.

Hope it helps!


I should point out that unit testing is not just about what results your functions give out; it's also about how they mutate / impact other objects, as well. In a sense, they test what messages are passed between objects.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号