Unable to use when tests don't have access to sources (Xcode Cloud) #553
Replies: 29 comments 33 replies
-
Would it be possible to allow the use of run-time test path strings in |
Beta Was this translation helpful? Give feedback.
-
Also having this problem, a solution would be very much appreciated! |
Beta Was this translation helpful? Give feedback.
-
Our project is structured à la isowords, so we could work around the issue in this fashion: with a custom assertion that deduces the path to |
Beta Was this translation helpful? Give feedback.
-
I like @qmoya's solution and I think it's the best option sans changes to this library but it does mean we have to duplicate the |
Beta Was this translation helpful? Give feedback.
-
I experimented a bit with Xcode Cloud and ci_scripts - and I'll add my findings here - in case it can help someone in the future. I read that only contents within My second attempt was to create symbolic links to the My final approach is to have all my snapshots be placed under an And then instead of importing Here's my
One thing that I'm unsure about is how the environment propagates to the tests, so in my test scheme I had to manually forward CI as |
Beta Was this translation helpful? Give feedback.
-
Xcode Cloud is open now. Tried to use it, and that's how I have found this discussion. While some workarounds were probably ok when it was in beta, with bigger adoption it would be great to add some support to ease the pain of using snapshot tests on CI. |
Beta Was this translation helpful? Give feedback.
-
Symlinks are checked in, it’s a relative link so is able to be linked to
the snapshots directory.
I agree this library is very opinionated on where the files should be
located.
On Thu, 9 Jun 2022 at 13:57, Michal Laskowski ***@***.***> wrote:
Do you have a script that copies the files in ci_post_clone.sh, or just a
symlink that is checked into the directory? If the latter that would be
great.
But updating the library to handle that case better still stands ;)
(unless there is sth else I am not aware yet)
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SIHJXKFGQPUHAUKNZDVOHS4ZANCNFSM5KSOPA2A>
.
You are receiving this because you authored the thread.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/2913436@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
The ci_scripts directories and all sub directories are copied (following
any symlinks) to each test instance. We’ve been doing this for nearly a
year now and works fine for us.
The thing you have to do is feed the snapshot function an invalid file path
so that when the path elements get removed at runtime it ends up being the
correct file path to the ci_scripts directory. It’s a bit of trial and
error to get right hence opening this issue.
See
https://developer.apple.com/documentation/xcode/writing-custom-build-scripts
On Fri, 17 Jun 2022 at 20:15, Porter ***@***.***> wrote:
I can't figure out how to get this to work. I even tried putting the files
directly in ci_scripts but the test step in Xcode Cloud does not carry
over the files for me.
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SP55XXNPZ6A3N5SHHLVPTFEFANCNFSM5KSOPA2A>
.
You are receiving this because you authored the thread.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/2973898@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
Hi @mortenbekditlevsen @qmoya , private func snapshotDirectory(
for file: StaticString,
anchorRepoPathComponent: String = "Modules",
ciScriptsPathComponent: String = "ci_scripts",
snapshotsPathComponent: String = "__Snapshots__"
) -> String {
let fileURL = URL(fileURLWithPath: "\(file)", isDirectory: false)
let packageRootURL: URL = {
var newValue = fileURL
while newValue.lastPathComponent != anchorRepoPathComponent {
newValue = newValue.deletingLastPathComponent()
}
return newValue.deletingLastPathComponent()
}()
let testPathComponent = fileURL
.deletingPathExtension()
.lastPathComponent
let snapshotDirectoryPath = packageRootURL
.appendingPathComponent(ciScriptsPathComponent)
.appendingPathComponent(snapshotsPathComponent)
.appendingPathComponent(testPathComponent)
.path
print("snapshotDirectoryPath: \(snapshotDirectoryPath)")
return snapshotDirectoryPath
} |
Beta Was this translation helpful? Give feedback.
-
I was able to follow @cameroncooke comments and replicate on my side. No need for a custom ci_script, just create a symlink from ci_scripts to your screenshot destination - Xcode Cloud even copies recursive folders. Then use
The number of To get |
Beta Was this translation helpful? Give feedback.
-
I was able to make this work in a way similar to the proposed solutions, that is, by manually specifying the snapshot path in the
Did anybody encounter a similar problem? |
Beta Was this translation helpful? Give feedback.
-
Hmm... struggling with this still... I've tried @qmoya and @mortenbekditlevsen solutions but they both seem to be missing something. I'll keep going 👍🏻 |
Beta Was this translation helpful? Give feedback.
-
I use this at the moment. |
Beta Was this translation helpful? Give feedback.
-
We use Because Here is a basic example of what we're doing, though this can of course be optimised: final class ViewTests: XCTest {
let ciPath: StaticString = "/Volumes/workspace/repository/ci_scripts/SnapshotTests/ViewTests.swift"
let localPath: StaticString = #file
var isCIEnvironment: Bool { ... }
func testSomething() {
let view = View()
var filePath: StaticString
if isCIEnvironment {
filePath = ciPath
} else {
filePath = localPath
}
assertSnapshot(
matching: view,
file: filePath
)
}
} The key here is these two lines: let ciPath: StaticString = "/Volumes/workspace/repository/ci_scripts/resources/SnapshotTests/ViewTests.swift"
let localPath: StaticString = #file We have to ensure that the
On your local file-system the symlinks just act as aliases to the files at the target locations but Xcode Cloud "slurps" i.e. copies the target files and directories that the symlinks resolved to to the location of the symlink itself. If we inspected the
Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
So it’s not Xcode telling you they are no there it’s assertSnapshot()
function’s logic that’s saying it can’t find the images so I would suspect
the issue lies there as I see no reason why they wouldn’t be in the
ci_snapshots/ if you put them there.
On Wed, 5 Oct 2022 at 18:22, Oliver Foggin ***@***.***> wrote:
Ah, good idea, I'll do that now. Thanks.
The thing that makes me think they're not there is Xcode telling me it
can't find them there. It has the correct directory path and file name. It
just tells me it can't find the file.
😅
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SMTVNP6WXHNGWI7263WBW2MBANCNFSM5KSOPA2A>
.
You are receiving this because you were mentioned.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/3807522@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
The two paths look different to me one is missing the resources dir.
On Wed, 5 Oct 2022 at 19:09, Oliver Foggin ***@***.***> wrote:
OK, interesting. I'll have a look deeper at what's going on under the hood.
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SMA3NL5FVQDNJMYTZDWBW74XANCNFSM5KSOPA2A>
.
You are receiving this because you were mentioned.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/3807888@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
I’m not sure that is correct, when it says recording new snapshots and
gives a path to the new snapshot that directory of the new snapshot is the
location it was searching for and couldn’t fix the reference snapshot.
So this doesn’t look correct to me. They should be the same in my opinion.
On Wed, 5 Oct 2022 at 19:11, Oliver Foggin ***@***.***> wrote:
The one that is missing the resources directory is the file path to the
test file. Not the directory path of the snapshotDirectory.
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SNQ3XW7YSEIAY2DQBDWBXAFRANCNFSM5KSOPA2A>
.
You are receiving this because you were mentioned.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/3807903@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
OK... I logged out...
The first snapshot test it runs logs... "No file found". The second one logs... "ci_scripts". So something isn't taking that folder over to the test environment. |
Beta Was this translation helpful? Give feedback.
-
Oh man! I got there! @cameroncooke thanks so much for your help and comments. They got me there eventually. So...
Once that was done it all worked! Got there eventually. |
Beta Was this translation helpful? Give feedback.
-
Wow that’s subtle. I’m glad you got it sorted in the end.
On Wed, 5 Oct 2022 at 22:15, Oliver Foggin ***@***.***> wrote:
Oh man! I got there! @cameroncooke <https://github.com/cameroncooke>
thanks so much for your help and comments. They got me there eventually.
So...
1.
I discovered that ci_scripts does not necessarily go in the root of
the repo. It lives as a sibling of the project file. So in my case it was
in <repo_root>/App/ci_scripts.
2.
I then realised that because of this my tests had to point to two
separate directories.
- Locally it had to point to <repo_root>/App/ci_scripts/...
- In Xcode Cloud it points to <repo_root>/ci_scripts/...
Once that was done it all worked!
Got there eventually.
—
Reply to this email directly, view it on GitHub
<#553 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SNP3MCAWEFPAHQI7JTWBXVX5ANCNFSM5KSOPA2A>
.
You are receiving this because you were mentioned.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/3809123@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
Um that looks okay, are you able to provide a demo project and I’ll take a
look?
On Wed, 5 Oct 2022 at 19:58, Oliver Foggin ***@***.***> wrote:
I’m not sure that is correct, when it says recording new snapshots and
gives a path to the new snapshot that directory of the new snapshot is the
location it was searching for and couldn’t fix the reference snapshot.
The location of the new snapshot is...
/Volumes/workspace/repository/ci_scripts/resources/Tests/AppFeatureTests/__Snapshots__/AppCoreTests/testAnalytics.1.txt
The snapshot directory I am giving it is...
/Volumes/workspace/repository/ci_scripts/resources/Tests/AppFeatureTests/__Snapshots__/AppCoreTests
—
Reply to this email directly, view it on GitHub
<#553 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZ6SK2UVNMUM27O2O7I3LWBXFTRANCNFSM5KSOPA2A>
.
You are receiving this because you were mentioned.Message ID:
<pointfreeco/swift-snapshot-testing/repo-discussions/553/comments/3808223@
github.com>
--
Cameron.
|
Beta Was this translation helpful? Give feedback.
-
I was having this same problem, and unfortunately didn't find this thread until after I'd spend a whole day finding a different solution. I opted to fork and change Then in the let snapshotFileUrl = snapshotDirectoryUrl
.appendingPathComponent("\(testName).\(identifier)")
.appendingPathExtension(snapshotting.pathExtension ?? "") to: let myBundle = Bundle(for: CleanCounterBetweenTestCases.self)
let snapshotFileUrl = myBundle.path(forResource: "\(testName).\(identifier)", ofType: snapshotting.pathExtension).map({ URL(fileURLWithPath: $0) })
?? snapshotDirectoryUrl
.appendingPathComponent("\(testName).\(identifier)")
.appendingPathExtension(snapshotting.pathExtension ?? "") this has the benefit that the Test.swift files don't need to toggle the |
Beta Was this translation helpful? Give feedback.
-
Hello everyone, thanks for all the digging and research in this thread. I've created PR #716 that attempts to solve this in the library, hopefully in line with the patterns you're already using. Check it out and see if it would replace any ad-hoc solutions you're currently using? |
Beta Was this translation helpful? Give feedback.
-
Hi there! We’ve been using this solution for over a year —see my old comment above—; since I notice people are still struggling, I’m open-sourcing a package that provides you with a drop-in replacement for |
Beta Was this translation helpful? Give feedback.
-
Hello! So far I tried everything, locally is working, but on Xcode Cloud I'm getting error: Right now symlink to ci_scripts root directory is configured. Snapshots is a symlink, real path myProjectName/Tests/. Generally it seems like similar situation to this post: https://developer.apple.com/forums/thread/716993, I'm running out of any new ideas. Any suggestions what's more I can do in case to make it work on Xcode Cloud? Maybe something specific to Xcode Cloud workflow? |
Beta Was this translation helpful? Give feedback.
-
Finally I figured out it! There are two different locations. One for Xcodebuild: Second one for Run tests on iPhone 11 (iOS 16.1) simulator: As you can see for running tests location is root directory. So for snapshotDirectory locations needs to be: Here is repository with an inspiration and root ci_script symlink. |
Beta Was this translation helpful? Give feedback.
-
I didn’t like the solutions around hacking |
Beta Was this translation helpful? Give feedback.
-
I like the solutions around hacking |
Beta Was this translation helpful? Give feedback.
-
I made a guide on how to make this work https://youtu.be/KPJL8vN3lAg |
Beta Was this translation helpful? Give feedback.
-
When attempting to run snapshot tests on a workflow where the tests are run in a different environment to the where the tests are built (sources unavailable)
assertSnapshot(...)
is unable to find the snapshots using the current logic.A concrete example of this setup is when using Xcode Cloud CI service which uses one environment to build the tests and then another environment to execute the tests. On the environment where the tests are executed, there is no access to the build sources that the
StaticString = #file
resolves to at build-time.While Xcode Cloud scripts can be used to copy files to a single
ci_scripts
directory on the environment, when running the tests there is no way to override the path used byassertSnapshot(...)
at run-time to point it to the directory of reference images because of the use ofStaticString
.It might make sense to have a way of overriding the business rules around where the snapshots files are located for a given test so that it can be used in situations where we can't rely on the automatic behaviour.
More information on why test actions don't have access to sources can be found here: https://developer.apple.com/videos/play/wwdc2021/10269/?time=711
Beta Was this translation helpful? Give feedback.
All reactions