Browse thread
invoke function from its name as string
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2008-03-14 (00:53) |
From: | Ludovic Coquelle <lcoquelle@g...> |
Subject: | Re: [Caml-list] invoke function from its name as string |
I like the "global test registry" of Andrej and will give it a try (adapted to OUnit). Thanks for all the advices! On Fri, Mar 14, 2008 at 1:03 AM, Andrew Gacek <andrew.gacek@gmail.com> wrote: > Andrej's solution is interesting since it lets you interleave the > regular code with the test code. For my own code, I keep all tests > isolated to separate files and in each file I maintain the tests as a > list of anonymous functions. As a made-up example I might have > > let list_tests = > "List" >::: [ > "Empty list has length zero" >:: > (fun () -> > assert_equal 0 (List.length [])) ; > > "Empty list appended to empty list is empty list" >:: > (fun () -> > assert_equal [] ([] @ [])) ; > > ... > > ] > > This structure makes it very easy to add new tests and does not > require me to come up with > convoluted_test_function_names_with_undersctores. The downside is that > tests end up being indented so much. > > -Andrew > > On Thu, Mar 13, 2008 at 11:41 AM, Andrej Bauer > > <Andrej.Bauer@fmf.uni-lj.si> wrote: > > > > Ludovic Coquelle wrote: > > > Thanks for this answer. > > > Problem I'm trying to solve is the following: > > > > > > I use 'make_suite' which is a program that do regex matching on source > > > code to extract a list of function that looks like OUnit tests; from > > > this list, it write an ocaml source code file which is a test case > > > that call all the previous functions found. > > > (see: http://skydeck.com/blog/programming/unit-test-in-ocaml-with-ounit/) > > > > I looked at the blog post. The idea is to interleave the source code > > with special test functions and extract those automatically. You have > > chosen to do this by searching the source code with regular expressions, > > looking for functions with a certain name. If I may be honest and will > > all due respect: this is a really horrible idea. It is fragile, > > sensitive to mistakes, you have no guarantee that all the test functions > > were actually found (say what if someone mispells the name of one of > > them slightly), and so on. It is just really bad. > > > > How about the following solution, in which I naively assume that test > > functions are supposed to return bool, but this is easily fixed. Define > > a module "Test" somewhat like this: > > > > ---test.ml---- > > (** The list of tests registered by the source code. *) > > let tests = ref [] > > > > (** Register a function as a test. *) > > let register name test = > > tests := (name, test) :: !tests > > > > (** Run all tests, maybe we can combine this with OUnit? *) > > let run_tests () = > > List.iter > > (fun (name,test) -> > > if not (test ()) then failwith ("FAILED: " ^ name)) > > !tests > > ------------- > > > > In your source code, whenever you want to have a test you just write: > > > > Test.register "some_name" (fun () -> > > (*test code here*) > > *) > > > > This is essentially the same overhead as what you have in your current > > solution, except that it is robust, ocaml will check that it is ok, and > > you do not have to come up with names of test functions of the form > > test_... all the time. The names of tests are strings, they can be more > > descriptive. > > > > To run your program, you do not do anything special. There will be a > > small initialization cost when the test functions are collected in the list. > > > > Tu run the tests, you link your source code with something like > > > > ---runtest.ml--- > > > > Test.run_tests () > > > > --------------- > > > > You can easily extend this idea to using OUnit inside test.ml or do > > whatever you like. The important thing is that you do not search the > > source code in a naive and fragile way that requires to programmer to > > follow arbitrary naming conventions. > > > > Best regards, > > > > Andrej > > > > > > > > _______________________________________________ > > Caml-list mailing list. Subscription management: > > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > > Archives: http://caml.inria.fr > > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > > Bug reports: http://caml.inria.fr/bin/caml-bugs > > >