/SwiftDocTest

DocTest for Swift

Primary LanguagePythonBSD 2-Clause "Simplified" LicenseBSD-2-Clause

SwiftDocTest

DocTest for Swift

Generates UnitTests from Swift doc-comments.

Very much inspired by Python's doctest module

See NSHipster for information on Swift's doc-comment format

Why?

Writing python doctests is extremely easy and incredibly fast. I wondered if I could bring something similar to swift, it turns out it wasn't too hard to get a proof of concept.

The advantages of doctests are:

  • Unit tests are right next to the code being tested. (This can help obviate the need for code coverage - which is good because swift has no code coverage tools yet).
  • Unit tests are documentation. Two birds one stone. Doctests effectively do double duty as examples of how to use the API and runnable unit tests.
  • Doctests are extremely terse, with little room for additional setup. This can help encourage smaller, more atomic, easier to test code.

The disadvantages:

  • Doctests are extremely terse. You're not really going to be happy unit testing complex code.
  • The tools aren't aware of doctests yet. Maybe an Xcode plugin can help here?
  • The workflow is a bit labour intensive. You need to run the swiftdoctest command line every time you update your docs.

Warning!

This code is very much just a proof of concept. But I tbink the technique is very interesting and has a lot of potential. Much more work is needed to make it robust.

If you like this idea but hate python - go away and rewrite this in whatever language you desire - but please take the concept further.

See: https://github.com/schwa/SwiftDocTest/issues/1

Installation

This is a python module so use pip to install. (You should be using virtual environments too. If you know what that means - great. If you don't - don't worry too much, you're probably a ruby person anyway).

    pip install --user git+https://github.com/schwa/SwiftDocTest.git

How to use

Decorate your Swift code with doc-comments containing unit tests. Each doc comment must contain one or more :test: segments and each :test: must have a corresponding expected :result:. The unit tests are generated in such a way that the test result is compared to your expected result. This means the the output of both segments must conform to the Comparable protocol.

/**
 :test:   floor(CGPoint(x:10.9, y:-10.5))
 :result: CGPoint(x:10, y:-11)
*/
public func floor(value:CGPoint) -> CGPoint {
    return value.map(floor)
}

/**
 :test:   ceil(CGPoint(x:10.9, y:-10.5))
 :result: CGPoint(x:11, y:-10)
*/
public func ceil(value:CGPoint) -> CGPoint {
    return value.map(ceil)
}

Run swiftdoc command line tool. By default it searches all swift files in the specified directory.

swiftdoc --output UnitTests --import FrameworkNameToImport .

Import the generated code into your Unit Test targets.

Yes, the process could do with more automagication.

CLI Usage

Usage: swiftdoc [OPTIONS] INPUT_DIR

  Produce unit test source files from correctly formatted Swift doc comments

Options:
  --output OUTPUT_DIR  Output directory for unit test files.
  --imports IMPORT     Imports to include in every Unit Test file.
  --help               Show this message and exit.