рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!
рд╣рдорд╛рд░реЗ рдкрд╛рдареНрдпрдХреНрд░рдореЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдПрдХ рдФрд░ рдирд╡реАрдирддрд╛:
"рдЖрдИрдУрдПрд╕ рдбреЗрд╡рд▓рдкрд░" , рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдкрд╛рдареНрдпрдХреНрд░рдо рдХреА рддреИрдпрд╛рд░реА рдХреЗ рджреМрд░рд╛рди рд╣рдореЗрдВ рдорд┐рд▓реЗ рджрд┐рд▓рдЪрд╕реНрдк рдЯреБрдХрдбрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ, рд▓реЗрдЦрдХ рдпреВрдЖрдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рдФрд░ рдЦреЗрд▓рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред

рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред
рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЕрдкрдиреЗ рдпреВрдЖрдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ
рджреВрддрд╛рд╡рд╛рд╕ рдФрд░
рд░рд╕реАрд▓рд╛ рдХреЛ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ред рдпрджрд┐ рдЖрдкрдХреЛ рдЗрди API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП UI рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рдореЙрдХ / рд╕реНрдЯрдм рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддреА рд╣реИред
рд╕рдорд╕реНрдпрд╛рдПрдВ:
- рдЖрд╡реЗрджрди рдпреВрдЖрдИ рдХреЛ рдЖрдмрд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ;
- рд╕реНрдЯрдмреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдФрд░ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ;
- рдореЛрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЬрд┐рдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреЙрд▓ рд╕реЗ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ;
- рдЗрд╕ рдХрдиреЗрдХреНрд╢рди рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ - рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЪрд░ рдФрд░ рдХреНрд░реИрд╢, рдмрд┐рд▓реНрдХреБрд▓ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛
рджреВрддрд╛рд╡рд╛рд╕ + рд░рд╕реАрд▓рд╛ рд╕рдорд╛рдзрд╛рдирд╕рдорд╛рдзрд╛рди рдПрдХ рд╕реНрдерд╛рдиреАрдп рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рджреВрддрд╛рд╡рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдХреЙрд▓ (рд░рд╕реАрд▓рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ) рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд╣рд▓реА рдмрд╛рд░ рдЬрдм рдЖрдк рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдорд╛рдирдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреЙрд▓ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рдЯреНрд░реЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЕрдЧрд▓реА рдмрд╛рд░, рдпреЗ рд╕рдорд╛рди рдиреЗрдЯрд╡рд░реНрдХ рдХреЙрд▓ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрддрд░ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗред рдЕрдЪреНрдЫрд╛ рд╣реИ, рд╣реИ рдирд╛? рдореЛрдЬрд╝реЗрдХ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЖрдк рд▓реИрдЧреНрд╕ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рдм рдирд┐рд░реНрдорд╛рдг рдорд╢реАрди рдХреЗ рдЕрдВрджрд░, рдПрдХреНрд╕рдХреЗрд╕реНрдЯ рдХреЗ рдЕрдВрджрд░ рдЪрд▓рддрд╛ рд╣реИ!
рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ?1. Succulent рдХреЗ рддрд╣рдд рдбрд╛рдЙрдирд▓реЛрдб рдФрд░ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВред рдЗрд╕ рд▓реЗрдЦрди рдХреЗ рд╕рдордп, cocoapods.com рдкрд░ рдХреЛрдИ рдкреЙрдб рдирд╣реАрдВ рдерд╛, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд╕реНрд░реЛрдд рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреА рдЙрдк-рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
target тАЬUI TestsтАЭ do inherit! :search_paths pod 'Succulent', :path => 'Succulent/' end
рджреВрддрд╛рд╡рд╛рд╕ рджреНрд╡рд╛рд░рд╛ рд░рд╕реАрдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
2. рдПрдХ рдирдИ рдкрд░реАрдХреНрд╖рд╛ рдпреВрдЖрдИ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдФрд░
рд░рд╕реАрд▓рд╛ рдЧрд┐рдЯрд╣рдм рд╕реЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдПрдБред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЖрдкрдХреЛ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдП:
import Succulent @testable import TestAppUITests class SucculentTestUITest: XCTestCase { private var succulent: Succulent! var session: URLSession! var baseURL: URL! /// The name of the trace file for the current test private var traceName: String { return self.description.trimmingCharacters(in: CharacterSet(charactersIn: "-[] ")).replacingOccurrences(of: " ", with: "_") } /// The URL to the trace file for the current test when running tests private var traceUrl: URL? { let bundle = Bundle(for: type(of: self)) return bundle.url(forResource: self.traceName, withExtension: "trace", subdirectory: "Traces") } /// The URL to the trace file for the current test when recording private var recordUrl: URL { let bundle = Bundle(for: type(of: self)) let recordPath = bundle.infoDictionary!["TraceRecordPath"] as! String return URL(fileURLWithPath: "\(recordPath)/\(self.traceName).trace") } override func setUp() { super.setUp() continueAfterFailure = false if let traceUrl = self.traceUrl { // Replay using an existing trace file succulent = Succulent(traceUrl: traceUrl) } else { // Record to a new trace file succulent = Succulent(recordUrl: self.recordUrl, baseUrl: URL(string: "https//base-url-to-record.com/")!) } succulent.start() let app = XCUIApplication() app.launchEnvironment["succulentBaseURL"] = "http://localhost:\(succulent.actualPort)/" app.launch() } override func tearDown() { super.tearDown() } }
рдЬрдм рдЖрдк рд░рд╕реАрд▓рд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЖрдзрд╛рд░ URL рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдзрдиреНрдпрд╡рд╛рдж рдЬрд┐рд╕рд╕реЗ рдЖрдзрд╛рд░ URL рд╕рд╣рд┐рдд рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
3. рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг UI рдХреЗ Info.plist рд▓рдХреНрд╖реНрдп рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ:
<key>TraceRecordPath</key> <string>$(PROJECT_DIR)/Succulent/Traces</string>
4. рд╕реНрдерд╛рдиреАрдп рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВред
рдЕрдкрдиреЗ рдореБрдЦреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЕрдВрджрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ "succulentBaseURL" рдореМрдЬреВрдж рд╣реИ рдФрд░ рдпрджрд┐ рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдпрд╣ рдЖрдкрдХреЗ рд╕реНрдерд╛рдиреАрдп рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЗ рдпреВрдЖрд░рдПрд▓ рдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдФрд░ рд╕реЗрдЯрдЕрдк рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЪрд░рдг 2 рдореЗрдВ рдКрдкрд░ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдмрд╕ рдЗрддрдирд╛ рд╣реА, рд╢рд╛рдпрдж!
рдЕрдм рдЬрдм рдЖрдк рдПрдХ рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ Succulent рдПрдХ рдПрдкреАрдЖрдИ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦреЗрдЧрд╛ рдФрд░ рдЖрдкрдХреЗ UI рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рдЯреНрд░реЗрд╕ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдПрдХ .trace рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдЧрд╛ред рдЕрдЧрд▓реА рдмрд╛рд░ рдЬрдм рдЖрдк рдПрдХ рд╣реА рдкрд░реАрдХреНрд╖рд╛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдореМрдЬреВрдж рд╣реИ рдпрд╛ рдирд╣реАрдВред
рдЖрдк Xcode рд╕реЗ рд╕реАрдзреЗ .trace рдлрд╛рдЗрд▓реЗрдВ рдЦреЛрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рднреА рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд▓реЗрдЦ рдорджрджрдЧрд╛рд░ рдирд┐рдХрд▓рд╛, рдпрд╣рд╛рдБ рдкрд┐рдЬреНрдЬрд╛ рд╣реИ

рдЕрдВрдд
рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╣рдо рдпрд╣рд╛рдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ, рдкреНрд░рд╢реНрдиреЛрдВ рдЖрджрд┐ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдпрд╛ рдЖрдк
рдУрдкрди рдбреЗ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ
рд╢рд┐рдХреНрд╖рдХ рд╕реЗ рдПрдХ рдкреНрд░рд╢реНрди рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВред