|
Prev: Teaching OO
Next: multimethod + multiple inheritance
From: Water Cooler v2 on 27 Feb 2006 06:44 Here's my understanding as of now. If I were writing a function bool IsValidContact(Offerer objOfferer, Accepter objAccepter, TermsAndConditions objTermsAndConditions); Before writing the function, I'd enlist all the conditions that must be met for a contract to be valid. Something along the lines of: 1. There must be a valid offer made by an offerer; 2. There must be an unconditional, voluntary acceptance of the offer; 3. The offerer and accepter must be above the age of minority; 4. There must be a valid consideration (quid pro quo). Though there are many more conditions, for the sake of simplicity, let us stick to only the above four conditions. Going from the above four, I'd translate them into code precondition checks as follows: 1. Assert (objOfferer != null) 2. Assert (objAccepter.Acceptance.IsVoluntary() && objAccepter.Acceptance.IsUnconditional()) 3. Assert ((objOfferer.Age >= ObjLawOfMinority.MinimumAge) && ((objAccepter.Age >= ObjLawOfMinority.MinimumAge)) 4. Assert (objTermsAndConditions.Consideration.Value > 0) These four would be the basis of unit tests after writing code. In the implementation, I'd use Design By Contract (DBC) style assertion: if (objOfferer == null) return false; if (SomeOtherCondition Not Met) return false; Or I might use the straight-forward-one-return-path style design like, if (objOfferer) if (SomeOtherCondition Met) return true; After writing the implementation of the above function, I'd write unit test scripts to test each of the above conditions. These would be seperate functions that would call the function IsValidContract with invalid and valid values against each of the above four conditions we outlined. Now, let me in on some terminology. Which of the above are test cases and what is the unit tests here?
From: Laurent Bossavit on 27 Feb 2006 09:02 > Now, let me in on some terminology. Which of the above are test cases > and what is the unit tests here? You are coding a function returning boolean - a predicate. Your immediate concern is: "how do I know that the function is correct" ? A test case is a specification of inputs to and outputs from your function. If, when supplied these inputs, your function returns something other than the specified output, then the function is *incorrect*. A unit test is code that supplies the inputs, calls the function, and checks the result against the output specified by the test case. I think you are confused about preconditions. It is *not* a precondition on the isValidContract() function that the offerer should be an adult. Rather, it is the job of the function, when passed a parameter which denotes a minor, to return FALSE indicating that the contract is not, in fact, valid. If I was writing unit tests for this function, I'd probably come up with something along the following lines: void testIsValidContract() { // given these inputs... offerer = makeMajorOfferer(); acceptance = makeVoluntaryAcceptance(); terms = makeTermsWithValidConsideration(); accepter = makeMinorAccepter(acceptance); // ...should return false because accepter is a minor assertFalse( isValid( offerer, acceptance, terms) ); } (There would be many more such tests, to cover the different cases. How many tests depends on your approach to test design. The fewer tests you need to specify for equivalent guarantees of correctness, the better.) Laurent
From: Water Cooler v2 on 27 Feb 2006 09:47 Thanks for your diligent reply, Laurent. It has been very helpful and interesting. I think I follow you and believe that my understanding has been correct so far. What still intrigues me is: 1. What then, are pre-conditions? My initial assessment showed they were conditions to test inside the function's implementation, before the function returned valid input. If they're not that, what are they? 2. I understood the unit-test script you wrote called testIsValidContract. You tested it for one condition/validation, and as it concurs with my understanding, you imply that it must extend for all such validations. Fine. But what about test-cases. You said, they are a specification of what input the function gets and what it spits out. My question precisely is, "what is the format in which they are written?" Could you please produce a list of test-cases for this example we've taken? That would give me an outline. Thanks.
From: Daniel T. on 27 Feb 2006 10:22 In article <1141051642.754991.221520(a)u72g2000cwu.googlegroups.com>, "Water Cooler v2" <wtr_clr(a)yahoo.com> wrote: > Thanks for your diligent reply, Laurent. It has been very helpful and > interesting. > > > I think I follow you and believe that my understanding has been correct > so far. What still intrigues me is: > > 1. What then, are pre-conditions? > > My initial assessment showed they were conditions to test inside the > function's implementation, before the function returned valid input. If > they're not that, what are they? A pre-condition is something about the input such that, if the condition doesn't hold, the function's result is undefined. In other words, if the precondition doesn't hold, the function has no way of knowing what to return. There may be no preconditions in your function. To put it another way, preconditions are conditions that your function doesn't have to test, because they must hold *before* the function can be called. > 2. I understood the unit-test script you wrote called > testIsValidContract. You tested it for one condition/validation, and as > it concurs with my understanding, you imply that it must extend for all > such validations. Fine. But what about test-cases. You said, they are a > specification of what input the function gets and what it spits out. My > question precisely is, "what is the format in which they are written?" > Could you please produce a list of test-cases for this example we've > taken? That would give me an outline. The format for the unit tests depends on the language and test harness used, but they are written *outside* the function. A test case should create some input, call the function with that input, then test the output to see if it is correct. The tests can also be used by implementers of code that use your function as examples of proper use. -- Magic depends on tradition and belief. It does not welcome observation, nor does it profit by experiment. On the other hand, science is based on experience; it is open to correction by observation and experiment.
From: Laurent Bossavit on 27 Feb 2006 10:51
> My initial assessment showed they were conditions to test inside the > function's implementation, before the function returned valid input. That's right, as long as you're careful with the implications of that definition. Preconditions are conditions that must prevail for the function to have a meaningful result. If preconditions are not met upon entry, that means someone is using the function wrongly. In other words, someone wrote a bug, and the bug isn't inside the function. A major benefit of DbC in my opinion is that it makes it easier, in just that way, to reason about "where the bug is". A precondition violation implies a bug in the caller; a postcondition violation imples a bug in the function called. Thus, objOfferer != null is a precondition. It is incorrect to call the function with a null offerer. However, objTermsAndConditions.Consideration.Value > 0 cannot be a precondition, since you *expect* that the function will sometimes be called with terms that do not comply with this criterion. The point of writing the function is that it should tell you when that is the case, by returning FALSE. > But what about test-cases. You said, they are a > specification of what input the function gets and what it spits out. My > question precisely is, "what is the format in which they are written?" It depends. :) I'm a practitioner of Test-Driven Development. I write down test cases in the format of unit tests. So, the testIsValidContract function I sketched is both things: - a test case (it specifies inputs and outputs) - an executable unit test You can also write down test cases in some other format. On paper, or on the whiteboard (I do that on occasion), in Excel tables... The precise format depends on what it is you're coding. Laurent |