Module eqc

This module defines functions for writing and testing QuickCheck properties.

Copyright © Quviq AB, 2004-2023

Version: 1.46.3

Description

This module defines functions for writing and testing QuickCheck properties. Much of the interface is provided via macros (defined in eqc.hrl). These are documented below:

?FORALL(X,Gen,Prop)

Property that holds if Prop holds for all values X that can be generated by Gen. For example,
 prop_reverse() ->
   ?FORALL(Xs,list(int()),
      lists:reverse(lists:reverse(Xs)) == Xs).
 
Generators are defined using the module eqc_gen.

?IMPLIES(Pre,Prop)

Property that holds if Prop holds whenever the precondition Pre is true. The precondition must be a boolean, but Prop can be any QuickCheck property. An implication is tested by discarding test cases which do not satisfy the precondition. This can make testing slow, since many more test cases may need to be generated to find 100 which satisfy the precondition. In the worst case, QuickCheck may not be able to find enough test cases that do satisfy the precondition, in which case the number actually found is reported. Some preconditions may also skew the test data badly--for example, a precondition that a list is sorted skews the test data towards short lists, since random longer lists are extremely unlikely to be sorted just by chance. ?IMPLIES works well for preconditions which are true with a high probability, but if the precondition is unlikely to hold, then it is better to write a custom generator which generates test cases where the precondition is true.

?WHENFAIL(Action,Prop)

Property that is equivalent to Prop, but performs Action (for its side effects) when Prop fails. This can be used to print additional information when a test case fails.

?TRAPEXIT(Prop)

A property which tests Prop in a separate process, trapping exits and treating them as test failures. QuickCheck always catches locally raised exceptions in properties, but when a test exits because a linked process fails, then the exit is NOT caught unless the body of the property is enclosed in ?TRAPEXIT. Shrinking is disabled for any ?FORALLs enclosed by ?TRAPEXIT (although not, of course, for ?FORALLs which enclose it). Thus ?TRAPEXIT would typically be used inside the innermost ?FORALL of a property.

Note that actions in the ?WHENFAIL macro are not executed if they are inside a TRAPEXIT, thus one may have less printed information in the failing test case. When using eqc_component specifications there is an alternative to ?TRAPEXIT by using a worker process instead.

?TIMEOUT(Limit,Prop)

A property which tests Prop with a time limit of Limit milliseconds. If the timeout is exceeded, then the property fails with the reason {timeout,Limit}. Note that any ?FORALLs within the ?TIMEOUT will not print the generated values, and moreover those values will not shrink on a test failure, so it is a good idea to nest ?TIMEOUT within ?FORALL rather than vice versa.

Example:

 prop_sleep() ->
   ?FORALL(N,choose(50,150),
     ?TIMEOUT(100,
       timer:sleep(N) == ok)).
 
fails as follows:
 1> eqc:quickcheck(foo:prop_sleep()).
 ....Failed! Reason:
 {'EXIT',{timeout,100}}
 After 5 tests.
 118
 Shrinking....(4 times)
 Reason:
 {'EXIT',{timeout,100}}
 101
 false
 
where the length of the sleep shrinks to the minimal value required to time out, of course.

?SETUP(Fun,Prop)

Similar to initializing a test suite, before running a QuickCheck test run, one might want to setup the subject under test. QuickCheck offers the ?SETUP property for defining setup and teardown behaviour for one QuickCheck run (default hundred tests). The zero-arity function Fun is called before the property is checked. This functions should return a zero-arity teardown function which is called after the property has been checked.
Example:
   prop_ok() ->
      ?SETUP(fun() -> setup_mocking(),
                  fun() -> teardown_mocking() end
             end,
         ?FORALL(Cmds, commands(), ...)).
 

?ALWAYS(N,Prop)

A property which tests Prop repeatedly N times, failing as soon as any of the tests of Prop fails. Typically this is used as follows:
?FORALL(X,...,?ALWAYS(N,?FORALL(Y,...,...)))
which generates N values of Y for each value of X. This is useful if Don't use this macro at the top-level of a property: numtests/2 is more appropriate for this.

