=head1 INTRODUCTION

The Zonemaster system intends to provide a framework for implementing DNS tests. In order to do this, it exposes APIs to the test code for examining a
DNS zone, to emit examination results and to access configuration information on how the tests should be performed.

=head1 RULES AND RECOMMENDATIONS FOR TEST CODE

=over

=item Only access the outside world via the framework APIs.

The framework is built to make test results traceable, repeatable and understandable. If the test code itself goes around the framework and accesses
things on its own, all those attributes are lost. If the test you're writing needs something the framework doesn't provide, request that it be added
to the framework.

=item Make as few assumptions as possible.

When the entry method in a test module is called, it can rely on only a handful of things about the testing process so far:

=over

=item

The zone object it's given has a parent.

=item

The zone object it's given has glue records.

=item

The zone object it's given has nameservers.

=back

=item Favor code clarity over performance.

Strive to make the test code as easily understood as possible. Ideally, it should be possible for a person with only a basic understanding of Perl to
read the code and verify that it correctly implements the corresponding test specification. 

=back

=head1 TEST MODULE STRUCTURE

The Zonemaster framework will attempt to load and call all modules in the namespace C<Zonemaster::Engine::Test>. These modules must have three class methods
defined. One to run all tests it provides, and two to expose metadata about the module. Apart from that (and the rules above) the module can be
implemented as desired.

There is an example module included in the standard Zonemaster distribution, L<Zonemaster::Engine::Test::Example>, that demonstrates what a test module should
look like. Incidentally, it also serves to demonstrate how to use the policy to block a test module from being run.

=head2 Metadata methods

=over

=item C<version()>

This method should return a string representing the current version of the test module. The version information will be logged in a C<SYSTEM>
message, but otherwise not used.

=item C<metadata()>

This method should return a reference to a hash. The keys of this hash should be the names of the individual test methods in the module, and the
values for each key should be a reference to an array listing all the possible messages that test method can emit. 

=back

=head2 Test-running method(s)

The framework expects to be able to run all tests in a module by calling a class method C<all()> with a L<Zonemaster::Engine::Zone> object as the argument.
The return value from this method is expected to be a list of L<Zonemaster::Engine::Logger::Entry> objects describing the results of the tests run. The
example test module has one possible implementation of this.

In the case where one test module wants to use a test in another, the top-level L<Zonemaster::Engine> module has a method C<test_method()> to request that.
This method will call the other test, if it is available and the current policy allows its execution. It's up to the caller to know what arguments
the other test needs, and what it returns.

=cut
