liveBook · Manning

Precondition

As explained in Functional Design and Architecture: Examples in Haskell

A precondition is an input condition that must hold before a user scenario or system operation begins.

A precondition is an input condition that must hold before a scenario or operation begins. In requirements, it records the state users or systems must establish before following the main path, while a postcondition records the expected result afterward. section 2.1.4

A scenario precondition

For a scenario that generates a new random world, “the game is launched” is the precondition. The user then opens the generation window, supplies a seed or world parameters, and starts generation; a new world is the postcondition. section 2.1.4

In property-based testing, preconditions filter generated inputs before the tested logic runs. A formally correct condition can still produce a poor test when the generator rarely creates acceptable values: QuickCheck may reject too many inputs and give up before exercising the implementation sufficiently. section 15.1.3

When a generated-input precondition is too selective, adjust the test strategy:

  • Generate values from a narrower type or provide a better Arbitrary instance. section 15.1.3
  • Remove the filter and include negative cases in the property being checked. section 15.1.3
  • Customize generation depth, run counts, or generated values so meaningful inputs reach the operation. section 15.1.3
Listing 15.5 Adjusting the test data generator
...
$ monadicIO $ do
   x :: Int <- pick arbitrary                        #1
   y :: Int <- pick arbitrary
  
   pre (x >= 4 && x <= 10 && y >= 4 && y <= 10)      #2
  
   let action = generateLabyrinth (x, y) 3 3         #3
  
   eLab <- run (try (runLangL coreRuntime action))   #4
  
   case eLab of                                      #5
     Left (err :: SomeException) -> assert False
     Right lab -> do
       let (x, y) = getBounds lab
       assert (x * y >= 16 && x * y <= 100)

This listing shows a precondition restricting generated dimensions to the valid range before labyrinth generation is executed. section 15.1.3

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Explains requirements-level meaning and property-testing failure mechanics, then lists generator adjustments without developing formal contract theory.
Examples
Uses a launched game, bounded labyrinth dimensions, arbitrary integer pairs, and QuickCheck rejection behavior as examples.
What it assumes
Assumes familiarity with user scenarios and generated test values while defining how entry conditions constrain both.
What you can do after
Diagnose property tests that reject excessive generated inputs and choose narrower, broader, or better-distributed test data.
How it connects
Connects preconditions with user scenarios, postconditions, requirements modeling, property-based testing, and test-data generation.

Also explained in

Compare how 8 books explain precondition →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.