?SOMETIMES(N,Prop)

A property which tests Prop repeatedly N times, failing only if all of the tests fail. In other words, the property passes if Prop sometimes passes. This is used in situations where test outcomes are non-deterministic, to search for test cases that consistently fail. A property such as ?FORALL(X,...,?SOMETIMES(10,...)) will find test cases X for which the property inside ?SOMETIMES is very likely to fail.

?ONCEONLY(Prop)

A property, logically equivalent to Prop, which tests Prop once only for each combination of values bound in enclosing ?FORALLs. For example,
?FORALL(N,nat(),?ONCEONLY(N*N >= 0))
will test that N squared is non-negative only once for each value of N. (Since nat() only generates small naturals, testing this example will actually give up without generating 100 different tests).

?ONCEONLY saves each generated test, and skips any tests which are generated for a second time---it is equivalent to

?IMPLIES(...is a new test case...,Prop)
Skipped tests are displayed as a 'x', just as when using ?IMPLIES.

Note that duplicate test cases are generated as usual, but ?ONCEONLY prevents them from being run. This can save testing time if running tests is much more expensive than generating them. Of course, there is a space and time penalty for saving old tests and comparing new tests against them, so using ?ONCEONLY will not necessarily speed up testing.

Test cases are saved only during one run of quickcheck/1; this does not prevent repetition of tests in different runs of quickcheck/1.

Data Types

aggregated_data()

aggregated_data() = [{term(), integer()}]

Aggregated data, in principle a map from terms to number of occurences.

counterexample()

abstract datatype: counterexample()

A counter-example to a QuickCheck property, which can be obtained using counterexample/0 or counterexample/1, and used to repeat a test, or test a different property in the same case. Counterexamples are represented by the values bound by ?FORALL--for the counterexample to make sense independently, it's important that these were generated without side-effects.

eqc_info_map()

eqc_info_map() = #{result => boolean() | counterexample(), statistics => #{outcome => passed | failed | failed_as_expected | passed_unexpectedly | gaveup | bad_distribution, numtests => integer(), discards => integer()}, aggregated_data => [{atom(), aggregated_data()}], measurements => [{atom(), measure_map()}], user_info => eqc_user_info_map()}

eqc_user_info_map()

eqc_user_info_map() = #{}

Map containing user defined data. Data is stored using user_info/3, and the result is a map with all keys defined by the user.

I.e. user_info(key1, data1, ...) will result in a map #{ key1 => data1, ... }.

measure_map()

measure_map() = #{count => integer(), min => number(), max => number(), sum => number(), avg => number(), stddev => number()}

Map containing the returned data collected by measure/3.

print_method()

print_method() = print_method_fun() | {atom() | string(), none | string(), print_method_fun()}

Instructions on how to print statistics; either a pure print_method_fun (the old way), or a triple {Tag, Title, PrintFun}. Where Tag is used to tag the returned statistics see counterexample/2, Title is printed as a header for the statistics printed by PrintFun. Used by collect/3 and aggregate/3.

print_method_fun()

print_method_fun() = fun((aggregated_data()) -> false | any())

Printing statistics, the function is passed a list of samples and is expected to print statistical information about them. Print functions are used by collect/3 and aggregate/3.

property()

abstract datatype: property()

QuickCheck properties, which can either be boolean expressions, or constructed using the functions in this module. QuickCheck properties are tested using quickcheck/1.

Function Index

