Modern approach to testing localization on iOS

Hello! Let's talk about how now in the 2020th year you can test a multilingual iOS application if you do not want to check the localization manually.


image


β€” -, . ( ), . : , , , . . , , , .


image


Product Owner . , β€” , .


image


: , .


image


6-7 .



Exness Mobile Trader.


, WebSocket. . , . : , - . β€” push-.


image


, . .


2017 , 70% - , . . , . 2017- . . . , BDD-, API Postman. 2018 , - , .



β€” . , , .


β€” , , ?


Crowdin β€” . , Jira, : , , . , . .


Crowdin : XML, YML, JSON, . . - : , . Crowdin API. . , - , . , , , , .


Crowdin .


: ?
LinguanApp β€” «» Xcode-, - . , , - . : . LinguanApp : , . , , .


: LinguanApp , , Crowdin.



, . , , β€” , , . , . , , :


image


? , , , : 14 . iPhone ( , iPhone SE), 6 15 = 90 Β« β€” Β». . , . .


-, : iPhone Xs Max, iPhone X, 6S 6 plus. , , . Display Zoom:


image



? , . iPhone 6S, Display Zoom iPhone 5. iOS 11 iPhone Xs Display Zoom, Xr Xs Max .


. . , .



. , . UI-. UI-, , . , accessebility Identifier’:


signinButton.accessebilityIdentifier = "btn_auth"

, Identity Inspector Xcode.


, , . Swift XCTest.


func testTutorial() {
        tutorialButton.tap()
        waitForElementToDissappear(element: tutorialButton, timeout: 5)
        makeScreenshot()
        for _ in 1...4 {
            app.swipeLeft()
            makeScreenshot()
        }
        tutorialCloseButton.tap()
        waitForElementToDissappear(element: tutorialCloseButton, timeout: 3)
    }

, Tutorial. . , . tutorial , .


:



Stackoverflow :


func makeScreenshot() {
        XCTContext.runActivity(named: "Making a full screenshot and saving it") { (activity) in
            let screen = XCUIScreen.main
            let fullscreenshot = screen.screenshot()
            let fullScreenshotAttachment = XCTAttachment(screenshot: fullscreenshot)
            fullScreenshotAttachment.lifetime = .keepAlways
            activity.add(fullScreenshotAttachment)
        }
    }

:


func waitForElementToDissappear(element: XCUIElement, timeout: Double) {
        let doesNotExistPredicate = NSPredicate(format: "exists == FALSE")
        expectation(for: doesNotExistPredicate, evaluatedWith: element, handler: nil)
        waitForExpectations(timeout: timeout, handler: nil)
    }

.


β€” Fastlane, . , .


:


image



SnapshotHelper.swift Snapfile, .
Fastlane UI Test Target. UI Test Bundle:


image



:


image



Target membership .
. , shared. , Build :


image



Test :


image



Fastlane setUp(), -:


override func setUp() {
        continueAfterFailure = false
        setupnapshot(app)
        app.launch()
    }

, , Fastlane. makeScreenshot() snapshot("snapshot_name"), Fastlane .


, . :


func testTutorial() {
        tutorialButton.tap()
        waitForElementToDissappear(element: tutorialButton, timeout: 5)
        snapshot("Tutorial_page_1")
        var i: Int = 2
        repeat {
            app.swipeLeft()
            snapshot("Tutorial_page_\(i)")
            i += 1
        } while i <= 5
        tutorialCloseButton.tap()
        waitForElementToDissappear(element: tutorialCloseButton, timeout: 3)
    }

4 5 : , , , . , β€” , . :


image



list of device , ; , UI-, . , , β€” .


fastlane snapshot HTML- , , .


Fastlane . 5 4 5 28 . . Fastlane.


β€” XCTest Plan. WWDC 2019 Xcode 11. : , , . , XCTest Plan Xcode .


. , , XCTest Plan:


image



:


image



. application language:


image



Shared settings system language, , , :


image



. :


β€”> Run yourTestName():


image



,


Xcodebuild:


Xcodebuild 
    -workspace ExnessForHeisenbug.xcworkspace/
    -scheme ExnessForHeisenbug
    -destination 'platform=iOS Simulator,OS=10.3.1,name=iPhone 6s'
    -destination 'platform=iOS Simulator,OS=11.4,name=iPhone 7 plus' 
    -destination 'platform=iOS Simulator,OS=12.2,name=iPhone Xs' 
    -destination 'platform=iOS Simulator,OS=12.2,name=iPhone SE' 
    test -testPlan ExnessForHeisenbug

, , testPlan destination. , iOS, .


XCTest Plan. , . Fastlane.



testTutorial:


image



XCTest Plan: . Fastlane HTML-, , . , Xcode , - . XCTest Plan , Xcode.


. , Apple , , . , Fastlane 28 , XCTest Plan 2,6 . 10 .



, . , -: , .
- :


β€” iOS Snapshot Test Case, , Objective C. UIView/CALayer . (recordMode = true) (). (recordMode = false), .


image



Deposit is in your account! Long title! Test it Elon Musk!, 120 000 000.00 USD. , .


. , - . , transaction id, .


( ). , , .


pod


image



:


FB_REFERENCE_IMAGE_DIR β€” ,
IMAGE_DIF_DIR β€” .


image



. - , . , , .


β€” Swift Snapshot Testing, Point Free Co. : . JSON, , URL, .


. E Import Snapshot Testing, assertSnapshot() ViewController . .


import SnapshotTesting
import XCTest

class MyViewControllerTests: XCTestCase {
  func testMyViewController() {
    let vc = MyViewController()

    assertSnapshot(matching: vc, as: .image)
  }
}

, Swift . β€” diff: . . , , open source, , .



, . β€” XCTest Plan Fastlane. . -.


Exness : Exness Trading, , Social Trading, .


Crowdin . LinguanApp Exness Trading , , , . Social Trading. Fastlane . XCTest Plan . , Exness Trading Swift Snapshot Test Case, Social Trading β€” iOS Snapshot Test Case. , . Happy testing!


/ :


Fastlane:


https://agostini.tech/2018/07/15/automatic-screenshots-with-fastlane-snapshot/
https://docs.fastlane.tools/getting-started/ios/screenshots/


XCTestPlan:


https://shashikantjagtap.net/wwdc19-getting-started-with-test-plan-for-xctest/
https://developer.apple.com/videos/play/wwdc2019/403
https://developer.apple.com/videos/play/wwdc2019/413


swift-snapshot-testing:


https://github.com/pointfreeco/swift-snapshot-testing/


ios-snapshot-test-case:


https://github.com/uber/ios-snapshot-test-case/


Display Zoom:


http://www.iphonehacks.com/2014/09/use-display-zoom-iphone-6-plus.html


All Articles