From: benny Date: 2006-03-21T07:38:51+09:00 Subject: [ANN] lazytest 0.1.0 Benny is happy to announce his second published piece of software: "lazytest" available as gem. You may wonder what happened to my first gem, "FaceToFace". There will be an update in the near future.... Dear list, I hope this is useful for someone and I am curious what you think about it. The code itself is no big deal and always open for improvements (as my english is). == Overview lazytest allows you to do quick and easy testing and benchmarking of your library while developing it I found the available solutions for unit tests too laborious and wanted to be able to the testing directly where I program and independantly from a certain directory strucure. I also wanted to be able to test alternativ implementations and benchmark them to be able to get the best and fastest solution. So the idea came up to create a something that could be included to do the tests but that only would run the tests when the file is called from the shell. If it is included no test should be run. The second idea was to have the tests been written in the DATA area of the file (everything after '__END__' ) in YAML format to be easy and readable. == Example of Usage To use it your file should look like this: #!/usr/local/bin/ruby require 'rubygems' require_gem 'lazytest' # Here: stuff that is not needed for the test prepare_tests() # Here: definitions of the classes that should be tested run_tests() __END__ You might also pass a block to prepare_tests() that will only be executed when running a test. The Classes you define between the calls of __prepare_tests__ and __run_tests__ will be automagically detected. === Setting up the tests After '__END__' you write your tests in YAML style. It is a YAML hash where the key is the class name with the initialization code (here: Array.new(4)) and the value is a hash of methods (e.g. empty?) and their expected results (e.g. %s == true). __END__ Array.new(4): empty?: %s == true class: %s.name == "Array" dipsy: %s == NoMethodError size: - %s == 4 - %s != 0 - %s > 3 Please note that YAML identation is two spaces for each level! When running the tests the methods is applied on the created object and the result is placed inside the expected result where you placed the '%s'. The expected result is ruby code that should evaluate to 'true'. Tests that return false/nil are assumed to be failed. That's all! Simple, isn't it? You can even omit the '.new()' if your Class doesnt need parameters for initialization. If you want to disable a test, simply place a '#' at the beginning of the line === Running the tests Simply call the file from the shell, either like this: ./my_lib.rb test or if it is not executable: ruby my_lib.rb test You will get a summary of the test results and more verbose information about failed tests and errors. If you pass the option '-v' you will also see the verbose information about the tests that passed. To get help: ./my_lib.rb help test == Benchmarking Simply pass the option '-b NUMBER' when you call the script, where NUMBER is how many iterations you want to run on your tests for the benchmark. Note that only passed tests will be used for benchmarking. == Other options You may want to suppress the output of the test results when running benchmarks. This can be achieved by using the option '-n'. Maybe you want to reuse the output of the results for some further processing. Therefor you might use the option '-y' which returns the results as hash in YAML style. == Special: Testing and benchmarking alternativ Implementations Sometimes you have different options how to implement things. To evaluate this options, simply setup the alternative classes as subclasses of your main implementation class and overwrite the methods that you want to differ. Please make sure that their names contain the word 'TestCase' somewhere. Thats it! You might simply test and benchmark them in addition to the main implementation by using the option '-a' when calling the script. So you can easily check, if they contain hidden errors and what implementation is the fastest. I leave them in the script even after rearranging the main implementation to the best, simply to be able to see what I already tried when I feel the need to optimize later again. They don't hurd me as I don't use them when including the file. == What happens if I include my lib with all these tests? Nothing. It won't hurt you. == What happens if I want to test a script that should be called from the shell? lazytest is primarily for the testing of libraries, but since it only runs the tests when you pass the "test" option to the script that should not affect scripts that don't use "test" as keyword. == Future I am currently fighting with the profiler to have let there be a '-p NUMBER' profiling option. But it frequently conflicts with my error handling and I have to dig deeper in it. There will be some other testing tools to allow automagical compatibility checking and datasoup checking. This will be part of lazytest some day. == Where may I find a complete example? Look at example.rb. Project Website: http://rubyforge.org/projects/lazytest/ Contact: linux@marcrenearns.de benny