active_users/0Fetch a list of the currently active users of your licence.
aggregate/2A property logically equivalent to Prop, but which collects a list of values in each test, and displays the distribution of these values once testing is complete.
aggregate/3Like aggregate/2, but allows the user to specify how the collected values should be printed.
backtrace/0Displays a stack backtrace from the last exception QuickCheck caught.
check/1Equivalent to check(Prop, eqc:current_counterexample()).
check/2Tests the property in the case given.
check/3Tests the property in the case given.
check_distribution/4Check that at least a given fraction of test cases satisfy a condition.
classify/3Property which is logically equivalent to Prop, but also classifies test cases and displays the distribution of test case classes when testing is complete.
collect/2Equivalent to aggregate([S], Prop).
collect/3Equivalent to aggregate(PrintMethod, [S], Prop).
conjunction/1conjunction([{Tag1,Prop1},...,{TagN,PropN}]) is a property which is true if all of the properties Prop1...PropN are true.
count_values/0A print method that displays the number of occurrences for each value in the collected data.
counterexample/0Returns the last counter-example found.
counterexample/1Equivalent to counterexample(P, []).
counterexample/2Tests the property in the same way as quickcheck/1, but if a test fails, then the failing test case is returned as a counterexample.
counterexamples/0Returns a list of the counterexamples found by the last call of eqc:module, paired with the name of the property that failed.
current_counterexample/0Returns the most recent counterexample found by QuickCheck.
disjunction/1disjunction([Prop1,...,PropN]) is a property which is true if any of the properties Prop1...PropN is true.
dont_print_counterexample/1Suppress the normal printing of counterexamples.
equals/2A property which holds if X and Y are equal...
fails/1A property which succeeds when its argument fails.
features/2Attach a list of features to a test case, with the interpretation "this test case tests these features".
force_registration/1 Register a QuickCheck licence without asking questions.
format/2Can be used in place of io:format/2 inside ?WHENFAIL to allow the output to be captured by on_output/2.
in_parallel/1A property which is tested in parallel.
in_sequence/1A property which is tested sequentially.
less_or_equal/2A property which holds if X =< Y, and displays their values when a test fails.
licences_installed/0Returns a list of the installed licences.
measure/3Collects the values of X while testing Prop, and if all tests pass, displays statistics such as the minimum, average, and maximum values, identified by the name Name.
module/1Tests all the properties exported from a module, given the module name.
module/2Tests all the properties exported from a module, given options and the module name.
numtests/2Property which is logically equivalent to Prop, but is tested N times rather than 100.
on_output/2Supplies an output function to be used instead of io:format when QuickCheck generates output.
on_test/2Attaches a function to a property which is called every time a test passes or fails.
only_top/1A printing method for discarding all but the top N collected values.
only_top/2A printing method for discarding all but the top N collected values.
quickcheck/1Tests the property in 100 random cases, printing a counter-example if one is found.
recheck/1Tests the property with the same random number seed as the last failing call of quickcheck/1.
recheck/2Same as recheck/1, but if {with_info, true} is passed as an option a richer structure is returned.
registration/1Create a QuickCheck licence for the current user, using a one-time use registration identifier.
reserve/1Reserve a QuickCheck licence for this machine.
reserved_until/0The local time that the currently active QuickCheck licence is reserved until.
start/0Starts the QuickCheck server.
start/1Equivalent to start().
stop/0Stops the QuickCheck server.
testing_time/2Property which is logically equivalent to Prop, but is tested continuously for T time units (by default, seconds), rather than a fixed number of times.
user_info/3Sometimes it is useful to record data deep inside a property, thus we provide a basic key-value store.
version/0Returns the version number of this version of QuickCheck.
watch_shrinking/1Repeats the most recent failed test, but displays all the test cases explored during shrinking.
with_tag/1A printing method for collected data, which tags the collected data so that it is returned in the rich result structure from counterexample/2.
with_testing_time_unit/2Property which is logically equivalent to Prop, but in which calls of testing_time/2 measure testing time in units of Unit milliseconds--by default 1000.
with_title/1A printing method for collected data, which displays a title before the percentages of each value in the data.
with_title/2Add a title to a print method.

Function Details

active_users/0

active_users() -> any()

