Testlib is the name for a library which is used to create checkers. Checkers are programs which validate the output of solutions for problems in programming competitions.
Originally, Testlib was written in Pascal. A modern implementation was done in C++ by Mike Mirzayanov, which is available on GitHub.
In this repository, an implementation in Java is made to do the same thing. This implementation was used in recent NEERC semifinals.
We use Ant due to its simplicity.
- Run
ant compile-src
, or simplyant
, andtestlib4j.jar
will be created in thedeploy
directory. - Run
ant clean
to remove all JARs and intermediate build files.
Every checker should implement the ru.ifmo.testlib.Checker
interface.
There is a single method to implement, namely,
Outcome test(InStream inf, InStream ouf, InStream ans)
,
where the arguments of type ru.ifmo.testlib.InStream
correspond to
the input file, the output file and the answer file, correspondingly.
In this method, you do everything you normally do within a checker.
For example, you can read the answer from the contestant's output file (the ouf
parameter),
the correct answer from the answer file (the ans
parameter)
and compare them for equality. You can also read the input file (the inf
parameter)
and validate the contestant's output against this input.
You need to return the Outcome
, which is your verdict about correctness of the
contestant's output. There are various types of outcomes, reflected by the Outcome.Type
enum:
Outcome.Type.OK
: everything is OK, and the contestant's output is correct.Outcome.Type.PE
: "Presentation Error", the output cannot be parsed.Outcome.Type.WA
: "Wrong Answer", the output is understandable but wrong.Outcome.Type.FAIL
: something is really bad, so bad that someone needs to rewrite the checker.
When needed, you can create and return instances of Outcome
directly, for instance:
return new Outcome(OK, "This is a brilliant answer")
.
Outcome
s are also Throwable
s, so you can also throw new Outcome(WA, "Bad guys receive no gifts today")
.
There is a convenient shorthand Outcome.quit(Outcome.Type, String, Object...)
for immediately quitting from anywhere with the given outcome,
the format string and its arguments, for instance:
Outcome.quit(WA, "Expected %d found %d", 42, 26);
Once you have compiled your checker (we assume the class name is MyChecker
,
it is located in the default package, and the class files are packed in
a file called Check.jar
), you can run it as follows:
java -cp Check.jar:testlib4j.jar ru.ifmo.testlib.CheckerFramework MyChecker <input> <output> <answer>
where testlib4j.jar
is the JAR file containing classes from this project.
On Windows, you need to separate JAR files with ;
, for instance:
java -cp Check.jar;testlib4j.jar
.
This is maybe the simplest possible checker. It checks whether the output file produced by the contest participant contains the single integer which is the same as the right answer.
import ru.ifmo.testlib.*;
import static ru.ifmo.testlib.Outcome.Type.*;
public class CompareNumber implements Checker {
public Outcome test(InStream inf, InStream ouf, InStream ans) {
long answer = ans.nextLong();
long output = ouf.nextLong();
if (answer != output) {
return new Outcome(WA,
"The answer is " + answer + ", but you output " + output);
} else {
return new Outcome(OK,
"OK: " + answer);
}
}
}