Question

I am trying to use QuickCheck (for the first time) to test a function that validates TCP port numbers:

validatePort :: Int -> Either String Int
validatePort port =
  if port > 0 && port <= 65535
    then Right port
    else Left "Port must be between 1 and 65535 inclusive"

I wrote an instance of Arbitrary like this:

instance Arbitrary Int where
  arbitrary = choose (1, 65535)

but I'm not sure how to write the test property.

Was it helpful?

Solution

As a starting point, first: import Test.QuickCheck which already defines Arbitrary instance for Int

Then write a property:

prop_validate_port port = 
  if   port > 0 && port <= 65535
  then validatePort port == Right port
  else validatePort port == Left "Port must be between 1 and 65535 inclusive"

And run the test:

>quickCheck prop_validate_port
>+++ OK. passed 100 tests.

OTHER TIPS

Just as an addendum to jev's answer, you can also enjoy a loosely-coupled testing framework by using custom Gens:

validPorts :: Gen Int
validPorts = choose (1, 65535)

invalidPorts :: Gen Int
invalidPorts = oneof [choose (minBound, 0), choose (65536, maxBound)]

prop_validatePortValidatesValidPorts = 
  forAll validPorts (\port -> validatePort port == Right port)

prop_validatePortDoesNotValidateInvalidPorts =
  forAll invalidPorts (\port -> validatePort port == Left "...")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top