1 / 22

QuickCheck@Neilfest (or what I learned from Neil about software testing)

QuickCheck@Neilfest (or what I learned from Neil about software testing). John Hughes Chalmers University/Quviq AB. Company founded May 2006 Tools for testing software Profitable in the first year ! Customers include …. Soon TBA. QuickCheck.

kirkan
Download Presentation

QuickCheck@Neilfest (or what I learned from Neil about software testing)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. QuickCheck@Neilfest(or what I learned from Neil about software testing) John Hughes Chalmers University/Quviq AB

  2. Company founded May 2006 • Tools for testing software • Profitable in the first year! • Customersinclude… Soon TBA

  3. QuickCheck • Tests software automaticallyagainst a formal specification prop_reverse() -> ?FORALL({Xs,Ys}, {list(int()),list(int())}, reverse(Xs++Ys) == reverse(Xs)++reverse(Ys)).

  4. Testing… 19> eqc:quickcheck(ex:prop_reverse()). .........Failed! After 10 tests. {[2],[3,2]} Shrinking....(4 times) {[0],[1]} false

  5. QuickCheck • Tests software automaticallyagainst a formal specification prop_reverse() -> ?FORALL({Xs,Ys}, {list(int()),list(int())}, reverse(Xs++Ys) == reverse(Xs)++reverse(Ys)).

  6. QuickCheck in Brief Specification Test case Test outcome Generate Execute Simplify Minimal counter-example e.g. {[0],[1]}

  7. A MoreRealistic Test Case • A test case for the Erlang process registry test_register() -> Pid = spawn(), register(name,Pid), Pid2 = whereis(name), assert(Pid==Pid2), unregister(name). Spawn a new process (set up test data) Register it—a side-effect Inspect the results Did the test pass? Restore the state, ready for next test

  8. Industrial Test Cases • A sequence of • Calls to an API under test • Checks on the results • Not much like {[0],[1]}… • Howcanweconvert this kind of test caseinto a logicalproperty?

  9. QuickCheck in Industry Specification Test case: a program Test outcome Generate Execute Simplify Minimal program provoking a fault

  10. Programs as Data Objects • Why? • So failing test casescan be printed • So failing test casescan be repeated • So failing test casescan be simplified

  11. Can wemix generation and execution? • Randomlygenerateand performeachcall • Save a test case as a list of functions and actual parameters? • NO!!! • Whenwerepeat the test, Pid has a different value • Wemustuse a symbolic variable! test_register() -> Pid = spawn(), register(name,Pid),…

  12. Test Case Language • Do weneedconditionals? • Tests should be deterministic • Check the right branch, don’t test • Usersneedsimplicity—straight-linecode is simple, and suffices X = foo(…), casep(X) of true -> baz(X); false -> bar(X) end X = foo(…), assert not(p(X)), bar(X)

  13. Generating Test Cases • Howdoweknow • Whichcommands are valid at eachpoint? • What test data is available at eachpoint? • Whatresults are expected? • Track a test casestate • Check preconditionsbeforegeneratingeachcommand • Store available data in the state • Check postconditionswrt test casestate

  14. Process Registry State Available process ids typestate() = record pids::list(pid()), regs::list({atom(),pid()}) end. Currentlyregisteredprocesses

  15. Process Registry State • Two-level programs! • Static = test case generation time • Dynamic = test execution time Available process ids typestate() = record pids::list(symbolic(pid())), regs::list({atom(),symbolic(pid())}) end. Currentlyregisteredprocesses

  16. Two-level State Machines • Preconditions • Checkedduring generation, purelystatic • Postconditions • Checkedduringexecution, purelydynamic • Nextstatefunction • Used at bothtimes, two-level • Command generator • Usedduring generation, two-level

  17. Process Registry • spawn() • Adds a (dynamic) pid to the state • unregister(Name) • Pre:Name must be registered • RemovesName from the state • register(Name,Pid) • Adds {Name,Pid} to the state • Post:exceptionifName or Pidalreadyregistered

  18. A Failing Test Case [{set,{var,2},{call,…,spawn,[]}}, {set,{var,3},{call,…,register,[a,{var,2}]}}, {set,{var,6},{call,…,register,[b,{var,2}]}}, {set,{var,8},{call,…,spawn,[]}}, {set,{var,9},{call,…,register,[b,{var,8}]}}] V2=spawn(), register(a,V2), register(b,V2), V8=spawn(), register(b,V8) Code Spec Inconsistency!

  19. A BuggySpec • spawn() • Adds a (dynamic) pid to the state • unregister(Name) • Pre: must be registered • RemovesName from the state • register(Name,Pid) • Adds {Name,Pid} to the state • Post:exceptionifName or Pidalreadyregistered …providedthere is no exception!

  20. ”The Trick” • Whatifweknow part of the structure? • Check the known part in the postcondition • Add the known part statically to the state • ”The Trick” is as useful as ever! Added to the state Purelydynamic [{set,{var,2},{call,…,spawn,[]}}, …]

  21. Test Case Generator Two-levellanguages are helping to findthornybugs in industrial systems! RandomizedGenerating Extension =

  22. Best Bug! • In Ericsson’s Media Proxy (Multimedia IP-telephonyproduct, SIP) • A seriousbug • Obtained from a simple specification, by simplifying 160-command sequence! Add Add Sub Add Sub Add Sub

More Related