How to verify the product of all the elements in a list

The following code are the product of all the elements in a list and corresponding test function. If xs is small, I can hard coding the result and use it to achieve the test. But if xs is large, how can I achieve the test?

open OUnit2

let xs = [1;2;3];;

let rec product = function
    | []     -> 1
    | x::xs  -> x * product xs;;

let test_product =  assert_equal 6 (product xs);;

let test_suites = "[List]" >::: [
    "==== Test Product ====" >:: (fun _ -> test_product);

let _ = run_test_tt_main test_suites

What you’re trying to do is to see if some computation has a known, definite result. There’s no way to avoid hardcoding the result if this is your goal. If xs is really large, then just figure out the product and hardcode the result.

Alternatively you can test to see if some computation has a result that matches the result of another computation:

let pipe = Unix.open_process_in "perl -le 'print 1*2*3'" in
let result = int_of_string (input_line pipe) in
close_in pipe;
result  (* int = 6 *)

But then you have trust that computation. At least hope that it won’t break in the same direction of OCaml, hiding the breakage.


You can use QCheck to generate test cases. But, as @techate says, you’ll ultimately need to validate the one computation against another. You could do something like the following:

  • have QCheck generate a random integer
  • use a function to derive the prime factors of that integer
  • test whether your product function returns the original int when you run it on those prime factors.

For a simple function like this, you can probably just ‘visually inspect’ it to verify that it’s correct. But if you have some function for which you can’t do that, you could use property testing to try to catch the edge cases, and you could also use ‘expect tests’ (also known as snapshot testing or golden master testing) to write assertions without actually having to calculate and write down the expected results manually:

Take a look at ppx_expect, because it will save a lot of work when trying to write many assertions.

Note that property testing and expect testing aren’t compatible, because the former is randomised while the latter tests the same assertions each time.

1 Like