wwt / SwiftCurrent

A library for managing complex workflows in Swift

Home Page:https://wwt.github.io/SwiftCurrent/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better Test Experience

Tyler-Keith-Thompson opened this issue · comments

Is your feature request related to a problem? Please describe.

I'm frustrated by the current test experience Workflow provides.

Describe the solution you'd like

I want easy ways of making sure that workflows were launched, that they contain the representables expected, that it's easy to swap out what their proceed function does from tests. I think we need to look closely at developer experience, what makes the library a joy to test?

Describe alternatives you've considered

Mocking? (Workflow is final)
Some horrible thing where I @testable import Workflow and try to pick at its innards? Not ideal...

Additional context

We should also stick to our creed about not just changing production code for the sake of tests, where reasonable.

No clue how to pull it off but here's an idea of how I would like to interact with an API for testing Workflows

// Make sure a Workflow launched
let expectedWorkflow = Workflow(FR1.self).thenProceed(with: FR2.self, persistence: .removedAfterProceeding)
testViewController.doThingThatShouldTriggerAWorkflowLaunch()
XCTAssertWorkflowLaunched(expectedWorkflow)
// Assertion is smart enough to make sure that specific workflow was launched with correct persistence, does not necessarily have to be thread safe but should be able to handle 2 workflows launching and distinguishing which one to assert on, totally fine if I have to pass an index:
XCTAssertWorkflowLaunched(expectedWorkflow, launchIndex: 0) // first workflow launched should've been this one
// ADDITIONAL Params
// LaunchStyle (to assert it was launched with a particular style)
// Args (the args we expect it to launch with, to use this parameter Args must be equatable)

// Make sure proceed is called when expected
let fr1 = topViewController() as! FR1
let exp = expectation("proceedCalled")
fr1.proceedInWorkflow = { // this closure smart enough to either have no argument if Output == Never or typed output
   exp.fullfill()
}
fr1.tapSomeButtonWeExpectShouldProceed()
wait(for: [exp], timeout: 0.1)

We agree that there should be a better testing experience. We' created a milestone to track it and will address this feature when we start work on that milestone. Thank you for the idea on how it could look like to interact with it.

I started a branch called testing-package that did successfully clean up some cruft. However, I ran into some issues with Xcode. Essentially, while building the SwiftUIExampleTests works if you use the SwiftUIExample target, it does not work from the SwiftCurrent target. I feel like this is some SPM thing we have to deal with. The same problem happened with every hosted app, so SwiftCurrent_UIKitTests, SwiftUIExample, and UIKitExample all have problems but only when we try to run tests from the SwiftCurrent target.

I'm leaving the branch around in case it helps anybody, but am abandoning work on it for a while.