[m-users.] Basic Unit Test Framework
Dirk Ziegemeyer
dirk at ziegemeyer.de
Sun Jul 19 06:58:48 AEST 2015
Thank your for the clarification and sorry for my late reply.
I understand that my current testing approach is different.
I pass the predicate-under-test as a parameter to a test-predicate together with the expected result.
For the DCG parser, I use two different types of test-predicates:
1. takes the chars-to-be-parsed as a parameter. This is convenient only for small strings.
2. takes as parameter a name of a file, which is opened by the test predicate and contains the chars-to-be-parsed
My test-predicates also differ by the type of the expected result, which are:
a) bool for a semidet predicate with no output (e.g. a DCG predicate that just evaluates to true if the chars-to-be-parsed conform to the DCG grammar rule)
b) maybe(Result) for a semidet predicate with one output parameter (e.g. a DCG predicate that returns a parsing result if the chars-to-be-parsed conform to the DCG grammar rule)
Cheers,
Dirk
> Am 14.07.2015 um 01:35 schrieb Charles Shuller <charles.shuller at gmail.com>:
>
>
> > 3) Hard to get a message about what failed if the predicate only succeeds of fails. I save off results instead of pushing IO into the test harness though. I felt it made more sense.
>
> I also don’t like pushing IO through the test cases, but I didn’t accomplish to put test cases into a list. After reading in the reference manual section 8.3, that higher-order terms can cause problems in polymorphic collection types, I gave up my try to collect test cases in a list.
>
> I'm not using Polymorphism.
>
> :- type test_result
> ---> test_result(result_test_name::string,
> result_test_disposition::test_disposition).
>
>
> Eventually, I'll want to flesh that out with things like the hostname, startTime, stopTime, etc... but this is all I needed for no
>
> For a simple XML parser, I wrote dozens of test cases like these:
>
> %% testDCG(TestNo, DCG-predicate, InputToBeParsed, ExpectedResult, !IO)
>
> testDCG(1, nameStartChar, ":", yes(':'), !IO),
> testDCG(2, nameStartChar, "-", no, !IO),
> testDCG(3, nameChar, "-", yes('-'), !IO),
> testDCG(4, name, "Name", yes("Name"), !IO),
> testDCG(5, attValue, "\"AttValue\"", yes("AttValue"), !IO),
> testDCG(6, attribute, "attribute=\"Value\"",
> yes({"attribute", "Value"}), !IO),
> …
>
> I don’t understand the syntax of test_case yet. Could you please give me an example, how I can write a list of test cases for different DCG predicates?
>
>
> You don't pass in the predicate-under-test as a parameter, instead you build a test predicate and call predicate-under-test from there.
>
> Below is an example of test cases defined in terms of named predicates, instead of lambdas. I am currently No Good at DCGs, but I'll write something similar to what I think you're first test does and hopefully you can figure out how to adapt it.
> :- pred pass_test(test_disposition::out) is det.
> pass_test(Disposition) :-
> Disposition = pass.
>
> :- pred fail_test(test_disposition::out) is det.
> fail_test(Disposition) :-
> Disposition = fail("Fail tests aways Fail").
>
> :- pred name_start_test(test_disposition::out) is det.
> name_start_test(Disposition) :-
> nameStartChar(":someString" OutStartChar),
> (
> if OutStartChar = ":"
> then Disposition = pass
> else Disposition = fail("Expected StartChar to be : But got " ++ OutStartChar ++ " instead"
> ).
>
>
> TestList = [
> test_case("PassTest", pass_test),
> test_case("FailTest", fail_test),
> test_case("NameStartTest), name_start_test)
> ]
>
>
> the if...then...else in name_start_test could have been a call to assertions.are_equal instead:
> name_start_test(Disposition)
> nameStartChar(":someString", OutStartChar),
> assertions.are_equal(univ(":"), univ(OutStartChar), Disposition).
>
>
> Cheers!
>
> Charles
More information about the users
mailing list