CSC323 2010S, Class 21: Testing, Revisited Overview: * Models of Testing. * Dealing with Preconditions. * Programming-by-Contract. * Defensive Programming. * Talk about the Project. * An Alternative Activity. * EC for Student 1's and Student 2's (and two other people's) talk at 4:30 on Thursday Admin: * One more chapter of HFOOAD! (Due Thursday.) * So, what did you think of the great effort imparted on the minor joke? * Buy one get one free EBook sale at ORA until April 30. Code BYEBK. * So, why do you think folks are still printing to Escher? Models of Testing * Philosophic stuff * Unit testing * Functional vs. scenario-based testing * Very basic tests: Make sure the system is sane * Should programmers write their own tests, or should someone else write them? * Testing frameworks * Automatic! * Result: A list of how many tests succeeded, how many tests failed (and, perhaps, where) * Manual substitution for a unit testing framework * Input expression and expected result * Output: A list of successes and failures * In pages 458-459, just "Name of test: Success/Failure" * Static exploratory testing: Run the code and see the output * Dynamic exploratory testing: Run the code in an interactive environment and see the output Why use different testing methods? * The result of one test might affect which other tests you do (Why not just do them all?) * Why use your own testing "framework" rather than a standard testing framework? * Gives easier to read results to the customer. "Look, this output here says that the Frob method worked!" Testing frob method: OK Testing bar method: Sorry, didn't work * The testing framework may limit you in some way (that we cannot envision) * E.g., "Any of these results is okay" * Overhead of learning a unit testing framework * Ability to customize output * Why use static exploratory testing? * Potentially nicer for the client. Look, it's doing *this*. * Can give you more information on the way that a test failed. * When you can't write good unit tests to simulate interactions of different parts. * (Do such times exist?) * Can be a bit easier to do, particularly if you want to incorporate randomness. * Why use dynamic exploratory testing? * Lets you do some quick planning of what you expect it to do. * Lets you probe related things about the state of things. * Useful for exploration when a test case fails. * Quick and dirty testing during development. * Demo for the clients. * Sam recommends: * Dynamic exploratory testing during early development * Unit testing in a framework soon thereafter --- Every procedure and operation has preconditions (explicit or implicit) * hashtable.lookup(key) * key is a valid key type and is not null * in many designs, key must be in the hash table * hashtable is not null * a+b (assuming + means numeric addition and not one of those stupid overloaded uses) * a and b are both numbers (of compatible types) * a and b must both be declared * the sum must not be greater than the largest representable number in the common type * Who is responsible for checking preconditions? * the client * the library * No one? * What happens if preconditions are not met? * The library returns a special value to say "the preconditions are not met" * The library is doing the checking * Let it crash * The client should be doing the checking * Leave the result undefined * The client should be doing the checking * Throw an exception * The library is doing the checking Design-by-Contract (®) or Programming-by-Contract * The documentation for the procedure is a contract between client and library * If the client does not meet the preconditions, the library can do whatever it wants. * If the client does meet the preconditions, the library must meet the postconditions (and invariants) Defensive Programming * "Everyone" is responsible for checking preconditions (and results) because you Exceptions vs. Special Return Values * Java's model: * Libraries check many preconditions * Exceptions force the client to deal with problems * A reaction to C. int main (int argc, char **argv) { int i; FILE *outfile = fopen ("/tmp/params", "w"); if (outfile == NULL) { fprintf (stderr, "Can not open file /tmp/params\n"); exit (1); } for (i = 0; i < argc; i++) { if (fprintf (outfile, "%d: %s\n", i, argv[i]) < 0) { fprintf (stderr, "Agh! Unable to write to /tmp/params\n"); exit (1); } } fclose (outfile); exit (0); } /* main */ * Why use design-by-contract (®)? * Encourages better documentation * More efficient, less code to write * Shows trust in those using you code * The library chooses this model * Why use defensive programming? * You may not be able to trust the people who are using your code, or whose code you are using. * If you can't afford the risk of a program crashing. (But it still will crash, perhaps at another point.) * If you want to deal carefully with different kinds of errors. * The library you use chooses this model In our project, we will design by contract. * Which should we use? List of questions on the project * Uh...we ditched CompoundWorld. Hope that is okay.... * Was it "ditched" or did no one take responsibility for it? * It's complicated. * So it's a feature that we might add later (or not) * What interfaces is the GUI team planning on using? That is, what calls do you expect to make to the World and what calls do you expect the World to make to a WorldListener? * World methods * construct (int width, int height) ; provide positive width and height and not so big that it crashes * setSpecies (Position pos, Species species) ; might be disallowed throws Exception * Species getSpecies (Position pos) * step () * WorldListener methods * changed (Position pos) * changedTo (Position pos, Species newSpecies) * worldUpdated() - means "enough changed that you might as well query for everything" * message (String) - print this message * GUI question: When do the changes get sent to the world? All at once, or individually? * To support multiplayer, it makes sense to send them individually. * Adding pieces. How? * To be added later? * What interfaces is the model planning on using? (How does the network tell the model to do things or vice versa?) * See above * Do we pull from the model or does it push to us? * See above * Does the model send notification that it is updated, or do we tell it to step and do more things later? * See above * We need to talk through, as a class, how dataflow is going to work? * See above * Not worth discussing as a class * How do we properly close sockets? There has to be a better way than crashing the server. * Yes We tried having the client close the socket and reselecting, but that doesn't work. * Vague Alternative options to explore? * Yes Dumb ones (that will probably work better)? * Almost anything * We didn't really plan on implementing a chat thing until we saw one in the GUI notes and thought it seemed like a good training exercise. What other hidden features do we need to implement, if any? * Leave chat as a separate exercise * "Identify hidden features" is a good hidden feature to implement. * Can you (SamR) tell us what you think of our use cases? (available at designers/network/use-cases.notes) * They could use improvement * And I can't find them * And why are you using Lotus Notesotes? (Don't make up extensions.) * Can we work with the model team on implementing NetworldListener? We can tell you what we would like the interface to look like. * What is MVC doing? In our interpretation it is: Model = model Controller = Network/GUI View = GUI * It took us a significant portion of 9 hours to figure out how to use sockets. How are our successors going to do this efficiently? * Two of you are going to teach them. * What else should we know? * Next * How many boards are we handling through the network? * Just one shared board right now. * What happens at the edges of the board? * Is it a toroid? * Is there a void? (Not the type.) * Can the board grow? * Vote: It's a toroid! * How are we going to switch teams? in Week 11 * Two people stay on the team * Two people move to other teams * And the next week? (week 12) * The two new people stay, the two other people move * And the next week? (week 13) * The two new people stay, the two other people move * And the next week? * We're done! We'll figure out whether or not you're presenting