Fetch a list of the currently active users of your licence. The users are sorted by the expiry times of their current sessions; thus the user whose licence may first become free is first in the list. Of course, other users who continue running QuickCheck will automatically extend their sessions, so there is no guarantee that a licence will actually be released at the time indicated.

aggregate/2

aggregate(L::[term()], Prop::property()) -> property()

A property logically equivalent to Prop, but which collects a list of values in each test, and displays the distribution of these values once testing is complete. A typical use would be to aggregate the list of command names generated by eqc_statem:commands/1, in order to see how often each individual command appeared in generated tests:

aggregate(command_names(Cmds), ...) 

See also aggregate/3.

aggregate/3

aggregate(PrintMethod::fun(([{term(), int()}]) -> any()), L::[term()], Prop::property()) -> property()

Like aggregate/2, but allows the user to specify how the collected values should be printed. The PrintMethod parameter is called with a list of the collected data and the number of occurrences of each datum as an argument, and is expected to print some statistics. If the print method returns false the property fails. This is used in the implementation of check_distribution/4. A predefined printing methods is provided to add a title to the statistics:

aggregate(with_title(T),L,Prop).
This is useful when a property contains several calls to aggregate or collect.

backtrace/0

backtrace() -> ok

Displays a stack backtrace from the last exception QuickCheck caught. Note that this is only possible if the exception is raised in the process in which the test case starts. If a test case fails because of an exception in another, linked, process, then no backtrace is available. Calls to functions in the implementation of QuickCheck itself are not included in the backtrace.

If you really need to see a backtrace from a linked process, then you can do so by catching the exception yourself in that process, using try-catch to obtain the backtrace, and printing it yourself.

check/1

check(Prop) -> any()

Equivalent to check(Prop, eqc:current_counterexample()).

check/2

check(Prop::property(), Values::counterexample()) -> bool()

Tests the property in the case given. Counterexamples are generated by testing a property using counterexample/1 or counterexample/0, and contain a list of the values bound by ?FORALL. A property tested by check should begin with the same sequence of ?FORALL s as the property from which the counterexample was generated, otherwise the results will be unpredictable. In particular, there is no check that the values in the counterexample could actually have been generated by the ?FORALL s in the property under test.

check/2 can be used without a QuickCheck licence, allowing anyone to run tests that a licenced user has generated.

check/3

check(Prop::property(), Values::counterexample(), Options::[term()]) -> bool() | eqc_info_map()

Tests the property in the case given. Counterexamples are generated by testing a property using counterexample/1 or counterexample/0, and contain a list of the values bound by ?FORALL. A property tested by check should begin with the same sequence of ?FORALL s as the property from which the counterexample was generated, otherwise the results will be unpredictable. In particular, there is no check that the values in the counterexample could actually have been generated by the ?FORALL s in the property under test. If {with_info, true} is passed as an Option, a richer structure is returned, see counterexample/2.

check/3 can be used without a QuickCheck licence, allowing anyone to run tests that a licenced user has generated.

check_distribution/4

check_distribution(Tag::term(), Fraction::float(), Ok::boolean() | [boolean()], Prop::property()) -> property()

Check that at least a given fraction of test cases satisfy a condition. Unless Ok is true in at least Fraction of test cases the property fails. For instance,

check_distribution(non_empty, 0.75, Xs /= [], Prop)
checks that in at least 75% of test cases the list Xs is non empty. If Ok is a list, the distribution of the aggregated boolean values is checked (see aggregate/2).

classify/3

classify(B::bool(), S::term(), Prop::property()) -> property()

Property which is logically equivalent to Prop, but also classifies test cases and displays the distribution of test case classes when testing is complete. If the boolean is true then the current test case is labelled with the term S, and, after testing is complete, QuickCheck prints out the percentage of test cases carrying each label. This can be used to check that the space of possible test cases has been covered reasonably well. For example, classifying test cases according to the length of a list enables one to see whether unreasonably many lists were short. Classifying test cases is a way to discover skewed distributions, such as can arise from using ?IMPLIES. It is good practice to check the distribution of test data using classify or collect/2, at least while properties are being developed.

