Hi, all. Thanks for your indulgence in my badly-timed lightning talk at tonight's RUM meeting. Included below is a summary of what I managed to talk about and what got left behind by the Klaxon of Doom. If you think there's enough here for a longer talk, please email me so I can ponder making a proposal for a talk early next year. -Scott --- snip --- snip --- snip --- snip --- snip --- Abstract: It's time to start thinking very differently about code testing. If QuickCheck in Erlang can reduce a traditional 20-40 week testing job down to 2 weeks by a single person and find more bugs than the traditional way, that's seriously cool. But QuickCheck is also available for Ruby, so what are RubyMN attendees waiting for? The Ruby-flavored QuickCheck library that I mentioned at the beginning of the talk. From what I see, it has all of the components of basic QuickCheck. https://github.com/hayeah/rantly QuickCheck was first implemented in Haskell. See this article at Wikipedia for some links to QuickCheck in a whole bunch of languages. http://en.wikipedia.org/wiki/Quickcheck The idea behind QuickCheck is that your test defines a property, something that should always be true. (Or always be false.) QuickCheck will provide random data generators to create the test cases for you: run the model 100 times, 5,000 times, the computation is free. As a simple example, to test an arithmetic library, you want to test commutativity. In English: For all integers A & B, A + B = B + A. I'm extremely familiar with the Erlang version of QuickCheck, please forgive me, but it's really easy to write this commutativity property in Erlang using this syntax, really: ?FORALL({A, B}, {integer(), integer()}, my_library:plus(A, B) == my_library:plus(B, A)). That's all. Let the computer do all the work. Using the Ruby "rantly" library via IRB: >> gen.map(5) { a = integer ; b = integer ; a + b == b + a } => [true, true, true, true, true] My Ruby is rusty enough that making a more polished example to match the Erlang example would embarrass me ... but just to make certain that a & b are being set to random numbers: >> gen.map(5) { a = integer(50) ; b = integer(50) ; print a, " ", b, "\n" ; a + b == b + a } 29 27 -41 17 -12 -28 25 32 10 15 => [true, true, true, true, true] OK, back to my lightning talk. I showed 2 slides from a European Union-sponsored study on using QuickCheck to test the C code from a real-time embedded Linux automotive control computer. See slides 24 & 26 of Thomas Arts's talk at: http://www.erlang-factory.com/upload/presentations/293/EUC2010-Automotive.pdf The two weeks for the Erlang test covered the entire finite state machine (FSM) for the communication protocol, implemented by a master's CompSci student, that found several "issues"(*) with the specification that weren't found by the 20 weeks (plus 20 weeks of report writing) using traditional testing techniques. (*) According to Thomas, cars **do not** have "problems" and certainly don't have "bugs". They have "issues". If you have the time, it's worth reading all the slides. If you have C code that you need to test, it might give you some ideas of how to test it from a different angle.... On to Sam Rivas's talk, see the slides at: http://www.erlang-factory.com/upload/presentations/305/property_based_testing.pdf Sam's point is that most of us write unit tests, and most of those unit tests check for things that should not fail. But that is *not* enough, see the small case study in his slides. 100% code coverage by unit tests wasn't sufficient. But a property-based test, testing what *should work*, easily catches the case study bug. The template system (aka text substitution system) should look familiar to most Web-centric developers, whether you like them or not. The template system that Sam talks about has been in service for years, has an extensive unit test suite that exercises 100% of all lines of code. 100% code coverage == no bugs? No. When the "@@" feature was added, and new unit tests added, all tests passed, and 100% code coverage was still measured. But a serious bug slipped through the system and pissed off the customer (see atom bomb slide). All of the examples are in Erlang, but really the unit test examples are really just slightly different syntax that fits the basic xUnit-style test paradigm that's now ported to a dozen different languages. The QuickCheck examples are actual Erlang code, verbatim. Using the "rantly" library for Ruby would only take a few more lines of code. My summary: QuickCheck is available for Ruby, so what are RubyMN attendees waiting for?