SwiftCheck
QuickCheck for Swift.
For those already familiar with the Haskell library, check out the source. For
everybody else, see the Tutorial Playground for a
beginner-level introduction to the major concepts and use-cases of this library.
Introduction
SwiftCheck is a testing library that automatically generates random data for
testing of program properties. A property is a particular facet of an algorithm
or data structure that must be invariant under a given set of input data,
basically an XCTAssert
on steroids. Where before all we could do was define
methods prefixed by test
and assert, SwiftCheck allows program properties and
tests to be treated like data.
To define a program property the forAll
quantifier is used with a type
signature like (A, B, C, ... Z) -> Testable where A : Arbitrary, B : Arbitrary ... Z : Arbitrary
. SwiftCheck implements the Arbitrary
protocol for most Swift
Standard Library types and implements the Testable
protocol for Bool
and
several other related types. For example, if we wanted to test the property
that every Integer is equal to itself, we would express it as such:
For a less contrived example, here is a program property that tests whether
Array identity holds under double reversal:
Because SwiftCheck doesn't require tests to return Bool
, just Testable
, we
can produce tests for complex properties with ease:
Properties can even depend on other properties:
All you have to figure out is what to test. SwiftCheck will handle the rest.
Shrinking
What makes QuickCheck unique is the notion of shrinking test cases. When fuzz
testing with arbitrary data, rather than simply halt on a failing test, SwiftCheck
will begin whittling the data that causes the test to fail down to a minimal
counterexample.
For example, the following function uses the Sieve of Eratosthenes to generate
a list of primes less than some n:
We would like to test whether our sieve works properly, so we run it through
SwiftCheck with the following property:
Which produces the following in our testing log:
Test Case '-[SwiftCheckTests.PrimeSpec testAll]' started.
*** Failed! Falsifiable (after 10 tests):
4
Indicating that our sieve has failed on the input number 4. A quick look back
at the comments describing the sieve reveals the mistake immediately:
Running SwiftCheck again reports a successful sieve of all 100 random cases:
*** Passed 100 tests
Custom Types
SwiftCheck implements random generation for most of the types in the Swift
Standard Library. Any custom types that wish to take part in testing must
conform to the included Arbitrary
protocol. For the majority of types, this
means providing a custom means of generating random data and shrinking down to
an empty array.
For example:
There's also a Gen.compose
method which allows you to procedurally compose
values from multiple generators to construct instances of a type:
Gen.compose
can also be used with types that can only be customized with setters:
For everything else, SwiftCheck defines a number of combinators to make working
with custom generators as simple as possible:
For instances of many complex or "real world" generators, see
ComplexSpec.swift
.
System Requirements
SwiftCheck supports OS X 10.9+ and iOS 7.0+.
Setup
SwiftCheck can be included one of two ways:
Using The Swift Package Manager
- Add SwiftCheck to your
Package.swift
file's dependencies section:
Using Carthage
- Add SwiftCheck to your Cartfile
- Run
carthage update
- Drag the relevant copy of SwiftCheck into your project.
- Expand the Link Binary With Libraries phase
- Click the + and add SwiftCheck
- Click the + at the top left corner to add a Copy Files build phase
- Set the directory to
Frameworks
- Click the + and add SwiftCheck
Using CocoaPods
- Add our Pod to your podfile.
- Run
$ pod install
in your project directory.
Framework
- Drag SwiftCheck.xcodeproj into your project tree
as a subproject - Under your project's Build Phases, expand Target Dependencies
- Click the + and add SwiftCheck
- Expand the Link Binary With Libraries phase
- Click the + and add SwiftCheck
- Click the + at the top left corner to add a Copy Files build phase
- Set the directory to Frameworks
- Click the + and add SwiftCheck
License
SwiftCheck is released under the MIT license.