The Wayback Machine - https://web.archive.org/web/20200614083735/https://github.com/Quick/Quick/issues/890
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docuementation for data-driven examples #890

Open
pobengtsson opened this issue May 18, 2019 · 2 comments · May be fixed by #940
Open

Docuementation for data-driven examples #890

pobengtsson opened this issue May 18, 2019 · 2 comments · May be fixed by #940

Comments

@pobengtsson
Copy link
Contributor

@pobengtsson pobengtsson commented May 18, 2019

  • I have read CONTRIBUTING and have done my best to follow them.

Hi, thanks for making Quick and Nimble,

I don't write any swift code in my project without some examples/tests in Quick/Nimble. I feature that I was missing from how I could use e.g. Jasmine or scalatest, was to do data-driven specs.

For a long period I thought it wasn't possible as I couldn't find any examples in the documentation or on the internet. A short while back, I thought I'd give it one more try and if there was something preventing success, file an issue. To my great joy, I found a way that just worked. :)
(I wrote about this on my blog found here)

if the maintainers consider this way of writing tests supported over time and versions, I am willing put together a documentation PR including an example of data-drive tests using Quick for fellow coders' benefit.

What is your view?

Code example for how to drive tests with data

import Quick
import Nimble

func double(_ value : Int) -> Int { return 2*value }

class QuickDataDrivenTests: QuickSpec {
    override func spec() {
        describe("the double function") {
            let specified_examples : [(input: Int, output: Int)] = [
                (input: 0, output: 0),
                (input: 1, output: 2),
                (input: 2, output: 4)
            ]
            specified_examples.forEach { (input: Int, output: Int) in
                context("for input \(input) and output \(output) ") {
                    var for_each_executed_with_input : Int?
                    beforeEach {
                        for_each_executed_with_input = input
                    }
                    it("should execute the beforeEach") {
                        expect(for_each_executed_with_input).toNot(beNil())
                    }
                    it("should execute the before each with each entry") {
                        expect(for_each_executed_with_input).to(equal(input))
                    }
                    it("should double the input for output") {
                        expect(double(input)).to(equal(output))
                    }
                }
            }
        }
    }
}

Versions I tested it on

  • Quick: 2.0
  • Nimble: Nimble 8.0
  • Xcode Version: 10.2.1
  • Swift Version: 4.2 and 5.0

Please also mention which package manager you used and its version. Delete the
other package managers in this list:

  • Cocoapods: 1.5.3
@revolter
Copy link
Contributor

@revolter revolter commented Oct 28, 2019

Thank you very much for the example!

I changed it a bit to:

import Quick
import Nimble

func double(_ value : Int) -> Int { return 2*value }

class TestData<T> {

    public let context: String
    public let input: T
    public let output: T
    public let line: UInt

    init(input: T, output: T, line: UInt = #line) {
        self.input = input
        self.output = output
        self.line = line

        self.context = "for input \(self.input) and output \(self.output)"
    }
}

class QuickDataDrivenTests: QuickSpec {
    override func spec() {
        describe("the double function") {
            let dataSet = [
                TestData<Int>(input: 0, output: 0),
                TestData<Int>(input: 1, output: 2),
                TestData<Int>(input: 2, output: 4)
            ]
            dataSet.forEach { (data) in
                context(data.context) {
                    var for_each_executed_with_input : Int?

                    beforeEach {
                        for_each_executed_with_input = data.input
                    }

                    it("should execute the beforeEach", line: data.line) {
                        expect(for_each_executed_with_input, line: data.line).toNot(beNil())
                    }

                    it("should execute the before each with each entry", line: data.line) {
                        expect(for_each_executed_with_input, line: data.line).to(equal(data.input))
                    }

                    it("should double the input for output", line: data.line) {
                        expect(double(input), line: data.line).to(equal(data.output))
                    }
                }
            }
        }
    }
}

This way, when a test fail, Xcode marks with red the line where the test's TestData was initialized, instead of marking the same expect line for every test data.

@pobengtsson
Copy link
Contributor Author

@pobengtsson pobengtsson commented Nov 8, 2019

Line references was a cool addition, that improves the whole thing. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants
You can’t perform that action at this time.