Each test case can be labelled with any number of labels: QuickCheck then displays the percentage of each label in the generated test data.

Calls of classify or collect can be nested, in which case each call generates its own table of distributions.

collect/2

collect(S::term(), Prop::property()) -> property()

Equivalent to aggregate([S], Prop).

collect/3

collect(PrintMethod::fun(([{term(), int()}]) -> any()), S::term(), Prop::property()) -> property()

Equivalent to aggregate(PrintMethod, [S], Prop).

conjunction/1

conjunction(Props::[{atom(), property()}]) -> property()

conjunction([{Tag1,Prop1},...,{TagN,PropN}]) is a property which is true if all of the properties Prop1...PropN are true. The tags are used when reporting counterexamples: the test case generated for each property is labelled with its tag in the output, together with an indication of whether that property passed or failed. Shrinking discards tags and properties which do not contribute to the test failure.

count_values/0

count_values() -> print_method()

A print method that displays the number of occurrences for each value in the collected data. It is intended to be passed to collect/3 or aggregate/3.

counterexample/0

counterexample() -> undefined | counterexample()

Returns the last counter-example found. See counterexample/1.

counterexample/1

counterexample(P::property()) -> true | counterexample()

Equivalent to counterexample(P, []).

counterexample/2

counterexample(P::property(), Option::[term()]) -> true | counterexample() | eqc_info_map()

Tests the property in the same way as quickcheck/1, but if a test fails, then the failing test case is returned as a counterexample.

If {with_info, true} is passed as an option, an even richer structure is returned, namely an eqc_info_map. The returned map contains the following fields:

counterexamples/0

counterexamples() -> [{atom(), counterexample()}]

Returns a list of the counterexamples found by the last call of eqc:module, paired with the name of the property that failed.

current_counterexample/0

current_counterexample() -> counterexample()

Returns the most recent counterexample found by QuickCheck. This can be used while QuickCheck is shrinking a failed test case to follow progress, or if shrinking must be interrupted, to recover the last failed test case that QuickCheck had found. The counterexample is fetched from a file in the current directory.

disjunction/1

disjunction(Props::[property()]) -> property()

disjunction([Prop1,...,PropN]) is a property which is true if any of the properties Prop1...PropN is true. disjunction tests the properties from left-to-right, and stops as soon as one of them passes.

dont_print_counterexample/1

dont_print_counterexample(Prop::property()) -> property()

Equivalent to eqc_gen:with_parameter(print_counterexample, false, Prop).

Suppress the normal printing of counterexamples. Custom counterexample printing can be added using ?WHENFAIL.

equals/2

equals(X::any(), Y::any()) -> property()

A property which holds if X and Y are equal... and displays their values when a test fails.

fails/1

fails(Prop::property()) -> property()

A property which succeeds when its argument fails. Sometimes it is useful to write down properties which do not hold (even though one might expect them to). This can help prevent misconceptions. fails(P) is tested in the same way as P, but fails only if P succeeds for every test. Thus fails(P) declares that QuickCheck should be able to find a counter-example to property P.

features/2

features(Fs::[any()], Prop::property()) -> property()

Attach a list of features to a test case, with the interpretation "this test case tests these features". For example, the features might be lines of code covered by the test case, or argument values that were tested, or success/failure of individual functions. Features can be used to generate test suites that cover all of the features encountered. See eqc_suite:feature_based/1 for details.

force_registration/1

force_registration(X1) -> any()

Register a QuickCheck licence without asking questions. This function is useful when scripting user registration, but dangerous since licences may only be registered once! Note that it takes a list of exactly once licence to enable use with erl -run force_registration LicenceId

format/2

format(Fmt::string(), Args::[term()]) -> ok

Can be used in place of io:format/2 inside ?WHENFAIL to allow the output to be captured by on_output/2.

in_parallel/1

in_parallel(Prop::property()) -> property()

