Skip to content

lifepillar/ASUnit

Repository files navigation

ASUnit Logo

ASUnit

ASUnit is a unit testing framework for AppleScript derived from the original codebase1. For a detailed description of the architecture of the original ASUnit framework, read the old manual; some advanced features of ASUnit (such as custom TestCase and Visitor objects) are still described only in that document.

ASUnit's API is now thoroughly commented using HeaderDoc.

Download

Visit Releases to download the current release.

Alternatively, clone the repository from GitHub:

git clone https://github.com/lifepillar/ASUnit.git

Advanced Download Method

If for some reason you want to download a specific version of ASUnit from the terminal or with a shell script, you may adapt the following commands:

VERSION="1.2.5"
TARBALL="${VERSION}.tar.gz"
ASUNIT_BASE_URL="https://github.com/lifepillar/ASUnit/"
TARBALL_URL="${ASUNIT_BASE_URL}/archive/refs/tags/${TARBALL}"
cd ~/Downloads
curl -O "${TARBALL_URL}"
tar zxvf "${TARBALL}"

Or, if you prefer a Zip archive:

VERSION="1.2.5"
ZIPFILE="${VERSION}.zip"
ASUNIT_BASE_URL="https://github.com/lifepillar/ASUnit/"
ZIPFILE_URL="${ASUNIT_BASE_URL}/archive/refs/tags/${ZIPFILE}"
cd ~/Downloads
curl -O "${ZIPFILE_URL}"
unzip "${ZIPFILE}"

Change VERSION above to match the version you want to download.

Install

Once you have downloaded ASUnit, to build and install it you may proceed in two different ways.

  1. If you use AppleScript 2.4 (OS X 10.10 "Yosemite") or later and have installed ASMake, you may just write:
cd ASUnit
./asmake install
  1. Otherwise, you can install it manually with the following commands:
cd ASUnit
osacompile -o ASUnit.scptd -x ASUnit.applescript
mkdir -p "${HOME}/Library/Script Libraries/com.lifepillar"
mv ASUnit.scptd "${HOME}/Library/Script Libraries/com.lifepillar"

In either case, the file ASUnit.scptd will be installed in ~/Library/Script Libraries/com.lifepillar.

Importing ASUnit

To use ASUnit, add one of the two properties below to your script in order to import the library.

If you have AppleScript 2.3 (OS X 10.9 "Mavericks") or later, use this:

property parent : script "com.lifepillar/ASUnit"

If you have an older, pre-Mavericks system, use this instead:

property parent : ¬
  load script (((path to library folder from user domain) as text) ¬
    & "Script Libraries:com.lifepillar:ASUnit.scptd") as alias

Running Tests

Your test script must define a suite property and pass it to ASUnit's autorun() handler:

property suite : makeTestSuite("A description for my tests")
autorun(suite)

You may run the test script in various ways: inside Script Editor, from the command-line using osascript, or in other environments (Script Debugger, AppleScriptObjC Explorer).

When you have several test files, you may run them all at once using a test loader (there is no need to compile them in advance). See Test Loader.applescript in the examples folder.

Logging

By default, if you run the tests in Script Editor, the output is written to a new Script Editor document; if you run the tests in the Terminal, the output is sent to stdout; otherwise, the output is sent to the current system logger through log statements; access them via Console.

You may, however, change this by setting the suite's loggers property. The value of this property must be a list of loggers (you may send the output to more than one destination). Currently, ASUnit defines three loggers:

  • AppleScriptEditorLogger: sends colored output to a Script Editor window;
  • StdoutLogger: sends colored output to stdout.
  • ConsoleLogger: prints the output using log statements (most portable logger).

Defining custom loggers should be fairly easy: you simply need to define a script that inherits from TestLogger and override the print…() handlers to generate the output you want. A more advanced alternative consists in subclassing Visitor: you may find an example in the old manual.

Writing Tests

A test template is provided in the templates folder. See the examples folder for complete examples. The general structure of a test script is as follows:

    script |One test set|
      property parent : TestSet(me)

      on setUp()
        -- Code executed before each unit test
      end

      on tearDown()
        -- Code executed after each unit test
      end

      script |a test|
        property parent : UnitTest(me)

        assert(1 + 1 = 2, "one plus one should be two")
        assertEqual(2, 1 + 1)
        refute(3 = 1 + 1, "1 + 1 should not be 3")
      end script

      script |another test|
        property parent : UnitTest(me)
        -- More assertions…
      end
    end script

    script |Another test set|
      property parent : TestSet(me)
       -- More tests…
    end

