Using Xcode7's UI tests to create app screenshots for the App Store
Asked Answered
A

4

11

Every time we change something in the UI, we have to manually prepare and take 375 (= 5 screenshots * 5 device types * 15 languages) screenshots for iTunes Connect's listing.

I'm trying to "exploit" iOS 9's new UI testing to automatically prepare and take these screenshots for each language. This should save a huge amount of time and provide a better experience to our users, because we didn't update the screenshots frequently due to the hard work involved.

I couldn't find much help on the internet, probably because this feature is too fresh. So here are two essential questions, hopefully we can find a way to make it happen.

  1. Is it possible to save a screenshot to disk through the UI testing API?

  2. Is it possible to have a clean install for a XCTestCase?

Argyle answered 18/6, 2015 at 6:11 Comment(0)
W
11

This isn't completely related to Xcode 7, but you can automate screenshot taking with snapshot.

Winograd answered 18/6, 2015 at 6:38 Comment(3)
Doesn't answer the UI tests API questions, but I'll accept because it solves the problem perfectly and maybe even in a better way.Argyle
@Winograd I saw that yesterday when looking at snapshot :)Kissel
@Argyle I've implemented screenshot taking for Xcode7 UI tests. Screenshots are captured by the app and passed to the test via sockets, requires adding a framework to the app. The code is here: github.com/zmeyc/UITestUtilsRiddell
P
6

Yes, you can create screenshots using the Xcode UI Testing.

  • Create a custom scheme for your tests (optional but recommended).
  • Use CLI(terminal) to run the tests. Something like this:
xcodebuild -workspace App.xcworkspace \
     -scheme "SchemeName" \
           -sdk iphonesimulator \
           -destination 'platform=iOS Simulator,name=iPhone 6,OS=9.0' 
           test

Once you are done with this, to generate screenshots, add the path to where you want the screenshots, like this:

xcodebuild -workspace App.xcworkspace \
 -scheme "SchemeName" \
       -sdk iphonesimulator \
       -destination 'platform=iOS Simulator,name=iPhone 6,OS=9.0'
       -derivedDataPath './output'
       test

./output will tell Xcode to take screenshots for every test. You can find this in detail here

Pieplant answered 28/7, 2015 at 9:9 Comment(0)
K
3
  1. Is it possible to save a screenshot to disk through the UI testing API?

You can manually save them (through the "open in preview" button), but I do not know of an API to collect them during the tests. File a radar! (https://bugreport.apple.com)

  1. Is it possible to have a clean install for a XCTestCase?

I don't know of a way to actually reinstall your app for every XCTestCase, but you can uninstall it before running all of your tests, or you can use the setUp class method or instance method on XCTestCase to ensure that your app is in a fresh state before your tests are run (ex. reset user defaults, etc).

Kissel answered 18/6, 2015 at 6:47 Comment(2)
About #2, how do I reset user defaults / documents dir on the setUp? Couldn't find anything related in XCUIApplication reference.Argyle
@Kof: see here: #32351649 , and here adamkaump.com/thoughts/uitestsDesolation
D
0

This is the best way I found to do this so far: Automating App Store localized screenshots with XCTest and Xcode Test Plan

To sum it up (and try to make sure this answer doesn't suffer from link rot in the future), you should create a Test Plan that goes through the screens in your app you want to screenshot and include code similar to the following to take the screenshots:

class AppStoreScreenshotTests: XCTestCase {

    var app : XCUIApplication!

    override func setUpWithError() throws {
        continueAfterFailure = false
        self.app = XCUIApplication()
    }
    
    override func tearDownWithError() throws {
        self.app = nil
    }

    func testSearchJourney() {
        self.app.launch()

        // moving to search tab
        app.buttons[AccessibilityIdentifiers.searchTab.rawValue].tap()
        
        // wait for screen to be fully displayed within 5sec
        XCTAssertTrue(app.buttons[AccessibilityIdentifiers.searchButton.rawValue].waitForExistence(timeout: 5))
        
        // take a screenshot of the search page
        attachScreenshot(name: "search-form")
    }

    private func attachScreenshot(name: String) {
        let screenshot = app.windows.firstMatch.screenshot()
        let attachment = XCTAttachment(screenshot: screenshot)
        attachment.name = name
        attachment.lifetime = .keepAlways
        add(attachment)
    }

Then you can automate creation and extraction of screenshots with a shell script that executes the test with xcodebuild test and use xcparse to export them into a separate folder:

xcparse screenshots --os --model --test-plan-config /path/to/Test.xcresult /path/to/outputDirectory

Personally I prefer this approach rather than using Fastlane.

Dethrone answered 19/11, 2022 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.