Closed klevison closed 8 years ago
By default snapshot
will print out a list of available schemes. I think it's only possible to do that for schemes.
My solution:
1) Create 3 UITest targets
2) Set the test action foreach
3) Create
3.1 Create SnapshotUITests.swift
targeting to all UITest targets (step 1).
import XCTest
class SnapshotUITests: XCTestCase {
override func setUp() {
super.setUp()
continueAfterFailure = false
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
}
override func tearDown() {
super.tearDown()
}
func testMainScreenSnapShot() {
snapshot("01MainScrenn")
}
func testLeftMenuSnapShot() {
XCUIApplication().navigationBars["App"].buttons["menu"].tap()
snapshot("02LeftMenu")
}
}
3.2 Create SnapshotPrimeUITests
file where it targets to SnapshotPrimeUITests
target
class SnapshotPrimeUITests: SnapshotUITests {
}
3.2 Create SnapshotExclusiveUITests
file where it targets to SnapshotExclusiveUITests
target
class SnapshotExclusiveUITests: SnapshotUITests {
}
3.3 Create SnapshotClassicUITests
file where it targets to SnapshotClassicUITests
target
class SnapshotClassicUITests: SnapshotUITests {
}
4.1) Snapfile
scheme ENV["SCHEME"]
devices([
"iPhone 6s",
"iPhone 6s Plus",
"iPhone 5s",
"iPhone 4s"
])
languages([
"pt-BR"
])
launch_arguments(ENV["SCHEME"])
4.2) Fastfile
desc "Runs all the tests"
["Prime", "Exclusive", "Classic"].each do |scheme_name|
ENV["SCHEME"] = scheme_name
snapshot
end
Result:
With this solution I have the "ideal final result" but I'm looking for a way that avoid create a lot of targets and subclass..
@klevison Thanks for sharing. Do you know if there is a way to only run a subset of tests using xcodebuild
? If so, I can easily add this to snapshot
.
@KrauseFx I know that xctool
can do this https://github.com/facebook/xctool#testing
Also, there is a Open Radar on this http://www.openradar.me/15750338
@hebertialmeida I might be wrong, but I think xctool
doesn't use xcodebuild
to run tests.
Same issue. Multiple targets.
Is there any progress on this??
I have over 70 targets (don't ask) and a single ui test could cover them all so I want to avoid creating 70+ additional targets for the unit tests.
I also have the same problem (50+ targets, all with minor differences for particular clients, that otherwise need the same UI test). The OP here makes a decent architectural suggestion to at least not have to copy+paste the test every time, but if anyone else has a better way of implementing it, I'm happy to try to add it. Right now I don't know if it's possible to dynamically specify the "Target Application" for a UI Test... that would seem to be easiest for me. I'll look and see if there's some magic voodoo for this but if you've figured out a way (without unsafe changes to the pbxproj file) please share!
@KrauseFx I'm not seeing how it would help to be able to run a subset of tests... one would still need to create a separate Test for each Target Application. What we really need is a way to dynamically set Target Application and the only way I'm coming up with is copying the .pbxproj and doing a manual edit to set the desired Target Application, which would be rather fragile. I've filed another bug against Apple but given my track record of not even getting responses lately, I'm not holding my breath.
For those who are interested in this, I managed to make this work dynamically using some hackery and Xcodeproj. I'm not going to do a pull request (yet) because it's just too hacky. But in general, I set up a single UI test and set up every Scheme to build/test it. Then I have this in my Fastfile:
Note that my setup has fastlane set up for each target under a "Custom/
lane :snapshot do
prepare_UITest_target("../../../MyRealApp.xcodeproj", "../../../test.xcodeproj", ENV["SCHEME"])
snapshot(clean: true, project: "../../test.xcodeproj", scheme:ENV["SCHEME"])
end
def prepare_UITest_target(source, dest, test_target)
# Make a copy and open it so we can't harm the actual project file
FileUtils::cp_r(source + "/.", dest)
project = Xcodeproj::Project.open(source)
# Find the target for the test
dependency_target = 0
project.targets.each do |target|
if test_target == target.name
dependency_target = target
end
end
# Add the target as a dependency and update the TEST_TARGET_NAME's
project.targets.each do |target|
# HACK ALERT: Hardcoded UI Test target name... have not yet generalized
next unless "SnapshotUITestsCustom" == target.name
target.add_dependency(dependency_target)
target.build_configurations.each do |configuration|
configuration.build_settings['TEST_TARGET_NAME'] = test_target
end
end
project.save(dest)
# Change all references to test.xcodeproj -- XXX: This is not generic
# HACK ALERT: Hardcoded the source and dest project names
system("LC_ALL=C find #{dest} -type f -exec sed -i '' 's/MyRealApp.xcodeproj/test.xcodeproj/g' '{}' \\;")
end
I apologize for not having cleaned it up, but I got it working and wanted to document ASAP. I'll edit this if I'm able to get it properly generalized (and un-hacked enough to support a pull request to build it in to snapshot)
The biggest thing I'd like to do is make the copy in the fastlane/ directory, but then it won't build because it's missing all of the files. I might be able to hack this again with sed to fix the relative path, but that seems even worse. I'm open to suggestions for improvement.
This issue was migrated to https://github.com/fastlane/fastlane/issues/1676. Please post all further comments there.
fastlane
is now a mono repo, you can read more about the change in our blog post. All tools are now available in the fastlane main repo :rocket:
For any reasons I have 3 targets/scheme each one to load a different theme. So, when I run snapshot command it only take the snapshot of the target selected into Target Application (UITest Target).
Is there a way to deal with it dynamically? I wanna run
snapshot
command and get the result of 3 themes/targets/scheme.