A property which is tested in parallel.

in_sequence/1

in_sequence(Prop::property()) -> property()

A property which is tested sequentially. Takes priority over in_parallel/1.

less_or_equal/2

less_or_equal(X::any(), Y::any()) -> property()

A property which holds if X =< Y, and displays their values when a test fails.

licences_installed/0

licences_installed() -> any()

Returns a list of the installed licences.

measure/3

measure(Name::atom() | string(), X::number() | [number()], Prop::property()) -> property()

Collects the values of X while testing Prop, and if all tests pass, displays statistics such as the minimum, average, and maximum values, identified by the name Name. X can also be a list of values, in which case all of them are included in the measurements.

module/1

module(Mod::atom()) -> [atom()]

Tests all the properties exported from a module, given the module name. Any function with arity zero whose name begins with "prop_" is treated as a property. The result is a list of the names of the properties that failed. See also module/2.

module/2

module(Options::any(), Mod::atom()) -> [atom()]

Tests all the properties exported from a module, given options and the module name. Any function with arity zero whose name begins with "prop_" is treated as a property. The result is a list of the names of the properties that failed.

The Options parameter can be a single option, or a list of options. Each option represents a function to be applied to each property before it is tested, and can either be a fun value, an atom (representing a function exported from module eqc), or a tuple of an atom and some arguments (representing a function exported by module eqc taking additional arguments before the property).

Example
To test every property in a module 1,000 times, use

 eqc:module({numtests,1000},ModuleName).
 

Testing budget

Using the testing_time option (thus calling eqc:testing_time/2) one can set a fixed testing time for each property. This is quite inflexible, however, and often you want different testing times for different properties and you don't want the total time to depend on the number of properties in the module. For this purpose there is a special option {testing_budget, Seconds} which controls the total time available for testing. By default the testing budget is distributed uniformly among the properties, but the distribution can be controlled by defining the property_weight/2 callback. This takes a testing profile and a property name as arguments and returns the relative weight for the property. The testing profile can be set with the {testing_profile, Profile} option and can be any Erlang term.

Example
Here is a simple example with two properties and two testing profiles.

 -module(example_eqc).
 -compile(export_all).

 prop_a() -> ...
 prop_b() -> ...

 property_weight(more_a, prop_a) -> 3;
 property_weight(more_b, prop_b) -> 3;
 property_weight(_, _) -> 1.
 
Now we can choose the testing profile to decide how much time to spend on each property.
 1> eqc:module({testing_budget, 60}, example_eqc).
 prop_a: .....
 Time limit reached: 30.0 seconds.
 OK, passed 204 tests
 prop_b: .....
 Time limit reached: 30.0 seconds.
 OK, passed 213 tests
 []
 2> eqc:module([{testing_budget, 60}, {testing_profile, more_a}], example_eqc).
 prop_a: .....
 Time limit reached: 45.0 seconds.
 OK, passed 298 tests
 prop_b: .....
 Time limit reached: 15.0 seconds.
 OK, passed 102 tests
 []
 3> eqc:module([{testing_budget, 60}, {testing_profile, more_b}], example_eqc).
 prop_a: .....
 Time limit reached: 15.0 seconds.
 OK, passed 96 tests
 prop_b: .....
 Time limit reached: 45.0 seconds.
 OK, passed 311 tests
 []
 

numtests/2

numtests(N::nat(), Prop::property()) -> property()

Property which is logically equivalent to Prop, but is tested N times rather than 100.

It is also possible to specify {min,N} or {max,N} as the number of tests, in which case we run at least N tests, or at most N tests, but otherwise according to the time limits or numtests/2 specified in the rest of the property.

on_output/2

on_output(Fun::fun((string(), [term()]) -> any()), Prop::property()) -> property()

Supplies an output function to be used instead of io:format when QuickCheck generates output. All output generated by QuickCheck is passed to Fun, in the form of a format string and a list of terms--the same arguments expected by io:format. By supplying a function which does nothing, QuickCheck can be run silently. By supplying a function which writes to a file, all QuickCheck output can be saved.

