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

4.9k views Asked by At

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?

4

There are 4 answers

3
rounak On BEST ANSWER

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

2
Andrew On
  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).

0
Velociround On

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.

0
Gautam Jain On

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