In some cases we write functions that have a dual operation, for example *encode* and *decode*, *parse* and *pretty\_print*, or *convert\_to* and *convert\_from*.
Developing both functions at the same time gives an advantage when testing, since one of the properties that one is interested in is
encode(decode(X)) == X.
Surely, one could easily implement functions that guarantee this operation and are still doing the wrong thing, thus only this property is insufficient for testing. That said, it still is a good idea to also check this property and many bugs have been found by simple properties like this.
Erlang R12B has a module base64 in the standard library http://www.erlang.org/doc/man/base64.html. The module has a number of function, among which *encode* and *decode*.
We write the obvious property. Just read the manual: Encodes a plain ASCII string into base64. Use http://en.wikipedia.org/wiki/ASCII wikipedia to remind yourself that a plain ascii character is a value between 0 and 127. Extended ascii goes to 255.
prop_identity() -> ?FORALL(Data,list(plain_ascii_char()), base64:decode(base64:encode(Data)) == Data). plain_ascii_char() -> choose(0,127).
We can run QuickCheck to find out that we haven't specified ourself clear enough.
14> eqc:quickcheck(base64_eqc:prop_identity()). Failed! After 1 tests.  false
The authors of the module base64 allow the input of encode to be either a binary or a string, but the result is always a binary.