Note that output generated by user code is not passed to this output function. For example, calls to io:format in the property, or in the code under test, will generate output in the shell as usual. This applies even to calls inside a ?WHENFAIL, although this output can be redirected by replacing calls to io:format by calls to eqc:format/2. If you want to redirect output outside of ?WHENFAIL, then you need to modify your own code appropriately.

The reason that Fun is passed a format string and arguments, rather than an already formatted string, is to make it easier to extract information from the output without parsing it. However, there is no guarantee that different versions of QuickCheck will use the same format strings and term lists--you use this information at your own risk, in other words.

on_test/2

on_test(Fun::fun((counterexample(), bool()) -> any()), Prop::property()) -> property()

Attaches a function to a property which is called every time a test passes or fails. The arguments are the test case (a list of values), and a boolean indicating whether or not the test passed. Tests which are skipped (because of an ?IMPLIES(false,...)) are not included.

only_top/1

only_top(N::integer()) -> print_method()

A printing method for discarding all but the top N collected values. Discarded values are grouped together into an entry labelled '...'. The resulting print method is intended to be passed to collect/3 or aggregate/3.

only_top/2

only_top(N::integer(), F::print_method()) -> print_method()

A printing method for discarding all but the top N collected values. Discarded values are grouped together into an entry labelled '...'. The second argument is a print method for the pruned data, such as with_title/1. The resulting print method is intended to be passed to collect/3 or aggregate/3.

quickcheck/1

quickcheck(P::property()) -> bool()

Tests the property in 100 random cases, printing a counter-example if one is found. Initially small test cases are generated, then the size increases as testing progresses (see eqc_gen, ?SIZED, eqc_gen:resize/2 for the way size affects test data generation). The result is true if all tests succeeded (or if one failed, and failure was expected). On success, quickcheck analyses the distribution of test case labels. On failure, quickcheck tries to simplify the counter-example found as far as possible (see shrinking, described in eqc_gen).

recheck/1

recheck(Prop::property()) -> bool()

Tests the property with the same random number seed as the last failing call of quickcheck/1. If the property is the same as in that last call, then the same test case will be generated. Note that recheck repeats the test and its shrinking. This can be used to adjust the shrinking strategy in the property, then reshrink the same counterexample, perhaps to a better result. If you just want to repeat the shrunk test, then use

eqc:check(Prop,eqc:counterexample())
instead.

recheck/2

recheck(Prop::property(), Options::[term()]) -> boolean() | eqc_info_map()

Same as recheck/1, but if {with_info, true} is passed as an option a richer structure is returned. See counterexample/2 for a description of the return format.

registration/1

registration(LicenceId) -> any()

Create a QuickCheck licence for the current user, using a one-time use registration identifier. Note that using the same registration identifier twice will invalidate it---if you do this, ask your licence administrator to reset your licence for you.

Each registration identifier is associated with a licence name, usually the name of the licence owner, such as "Quviq AB". It is possible to register several identifiers with different licence names, which makes it possible to use different licences on different occasions. If you are registered as a user of more than one licence, then you will need to create a preferences file called .eqc_licence to specify which licence you want to use. This file can be placed in your home directory, or locally in the directory in which you are running QuickCheck, or one of its parent directories. A local file takes precedence over the one in your home directory.

The .eqc_licence file can just contain the name of the licence you want to use, or the names of several licences, one per line. In the latter case, QuickCheck tries each licence in turn, using the first one that enables a successful start. A warning is generated for each licence name (mentioned in this file) for which no registration identifier is installed. The warning can be disabled by appending a '?' to the licence name.

reserve/1

reserve(Period) -> any()

Reserve a QuickCheck licence for this machine. Reservations can be made for up to seven days; once a licence is reserved, it cannot be used on another machine until the reservation has expired. Reserving a floating licence can be useful to ensure that another user does not begin using it at a critical time, or, since a reserved licence can be used without internet access, to prepare a laptop for a trip during which internet access will not be available.