Each unit test is a script that inherits from UnitTest(me). Inside such scripts, you may make a number of assertions.

Assertions

Below, “iff” stands for “if and only if”.

  • skip(msg): skips the current test.
  • fail(msg): makes the test unconditionally fail.
  • ok(expr): succeeds iff the boolean expr evaluates to true.
  • notOk(expr): succeeds iff expr evaluates to false.
  • assert(expr, msg) or should(expr, msg): succeeds iff expr is true.
  • refute(expr, msg) or shouldnt(expr, msg): succeeds iff expr is false.
  • shouldRaise(num, object, msg): succeeds iff object raises exception num when executed. The object can be a script object or a handler without parameters.
  • shouldNotRaise(num, object, msg): succeeds iff object does not raise exception num when executed. The object can be a script object or a handler without parameters.
  • assertEqual(expr, value) or shouldEqual(expr, value): succeeds iff expr = value.
  • refuteEqual(expr, value) or shouldNotEqual(expr, value): succeeds iff exprvalue.
  • assertMissing(expr): a synonym for assertEqual(missing value, expr).
  • assertObjCReference(expr): succeeds iff expr is a reference to a Cocoa object.
  • refuteObjCReference(expr): succeeds iff expr is not a reference to a Cocoa object.
  • refuteMissing(expr): a synonym for assertNotEqual(missing value, expr).
  • assertNull(expr): a synonym for assertEqual(null, expr).
  • refuteNull(expr): a synonym for assertNotEqual(null, expr).
  • assertEqualAbsError(e1, e2, delta): succeeds iff |e1-e2| <= delta.
  • assertEqualRelError(e1, e2, eps): succeeds iff |e1-e2| <= min(|e1|,|e2|) * eps.
  • assertReference(x) or shouldBeReference(x): succeeds iff x is a reference.
  • assertNotReference(x) or shouldNotBeReference(x): succeeds iff x is not a reference.
  • assertInstanceOf(aClass, expr): succeeds iff the class of expr is equal to aClass.
  • refuteInstanceOf(aClass, expr): succeeds iff the class of expr is not aClass.
  • assertKindOf(aClass, expr): succeeds iff expr or any of its ancestors belongs to aClass.
  • refuteKindOf(aClass, expr): succeeds iff neither expr nor any of its ancestors belong to aClass.
  • assertInheritsFrom(a, b): succeeds iff b (directly or indirectly) inherits from a.
  • refuteInheritsFrom(a, b): succeeds iff b does not inherit from a.

Some of the assertions take a textual message as an argument (msg parameter), which is printed when the assertion fails.

A clarification is in order for the last three types of assertions. Consider the following two scripts:

    script A
      property class : "Father"
    end script

    script B
      property parent : A
      property class : "Child"
    end script

Then, these assertions must succeed:

    assertInstanceOf("Father", A)
    assertInstanceOf("Child", B)
    refuteInstanceOf("Father", B)
    assertKindOf("Father", B)
    refuteInstanceOf(script, A)
    assertKindOf(script, A)
    assertInheritsFrom(A, B)
    refuteInheritsFrom(B, A)

Related unit tests can be grouped together into a script that must inherit from TestSet(me). One advantage of grouping tests is that you may define setUp() and tearDown() operations that are automatically executed before and after each unit test, respectively. Such handlers can be used for initialization of data structures and clean up operations, and help ensure that each unit test is not affected by the behavior of the others.

Note that the names of the scripts are used in the output. For this reason, you may want to use short sentences enclosed between vertical bars as script names, as it was done in the example above. Alternatively, you may define the name property of the script explicitly.

Copyright

Copyright © 2013 Lifepillar, 2006 Nir Soffer. All rights reserved.

License

This software is licensed under the GNU GPL-2.0 License, see COPYING for details.

Footnotes

  1. The original framework codebase was written by Nir Soffer.

About

AppleScript unit testing framework (originally written by Nir Soffer)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •