Creating dynamic test cases

Hello! I’m trying to dynamically generate tests for run_tests. to run… but I’m struggling.

The goal is I have a bunch of text files organized with input/output files (I take input, run prolog code on it, and then compare the output file to the output generate).

Here is one version of my unsuccessful attempts (I also tried :- initialization...) :

:- begin_tests(dynamic_suite).
:- dynamic test/1.

test(cool) :- true.

generate_tests :-
    print("DYNAMIC TESTS CREATED"),
    assertz(test(is_positive_N) :- true).

:- generate_tests.

:- end_tests(dynamic_suite).

When I run

swipl -g run_tests -t halt dynamic_suite.plt

I get

[1/1] dynamic_suite:cool ...................................................................................................................................... passed (0.012 sec)
% test passed in 0.017 seconds (0.015 cpu)

but I’m expecting something like this:

DYNAMIC TESTS CREATED
[2/2] dynamic_suite:is_positive_N ............................................................................................................................. passed (0.000 sec)
% All 2 tests passed in 0.018 seconds (0.016 cpu)

The test/1,2 clauses are not asserted literally, but processed by term_expansion/2 rules. The normal way to do this is to define your own local term_expansion/2 rule as in

term_expansion(my_tests, Tests) :-
    <Bind Tests to a list of (test(Name,Optons) :- Body) terms>

my_tests. % The thing that is expanded

This technique is used quite frequently to generate tests from external test data. You can make a lot of variations on this idea.

1 Like