Examples: eqc:reserve({3,days}), eqc:reserve({6,hours}), eqc:reserve(5). (If the unit, days or hours, is not specified, then it defaults to days).

This call always succeeds, and returns {reserved_until,Time}, where Time is the local time the licence is now reserved until.

reserved_until/0

reserved_until() -> any()

The local time that the currently active QuickCheck licence is reserved until.

start/0

start() -> pid()

Starts the QuickCheck server. If it is already running on this node, nothing is done.

Each user can run only one instance of the QuickCheck server at a time. If the server is already running on another Erlang node, it will be terminated automatically.

start/1

start(Dummy) -> any()

Equivalent to start().

stop/0

stop() -> any()

Stops the QuickCheck server. QuickCheck properties are tested in the QuickCheck server process, which is spawned automatically when quickcheck is first called. Usually there is no need to stop the QuickCheck server explicitly, but if a need does arise then this function can be used.

testing_time/2

testing_time(T::nat(), Prop::property()) -> property()

Property which is logically equivalent to Prop, but is tested continuously for T time units (by default, seconds), rather than a fixed number of times. This can be used to apportion available testing time among a set of properties. When the time limit is reached, then no more tests are started, but any currently running test is completed.

The time unit can be specified using with_testing_time_unit/2.

It is also possible to specify {min,Time} or {max,Time} as the time limit, in which case tests are run for at least Time time units, or at most Time units, but otherwise according to the time limits or numtests/2 specified in the rest of the property.

user_info/3

user_info(Key::atom(), FunOrData::fun((any()) -> any()), Prop::property()) -> property()

Sometimes it is useful to record data deep inside a property, thus we provide a basic key-value store. Either some static piece of data can be stored for Key, if DataOrFun is not a function. Otherwise the function (with arity 1) in DataOrFun is applied to whatever data is stored for Key, if no data is yet stored the function is applied to undefined.

   prop_ok() ->
     ?FORALL(X, nat(),
       user_info(sum, fun(undefined) -> X; (Sum) -> Sum + X end, ...)).
 
If this property is tested with counterexample/2 passing {with_info, true} as an option it will result in a result map where user_info is a map containing the key sum and the value will be the total sum of all tested values (including shrunk values if the property fails!). The rich result is further described for counterexample/2.

version/0

version() -> any()

Returns the version number of this version of QuickCheck.

watch_shrinking/1

watch_shrinking(P::property()) -> ok

Repeats the most recent failed test, but displays all the test cases explored during shrinking. The test cases are reported in the order they are tried, so each Failed test is followed by attempts to shrink it, while each OK test (or test skipped because a precondition failed) is followed by an alternative way to shrink the last Failed test. The last Failed test displayed is the final result of shrinking.

with_tag/1

with_tag(Tag::atom() | string()) -> print_method()

A printing method for collected data, which tags the collected data so that it is returned in the rich result structure from counterexample/2. It is intended to be passed to collect/3 or aggregate/3.

with_testing_time_unit/2

with_testing_time_unit(Unit::nat(), Prop::property()) -> property()

Property which is logically equivalent to Prop, but in which calls of testing_time/2 measure testing time in units of Unit milliseconds--by default 1000. If testing_time/2 is used to apportion available testing time between properties, then with_testing_time_unit/2 can be used as a property wrapper to increase or decrease the total time spent testing.

with_title/1

with_title(Title::atom() | string()) -> print_method()

A printing method for collected data, which displays a title before the percentages of each value in the data. It is intended to be passed to collect/3 or aggregate/3.

The function also tags the collected data (with the title) so that it is returned in the rich result structure from counterexample/2.

with_title/2

with_title(Title::atom() | string(), Fun::print_method()) -> print_method()

Add a title to a print method. The title is printed before the print method is called.


Generated by EDoc