Skip to content

Releases: Quick/Quick

v7.0.0 - AsyncSpec and Human-Readable Test Selectors

20 May 18:18
Compare
Choose a tag to compare

Highlights

Async Test Changes

Quick 7 changes how Async tests are run. Instead of forcing all tests to run in an async context, Quick 7 provides a separate Spec class for Async Tests. Create an AsyncSpec subclass, and all tests inside of that subclass will run in an async context. Tests inside of QuickSpec subclasses will have a similar behavior to what was in Quick 5.

Additionally, Quick 7 changes how the DSL is defined slightly. In Quick 6 and before, the DSL was defined as a series of global functions, available to be called anywhere. In Quick 7, these functions were moved to be static methods on the new SyncDSLUser (which QuickSpec, Behavior, and QuickConfiguration conform to) and AsyncDSLUser (which AsyncSpec and AsyncBehavior conform to) protocols. This allows us to make sure that you are using the correct DSL for the context, and was necessary for this approach.

For example:

class SynchronousSpec: QuickSpec {
    override class func spec() {
        it("runs synchronously, as you'd expect") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

actor OceanActor<T> {
    var contents: [T] = []
    func append(_ value: T) {
        contents.append(value)
    }
}

class AsynchronousSpec: AsyncSpec {
    override class func spec() {
        it("runs the test in an async context") {
            let ocean = OceanActor<String>()
            Task {
                await ocean.append("dolphins")
                await ocean.append("whales")
            }
            await expect { await ocean.contents }.toEventually(contain("dolphins", "whales"))
        }
    }
}

Unencoded Test Selectors

Furthermore, Quick 7 changes how test selectors are generated for QuickSpec. Now, both AsyncSpec and QuickSpec will use the unencoded test names as the test selectors. Test selectors are now generated by joining the describe/context blocks leading up to the it block with ", ". This makes test names immensely easier to read. For example, with the following spec:

class MySpec: QuickSpec {
    override class func spec() {
        describe("some feature") {
            context("in one case") {
                it("has a behavior") {}
            }

            context("in another case") {
                it("doesn't have the earlier behavior") {}
            }
        }
    }
}

will generate the following test selectors:

  • some feature, in one case, has a behavior
  • some feature, in another case, doesn't have the earlier behavior

You can disable this change by setting the QUICK_USE_ENCODED_TEST_SELECTOR_NAMES environment variable.

Migrating Suggestions

Quick 7 is not a drop-in migration from either Quick 5 or Quick 6. Quick 5 users will have a slightly easier time upgrading, but due to spec being defined as a class method instead of an instance method, there will still be changes.

Doing a Find & Replace of override func spec with override class func spec will take care of the low-hanging fruit. If you have any test helpers that exist as properties or methods of your QuickSpec subclasses, the you will need to either move them inside of the spec function, or outside to another scope. For Objective-C users, this is, for the most part, a drop-in replacement. You will only need to do anything if you do not use the QuickSpecBegin and QuickSpecEnd macros (in which case: do a find & replace of the regex -(\s*)\(void\)(\s*)spec with +$1(void)$2spec).

For migrating from Quick 6 to Quick 7, it would be easiest to also do a Find & Replace of : QuickSpec to : AsyncSpec, then migrate tests that do not need to run in async contexts to be QuickSpecs themselves.

Auto-Generated Changelog

What's Changed

New Contributors

Full Changelog: v6.1.0...v7.0.0

v7.0.0-beta.3

27 Apr 15:52
2fcf827
Compare
Choose a tag to compare
v7.0.0-beta.3 Pre-release
Pre-release

Beta 3 Changes

Quick 7 Beta 3 adds a flag to re-enable the encoded test selector names. This is useful for automated test analysis tools which track tests over time or are broken with the new human-readable test selectors.

Set the QUICK_USE_ENCODED_TEST_SELECTOR_NAMES environment variable and Quick will generate the older-style encoded test selector names (all non alpha-numeric characters will be replaced with underscores).

Thanks to @tikitu and @stonko1994 for their help prioritizing adding this flag.

As with previous betas, we encourage you to check this out, and to share feedback by filing an issue or discussing this in the discussion page.

Beta 2 Changes

Quick 7 Beta 2 changes how test selectors are generated for QuickSpec. Now, both AsyncSpec and QuickSpec will use the unencoded test names as the test selectors. Test selectors are now generated by joining the describe/context blocks leading up to the it block with ", ". This makes test names immensely easier to read. For example, with the following spec:

class MySpec: QuickSpec {
    override class func spec() {
        describe("some feature") {
            context("in one case") {
                it("has a behavior") {}
            }

            context("in another case") {
                it("doesn't have the earlier behavior") {}
            }
        }
    }
}

will generate the following test selectors:

  • some feature, in one case, has a behavior
  • some feature, in another case, doesn't have the earlier behavior

Beta 1 Changes

Quick 7 changes how Async tests are run. Instead of forcing all tests to run in an async context, Quick 7 provides a separate Spec class for Async Tests. Create an AsyncSpec subclass, and all tests inside of that subclass will run in an async context. Tests inside of QuickSpec subclasses will have a similar behavior to what was in Quick 5.

Additionally, Quick 7 changes how the DSL is defined slightly. In Quick 6 and before, the DSL was defined as a series of global functions, available to be called anywhere. In Quick 7, these functions were moved to be static methods on the new SyncDSLUser (which QuickSpec, Behavior, and QuickConfiguration conform to) and AsyncDSLUser (which AsyncSpec and AsyncBehavior conform to) protocols. This allows us to make sure that you are using the correct DSL for the context, and was necessary for this approach.

For example:

class SynchronousSpec: QuickSpec {
    override class func spec() {
        it("runs synchronously, as you'd expect") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

class AsynchronousSpec: AsyncSpec {
    override class func spec() {
        it("runs the test in an async context") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            await expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

Doing a Find & Replace of override func spec with override class func spec will take care of this. If you have any test helpers that exist on properties of your QuickSpec subclasses, the you will need to either move them inside of the spec function, or outside to another scope. For Objective-C users, this is, for the most part, a drop-in replacement. You will only need to do anything if you do not use the QuickSpecBegin and QuickSpecEnd macros (in which case: do a find & replace of the regex -(\s*)\(void\)(\s*)spec with +$1(void)$2spec).

For migrating from Quick 6 to Quick 7, it would be easiest to also do a Find & Replace of : QuickSpec to : AsyncSpec, then migrate tests that do not need to run in async contexts to be QuickSpecs themselves.

We encourage you to check this out, and to share feedback by filing an issue or discussing this in the discussions.

Auto-Generated Changelog

Beta 3 Changes

  • Add mechanism to fallback to legacy test selector names by @younata in #1211
  • Don't imply that we plan to remove the option to force encoded test selector names by @younata in #1212

Beta 2 Changes

New Contributors

Full Changelog: v7.0.0-beta.2...v7.0.0-beta.3

v7.0.0 beta 2

23 Apr 18:40
Compare
Choose a tag to compare
v7.0.0 beta 2 Pre-release
Pre-release

Quick 7 Beta 2 changes how test selectors are generated for QuickSpec. Now, both AsyncSpec and QuickSpec will use the unencoded test names as the test selectors. Test selectors are now generated by joining the describe/context blocks leading up to the it block with ", ". This makes test names immensely easier to read. For example, with the following spec:

class MySpec: QuickSpec {
    override class func spec() {
        describe("some feature") {
            context("in one case") {
                it("has a behavior") {}
            }

            context("in another case") {
                it("doesn't have the earlier behavior") {}
            }
        }
    }
}

will generate the following test selectors:

  • some feature, in one case, has a behavior
  • some feature, in another case, doesn't have the earlier behavior

As with Beta 1, we encourage you to check this out, and to share feedback by filing an issue or discussing this in the discussion page.

Beta 1 Changes

Quick 7 changes how Async tests are run. Instead of forcing all tests to run in an async context, Quick 7 provides a separate Spec class for Async Tests. Create an AsyncSpec subclass, and all tests inside of that subclass will run in an async context. Tests inside of QuickSpec subclasses will have a similar behavior to what was in Quick 5.

Additionally, Quick 7 changes how the DSL is defined slightly. In Quick 6 and before, the DSL was defined as a series of global functions, available to be called anywhere. In Quick 7, these functions were moved to be static methods on the new SyncDSLUser (which QuickSpec, Behavior, and QuickConfiguration conform to) and AsyncDSLUser (which AsyncSpec and AsyncBehavior conform to) protocols. This allows us to make sure that you are using the correct DSL for the context, and was necessary for this approach.

For example:

class SynchronousSpec: QuickSpec {
    override class func spec() {
        it("runs synchronously, as you'd expect") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

class AsynchronousSpec: AsyncSpec {
    override class func spec() {
        it("runs the test in an async context") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            await expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

We encourage you to check this out, and to share feedback by filing an issue or discussing this in the discussions.

Auto-Generated Changelog

What's Changed

New Contributors

Full Changelog: v7.0.0-beta.1...v7.0.0-beta.2

v7.0.0 Beta 1

14 Apr 15:57
Compare
Choose a tag to compare
v7.0.0 Beta 1 Pre-release
Pre-release

Quick 7 changes how Async tests are run. Instead of forcing all tests to run in an async context, Quick 7 provides a separate Spec class for Async Tests. Create an AsyncSpec subclass, and all tests inside of that subclass will run in an async context. Tests inside of QuickSpec subclasses will have a similar behavior to what was in Quick 5.

Additionally, Quick 7 changes how the DSL is defined slightly. In Quick 6 and before, the DSL was defined as a series of global functions, available to be called anywhere. In Quick 7, these functions were moved to be static methods on the new SyncDSLUser (which QuickSpec, Behavior, and QuickConfiguration conform to) and AsyncDSLUser (which AsyncSpec and AsyncBehavior conform to) protocols. This allows us to make sure that you are using the correct DSL for the context, and was necessary for this approach.

For example:

class SynchronousSpec: QuickSpec {
    override class func spec() {
        it("runs synchronously, as you'd expect") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

class AsynchronousSpec: AsyncSpec {
    override class func spec() {
        it("runs the test in an async context") {
            var ocean: [String] = []
            DispatchQueue.main.async {
                ocean.append("dolphins")
                ocean.append("whales")
            }
            await expect(ocean).toEventually(contain("dolphins", "whales"))
        }
    }
}

We encourage you to check this out, and to share feedback by filing an issue or discussing this in the discussions.

Full Changelog: v6.1.0...v7.0.0-beta.1

v6.1.0

25 Nov 21:05
Compare
Choose a tag to compare

Highlighted Changes

  • New TestState property wrapper (Thanks @CraigSiemens!). You can now wrap properties with @TestState to have them automatically set to nil.
  • Objective-C API is no longer available in Swift, this should reduce confusion whether a test is being executed in an async context or not.
  • This release drops support for Swift 5.6/Xcode 13.3.1.

Auto-generated Release Notes

What's Changed

  • Bump danger from 9.0.0 to 9.1.0 by @dependabot in #1184
  • Make Objective-C API unavailable in Swift. by @younata in #1185
  • Update Nimble to 11.2.1, remove now-unnecessary usage of awaits in tests. Drop support for swift 5.6/Xcode 13.3.1 by @younata in #1187
  • Added a TestState property wrapper. by @CraigSiemens in #1186

New Contributors

Full Changelog: v6.0.1...v6.1.0

v6.0.1

11 Nov 07:07
Compare
Choose a tag to compare

What's Changed

  • Force async in fit, xit, pending and justBeforeEach by @younata in #1183

Full Changelog: v6.0.0...v6.0.1

v6.0.0

01 Nov 04:14
Compare
Choose a tag to compare

This closes the v6.0.0 milestone.

Highlights

See additional details under the auto-generated release notes below.

Fixed

  • No more sporadic crashes attempting to detect subclasses #1156
  • Rerunning an individual test #1166
  • Skipped tests are reported to Xcode #1098

New

  • Async/await support. All tests now run in an async context. #1160
  • You can now throw a StopTest error to end a test prematurely without it being reported as an error. #1165
  • Added the justBeforeEach operator, which takes a closure and runs it immediately prior to the relevant it tests. #1169 For example
var ordering: [Int] = []
beforeEach {
    ordering.append(1)
}

justBeforeEach {
    ordering.append(3)
}

beforeEach {
    ordering.append(2)
}

it("runs justBeforeEach after the other beforeEach's") {
    expect(ordering).to(equal([1, 2, 3]))
}

Breaking

  • This version raises minimum required version to Swift 5.6, and required OS to macOS 10.15, iOS 13, and tvOS 13.
  • aroundEach is removed from the Objective-C API #1160
  • Again, with the async support, all tests now run in an async context. This will require you to make changes, especially if you use Nimble.

Auto-Generated Release Notes

What's Changed

New Contributors

Full Changelog: v5.0.1...v6.0.0

v5.0.1

19 Apr 18:04
f9d5198
Compare
Choose a tag to compare

This release closes the v5.0.1 milestone.

What's Changed

Full Changelog: v5.0.0...v5.0.1

v5.0.0

15 Apr 19:48
6a3d1f5
Compare
Choose a tag to compare

This release closes the v5.0.0 milestone.

Highlights

See additional details under the auto-generated release notes below.

Fixed

  • Tests not discoverable or cannot fail in Xcode 13.3 #1123, #1129

New

Breaking

  • Rename Configuration -> QCKConfiguration #1133
  • Make FilterFlags implementation detail #1068

Auto-generated release notes

What's Changed

New Contributors

Full Changelog: v4.0.0...v5.0.0

v4.0.0

08 May 00:40
v4.0.0
Compare
Choose a tag to compare

Quick v4 has been released! 🎉 The new major version requires Swift 5.2 / Xcode 11.4 at least.

BREAKING CHANGES

  • Bump minimum iOS version to 9.0 #1013
  • Rename master branch to main #1052

Changes

  • [CI] Test Xcode 12 and Swift 5.3 #1010
  • Set ENABLE_TESTING_SEARCH_PATHS to YES #1011
  • Upgrade Project Format to Xcode 11.4-compatible #1012 (Thanks @mRs-)
  • [CI] Use rake directly instead of travis-script-macos #1019
  • Update Nimble to 9.1.0 #1020, #1062, #1066
  • Xcode 12.0: Update to recommended settings #1021
  • Address deprecation warnings in Xcode 12 #1040
  • Migrate Linux CI from Travis to GitHub Actions #1042
  • [CI] Use norionomura/swift Docker images for Linux CI #1043
  • [SwiftLint] Enable yoda_condition rule #1044
  • [CI] Use the official Swift Docker images #1049
  • [CI] Split ci.yml into dedicated workflows #1050
  • Tweak CI workflows regarding fkirc/skip-duplicate-actions and matrix testing #1051
  • Xcode 12.5: Update to recommended settings #1063
  • [CI] Update Xcode and Swift versions #1064

Documentation Changes

  • vieiwDidAppear not be called automatically in iOS SDK 13.0 #942 (Thanks @nickm01)
  • [Translation] Update Chinese README.md #1053 (Thanks @EdgarDegas)

Miscellaneous