Syntactic Sugar for TestReports

You can make it look somewhat more pleasant by using simple expression parsers. For example, define an auxiliary head Tests, as follows:

ClearAll[transformTest];
SetAttributes[transformTest, {HoldAll, Listable}];
transformTest[lhs_ -> rhs_] := Hold[VerificationTest[lhs, rhs]];
transformTest[Tests[tests___]] := Thread[transformTest[{tests}], Hold];


ClearAll[Tests];
SetAttributes[Tests, HoldAll];
Tests /: TestReport[t_Tests, args___] :=
  Replace[
    transformTest[t],
    Hold[tests___] :> TestReport[tests, args]
  ];

And now you can use the following syntax:

TestReport @ Tests[
  StringFreeQ["apple", "lp"] -> True, 
  StringFreeQ["apple", "a" ~~ __ ~~ "e"] -> False,
  StringFreeQ["apple", "ap"] -> False, 
  StringFreeQ["apple", "x"] -> True,
  StringFreeQ["", "asd"] -> True
]

which looks a little nicer to me.


You can make your own code work simply enough by controlling evaluating with e.g. Inactive

Inactive[TestReport][
  Inactive[VerificationTest] @@@ 
   Thread[{Inactive[StringFreeQ] @@@ args, results}]] // Activate

or Block:

Block[{StringFreeQ, VerificationTest, TestReport},
  TestReport[VerificationTest @@@ Thread[{StringFreeQ @@@ args, results}]]
]

If writing this myself I would probably use my own heldCases and this:

heldCases[
  Thread @ {args, results},
  {{a_, b_}, r_} :>
    VerificationTest[StringFreeQ[a, b], r]
] /. _[x__] :> TestReport[{x}]

I prefer Leonid's more general approach however.