Some UI testing code

This commit is contained in:
Selim Mustafaev 2022-04-04 20:15:35 +03:00
parent ea7924c5ac
commit 9204580dc4
14 changed files with 148 additions and 45 deletions

View File

@ -31,6 +31,13 @@
7A28283327E7263B0049BDBF /* UIStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A28283227E7263B0049BDBF /* UIStackView.swift */; };
7A28283627E74C110049BDBF /* SwiftEntryKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A28283527E74C110049BDBF /* SwiftEntryKit */; };
7A28283827E74D930049BDBF /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A28283727E74D930049BDBF /* CheckController.swift */; };
7A36E55C27FB55570025AACB /* Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E55B27FB55570025AACB /* Testing.swift */; };
7A36E55D27FB5A220025AACB /* ApiMethodMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAA27FA3CCF001A18EE /* ApiMethodMock.swift */; };
7A36E55E27FB5A260025AACB /* LoginMethodMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA927FA3CCF001A18EE /* LoginMethodMock.swift */; };
7A36E55F27FB5A2C0025AACB /* login_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A558AAC27FA3CCF001A18EE /* login_success.json */; };
7A36E56027FB5A2F0025AACB /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */; };
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; };
7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E56227FB5BEB0025AACB /* TestError.swift */; };
7A48B26727D9442A004D1A4B /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7A48B26627D9442A004D1A4B /* PKHUD */; };
7A49F4A327D4061900AEAAE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */; };
7A49F4A527D4061900AEAAE0 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */; };
@ -62,11 +69,6 @@
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */; };
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA527FA3CCF001A18EE /* SettingsTests.swift */; };
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA627FA3CCF001A18EE /* ApiTests.swift */; };
7A558AB227FA3CCF001A18EE /* LoginMethodMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA927FA3CCF001A18EE /* LoginMethodMock.swift */; };
7A558AB327FA3CCF001A18EE /* ApiMethodMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAA27FA3CCF001A18EE /* ApiMethodMock.swift */; };
7A558AB427FA3CCF001A18EE /* login_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A558AAC27FA3CCF001A18EE /* login_success.json */; };
7A558AB527FA3CCF001A18EE /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */; };
7A558AB627FA3CCF001A18EE /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; };
7A9F2AC327E71531006492A9 /* ACTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9F2AC227E71531006492A9 /* ACTabBarController.swift */; };
7AE32D6427F05F89004EF6E0 /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6327F05F89004EF6E0 /* VehicleCell.swift */; };
7AE32D6627F063A1004EF6E0 /* UIEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6527F063A1004EF6E0 /* UIEdgeInsets.swift */; };
@ -158,6 +160,8 @@
7A28283027E721A70049BDBF /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
7A28283227E7263B0049BDBF /* UIStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackView.swift; sourceTree = "<group>"; };
7A28283727E74D930049BDBF /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = "<group>"; };
7A36E56227FB5BEB0025AACB /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
7A49F49F27D4061900AEAAE0 /* AutoCat2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2.app; sourceTree = BUILT_PRODUCTS_DIR; };
7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@ -333,6 +337,16 @@
path = ACTabBar;
sourceTree = "<group>";
};
7A36E55A27FB54610025AACB /* Testing */ = {
isa = PBXGroup;
children = (
7A558AA727FA3CCF001A18EE /* Api */,
7A36E55B27FB55570025AACB /* Testing.swift */,
7A36E56227FB5BEB0025AACB /* TestError.swift */,
);
path = Testing;
sourceTree = "<group>";
};
7A49F49627D4061900AEAAE0 = {
isa = PBXGroup;
children = (
@ -396,6 +410,7 @@
7A49F4D827D4064500AEAAE0 /* AutoCatCore */ = {
isa = PBXGroup;
children = (
7A36E55A27FB54610025AACB /* Testing */,
7AE32D6F27F06D87004EF6E0 /* DataSource */,
7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */,
7A49F50427D406CB00AEAAE0 /* Models */,
@ -411,7 +426,6 @@
7A49F4E627D4064500AEAAE0 /* AutoCatCoreTests */ = {
isa = PBXGroup;
children = (
7A558AA727FA3CCF001A18EE /* Api */,
7A558AA627FA3CCF001A18EE /* ApiTests.swift */,
7A558AA527FA3CCF001A18EE /* SettingsTests.swift */,
);
@ -742,6 +756,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A36E55F27FB5A2C0025AACB /* login_success.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -749,7 +764,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A558AB427FA3CCF001A18EE /* login_success.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -820,12 +834,16 @@
7A49F51227D406CB00AEAAE0 /* VName.swift in Sources */,
7A1D80E827F30399007BD64F /* VModel.swift in Sources */,
7A49F51127D406CB00AEAAE0 /* PlateNumber.swift in Sources */,
7A36E55E27FB5A260025AACB /* LoginMethodMock.swift in Sources */,
7A49F50C27D406CB00AEAAE0 /* VBrand.swift in Sources */,
7A36E55C27FB55570025AACB /* Testing.swift in Sources */,
7A49F51027D406CB00AEAAE0 /* Settings.swift in Sources */,
929EDE9027F8F76300E55F65 /* DebugInfo.swift in Sources */,
7A36E55D27FB5A220025AACB /* ApiMethodMock.swift in Sources */,
929EDE8927F8E65500E55F65 /* VAd.swift in Sources */,
7A49F4F927D406B200AEAAE0 /* Constants.swift in Sources */,
929EDE8527F8CB0600E55F65 /* VEvent.swift in Sources */,
7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */,
7A49F50F27D406CB00AEAAE0 /* Response.swift in Sources */,
929EDE8127F8A75E00E55F65 /* VPhoto.swift in Sources */,
7A49F4FB27D406B200AEAAE0 /* Api.swift in Sources */,
@ -833,6 +851,8 @@
929EDE7F27F89C3000E55F65 /* VEngine.swift in Sources */,
929EDE8727F8E11E00E55F65 /* VOsago.swift in Sources */,
7A49F50E27D406CB00AEAAE0 /* User.swift in Sources */,
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */,
7A36E56027FB5A2F0025AACB /* MockURLProtocol.swift in Sources */,
7A49F4FA27D406B200AEAAE0 /* ApiError.swift in Sources */,
7AE32D7127F06DA4004EF6E0 /* DateSection.swift in Sources */,
);
@ -842,12 +862,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A558AB227FA3CCF001A18EE /* LoginMethodMock.swift in Sources */,
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */,
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */,
7A558AB627FA3CCF001A18EE /* ApiMethodMockProtocol.swift in Sources */,
7A558AB527FA3CCF001A18EE /* MockURLProtocol.swift in Sources */,
7A558AB327FA3CCF001A18EE /* ApiMethodMock.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -17,49 +17,49 @@
<key>AutoCatCore.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>7</integer>
</dict>
<key>DifferenceKit (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>2</integer>
</dict>
<key>DifferenceKit (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
<integer>3</integer>
</dict>
<key>DifferenceKit (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>1</integer>
</dict>
<key>SwiftDate (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
<integer>5</integer>
</dict>
<key>SwiftDate (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>5</integer>
<integer>6</integer>
</dict>
<key>SwiftDate (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>4</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -22,4 +22,9 @@ extension UIView {
bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -insets.bottom)
])
}
func accessibilityId(_ id: String) -> Self {
accessibilityIdentifier = id
return self
}
}

View File

@ -9,18 +9,22 @@ import AutoCatCore
class AuthController: UIViewController {
private lazy var emailField = ACTextField(placeholder: "Email")
.onTextChanged(textChanged)
.keyboardType(.emailAddress)
.onTextChanged(textChanged)
.keyboardType(.emailAddress)
.accessibilityId("emailTextField")
private lazy var passwordField = ACTextField(placeholder: "Password")
.onTextChanged(textChanged)
.secure(true)
.onTextChanged(textChanged)
.secure(true)
.accessibilityId("passwordTextField")
private lazy var loginButton = ACButton(title: "Log in", onTapAsync: loginTapped)
.enable(false)
.accessibilityId("loginButton")
.enable(false)
private lazy var signupButton = ACButton(title: "Sign up", onTapAsync: signupTapped)
.enable(false)
.accessibilityId("signupButton")
.enable(false)
private lazy var stackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [

View File

@ -6,16 +6,16 @@
//
import XCTest
import AutoCatCore
class AutoCat2UITests: XCTestCase {
private let testLogin = "test@gmail.com"
private let testPassword = "12345"
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDownWithError() throws {
@ -23,20 +23,22 @@ class AutoCat2UITests: XCTestCase {
}
func testExample() throws {
// UI tests must launch the application that they test.
let app = XCUIApplication()
app.launchArguments += ["UI-TESTING"]
app.launchEnvironment["testKind"] = Testing.TestKind.addNumberSuccess.rawValue
app.launch()
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testLaunchPerformance() throws {
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
// This measures how long it takes to launch your application.
measure(metrics: [XCTApplicationLaunchMetric()]) {
XCUIApplication().launch()
}
let loginButton = app.buttons["loginButton"]
guard loginButton.waitForExistence(timeout: 5) else {
XCTFail("Login button not found")
return
}
app.textFields["emailTextField"].tap()
app.textFields["emailTextField"].typeText(testLogin)
app.secureTextFields["passwordTextField"].tap()
app.secureTextFields["passwordTextField"].typeText(testPassword)
loginButton.tap()
}
}

View File

@ -1,5 +1,4 @@
import Foundation
import AutoCatCore
open class ApiMethodMock: ApiMethodMockProtocol {

View File

@ -1,14 +1,13 @@
import Foundation
import AutoCatCore
class LoginMethodMock: ApiMethodMock {
private var login: String
private var password: String
init(httpMethod: String, path: String, login: String, password: String) {
init(login: String, password: String) {
self.login = login
self.password = password
super.init(httpMethod: httpMethod, path: path)
super.init(httpMethod: "POST", path: "user/login")
}
override func response(headers: [String : String], params: [String : Any]) -> (status: Int, data: Data?) {

View File

@ -0,0 +1,20 @@
//
// TestError.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 04.04.2022.
//
import Foundation
enum TestError: LocalizedError {
case testKindNotFound
public var errorDescription: String? {
switch self {
case .testKindNotFound:
return "Test kind not found"
}
}
}

View File

@ -0,0 +1,49 @@
//
// Testing.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 04.04.2022.
//
import Foundation
public struct Testing {
typealias ApiMockMap = [TestKind: [ApiMethodMockProtocol]]
public static let testEmail = "test@gmail.com"
public static let testPassword = "12345"
public enum TestKind: String {
case addNumberSuccess
}
public static var isUITesting: Bool {
ProcessInfo.processInfo.arguments.contains("UI-TESTING")
}
public static var testUrlSession: URLSession? {
guard let kindStr = ProcessInfo.processInfo.environment["testKind"],
let kind = TestKind(rawValue: kindStr) else {
return nil
}
MockURLProtocol.baseUrl = Constants.baseUrl
MockURLProtocol.apiMethodMocks = apiMockSets[kind] ?? []
let sessionConfig = URLSessionConfiguration.default
sessionConfig.protocolClasses = [MockURLProtocol.self]
return URLSession(configuration: sessionConfig)
}
private static let apiMockSets: ApiMockMap = {
var map = ApiMockMap()
map[.addNumberSuccess] = [
LoginMethodMock(login: testEmail, password: testPassword)
]
return map
}()
}

View File

@ -18,6 +18,15 @@ public class Api: ApiProtocol {
self.settings = settings
if Testing.isUITesting {
if let testSession = Testing.testUrlSession {
self.session = testSession
} else {
fatalError("Error creating test session")
}
return
}
if let session = session {
self.session = session
} else {

View File

@ -11,7 +11,7 @@ class ApiTests: XCTestCase {
override func setUpWithError() throws {
MockURLProtocol.baseUrl = Constants.baseUrl
MockURLProtocol.apiMethodMocks = [
LoginMethodMock(httpMethod: "POST", path: "user/login", login: self.testLogin, password: self.testPassword)
LoginMethodMock(login: self.testLogin, password: self.testPassword)
]
let sessionConfig = URLSessionConfiguration.default