Xcode 7以降、UIテスト用の素晴らしいAPIがあります。主に私はそれに満足しています。唯一の懸念は速度に関連しています。
最初に、通常のUIテストケース(約15のアクション)が約25秒実行されました。次に、ネットワーキングを完全に模倣しました。今では20秒かかります。時間はアニメーションと起動時間(1秒以下)だけで済むことを考えると、スピードを上げる方法が必要だと思います。
UIテストの実行時にこのプロパティを設定してみてください。
UIApplication.shared.keyWindow?.layer.speed = 100
設定方法は次のとおりです。
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if ProcessInfo.processInfo.arguments.contains("UITests") {
UIApplication.shared.keyWindow?.layer.speed = 100
}
}
そして私のUIテストでは:
class MyAppUITests: XCTestCase {
// MARK: - SetUp / TearDown
override func setUp() {
super.setUp()
let app = XCUIApplication()
app.launchArguments = ["UITests"]
app.launch()
}
}
これには、さらに便利なヒントがいくつかあります ブログ投稿 。
別の可能性は、アニメーションをまったく無効にすることです:
[UIView setAnimationsEnabled:NO];
スウィフト3:
UIView.setAnimationsEnabled(false)
@Markの回答に続いて、Swiftバージョン:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if ProcessInfo.processInfo.arguments.contains("UITests") {
UIApplication.shared.keyWindow?.layer.speed = 200
}
}
あなたのUIテストファイル:
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
let app = XCUIApplication()
app.launchArguments = ["UITests"]
app.launch()
スナップショットテスト中は、すべてのアニメーションを無効にしたいと思っていました。以下のように、Core AnimationとUIViewアニメーションの両方を無効にすることで、これを実現できました。
私のアプリはストーリーボードを使用したので注意してくださいUIApplication.shared.keyWindow
は起動時にnilだったので、window
プロパティを直接参照してUIWindowにアクセスしました。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if ProcessInfo.processInfo.arguments.contains("SnapshotTests") {
// Disable Core Animations
window?.layer.speed = 0
// Disable UIView animations
UIView.setAnimationsEnabled(false)
}
return true
}
DidFinishLaunchに追加します
[UIApplication sharedApplication].keyWindow.layer.speed = 2;
デフォルト値は1で、速度を2倍にするには2にします。
UITestsの時間を30%に減らし、すべての手順に従います。
アプリを実行するときに、引数を追加します。
let app = XCUIApplication()
override func setUp() {
super.setUp()
continueAfterFailure = false
app.launchArguments += ["--Reset"]
app.launch()
}
次に、AppDelegateに次を追加します。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setStateForUITesting()
}
static var isUITestingEnabled: Bool {
get {
return ProcessInfo.processInfo.arguments.contains("--Reset")
}
}
private func setStateForUITesting() {
if AppDelegate.isUITestingEnabled {
// If you need reset your app to clear state
UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
// To speed up your tests
UIApplication.shared.keyWindow?.layer.speed = 2
UIView.setAnimationsEnabled(false)
}
}
コードで、がテストモードかどうかを確認するには、次を使用できます。
if AppDelegate.isUITestingEnabled {
print("Test Mode")
}
さらに、要素の読み込み中にwait
を実行するには、この拡張機能を作成しました。
import XCTest
extension XCUIElement {
func tap(wait: Int, test: XCTestCase) {
if !isHittable {
test.expectation(for: NSPredicate(format: "hittable == true"), evaluatedWith: self, handler: nil);
test.waitForExpectations(timeout: TimeInterval(wait), handler: nil)
}
tap()
}
}
次のように使用します。
app.buttons["start"].tap(wait: 20, test: self)
それらを並行して実行します。
ビルドマシンが1つしかない場合は、Bluepillを使用できます。 https://github.com/linkedin/bluepill
複数のマシンがある場合は、Emceeを使用できます: https://github.com/avito-tech/Emcee (単一のマシンのセットアップでも機能します)
50時間のUIテストがあり、Emceeでは1時間で実行できます。 UIテストを高速化するためのいくつかのトリックがありますが、それらを並行して実行しないと意味がありません。例えば。 25秒のテストを0.5秒で実行することはできません。
トリック:
_XCUIApplication(
privateWithPath: nil,
bundleID: "your.bundle.id"
)
_
注:アプリをインストールするには、XCUIテストランナーを起動するたびにXCUIApplication().launch()
でアプリを起動する必要があります。これにはプライベートAPIの使用が必要です。
_let someDataFromApi = getSomeData() // start request asynchronously and immediately return
launchApp() // this can be few seconds
useInTest(someDataFromApi) // access to data will wait request to finish
_
非同期のものがないようにコードを見せれば、QAの方が簡単になります。これを実装したいのですが、実装しなかったので、アイデアにすぎません。
EarlGreyに切り替えて、数秒続くテストを行います(ただし、ブラックボックスにはなりません)。
ディープリンクがある場合は、ディープリンクを介して画面を開きます。
プライベートAPIやその他のハックをたくさん使用します。例:UIから設定アプリに移動してプライバシー設定をリセットする代わりに、プライベートAPIを呼び出すことができます。
長い睡眠を決して使用しないでください。ポーリングを使用します。
アニメーションを高速化します。それらを無効にしないでください!
UIテストからアプリにいくつかのフラグを渡して、最初のアラート/チュートリアル/ポップアップをスキップします。多くの時間を節約できます。これらのアラートが機能することを確認するテストが少なくとも1つあることを確認してください。