プログラムによってUIButtonへのタッチイベントを偽造する方法


183

私はいくつかの単体テストを書いていますが、この特定のアプリの性質上、UIできる限りチェーンを高くすることが重要です。したがって、ユーザーがでボタンを押した場合と同じように、プログラムでボタンを押すようにしたいと思いますGUI

(はい、はい-私は可能性があり呼び出すだけIBActionセレクタをしかし、再び、この特定のアプリの性質は、それが重要なことに、このようなIの偽の実際のボタンを押し、ということになりIBAction、ボタンから呼び出すことが、自分自身。)

これを行うための好ましい方法は何ですか?


アクションメソッドを直接呼び出すのではなく、ボタンタッチを偽造することが重要である理由を説明できますか?実際には違いはありません。
Jasarien

1
@Jasarien:違いますからね!;)私のアプリでは、いくつかのボタンが同じアクションメソッドを使用しており、メソッドはボタンのタグに基づいて動作方法を解析します。したがって、ユニットテストでは、メソッドを介して特定のコードパスをテストすることに加えて、(a)すべてをテストする必要があり、(b)ボタンが正しく配線されていることも確認します。さらに、次のようなテキストファイルの行としてユニットテストを定義できるため、ユニットテストスイートをうまく抽象化します。「1 + 2 = 3」。どのボタンを押すかです。
Olie

アクションメソッドに(id)senderパラメータがありませんか?メソッドを呼び出してボタンを送信者として渡すことはできませんか?
ジャサリエン

3
私のテストハーネスの抽象的な性質のため、特定のボタンに対して呼び出す必要があるメソッドを知りません。ボタンを掘り下げて取得できると思いますが、sendActionsForControlEvents:を実行すると、エラーが発生する可能性が少なくなり、テストの要約とデザインの適合性が維持されます。
Olie

回答:


459

それが判明

[buttonObj sendActionsForControlEvents: UIControlEventTouchUpInside];

この場合、必要なものを正確に手に入れました。

編集:ユーザープレスと同様の結果を得るために、メインスレッドでこれを行うことを忘れないでください。


Swift 3の場合:

buttonObj.sendActions(for: .touchUpInside)


呼び出しと違いはありません[myController myActionMethod:myButton1];
Jasarien

11
コメントレスポンスに大きな制約があります;)
Dan Rosenstark、2010

@Jasarienは、登録されたすべてのターゲット(リスナー)にタッチイベントを送信するため、かなり異なります。
htafoya 2013年

2
残念ながら、これらはどちらも常に機能するわけではありません。たとえば、タップジェスチャーではなく、UIControlであるレシーバーに依存しています。
tooluser 2013年

1
@ChenLiYong、その理由の1つmyActionMethod:は、公開されていないためであり、直接呼び出すことはできません。
Iulian Onofrei 2016年

50

Swiftのこの回答の更新

buttonObj.sendActionsForControlEvents(.TouchUpInside)

編集:Swift 3用に更新

buttonObj.sendActions(for: .touchUpInside)

1
私はそれを言うだろう:buttonObj.sendActionsForControlEvents(.TouchUpInside)はさらにSwiftスタイルです;)
Sajjon '19

1
実行ループがサポートされていないボタンがXCTestCaseで作成された場合、これは機能しないと思います。
CopperCash

6

この種のテストを行う場合は、iOS 4のUIオートメーションサポートを気に入っていただけます。ドキュメント(特に開始部分)は少しですが、ボタンを押すなどをシミュレートするJavaScriptを簡単に作成できます。疎。


1
うん、それはクールだが、(それはあなたが意味する方法だ場合。)私は、アプリ内からではなく、楽器を経由して、それをやろうとしている
Olie

Instrumentsはアプリで実行されます。アプリはまだ実行中ですが、Instrumentsはタッチをシミュレートするだけです。
ジェフケリー

6
Instruments、Jeffについて理解しています。つまり、ラップトップやXCodeやInstrumentsが手元にない状態で、ユニットテストをポケット内のデバイスで実行したいのです。または、デバイスで機器を実行する秘密を知っていますか?;)
Olie

6

スウィフト3:

self.btn.sendActions(for: .touchUpInside)

3
これは、より高いスコアの回答を繰り返すだけです。
2017

5

この場合、UIButtonはから導出されUIControlます。これは、から派生しUIControlたオブジェクトに対して機能します。

UIBarButtonItem特定のユースケースで「」アクションを再利用したかった。ここでUIBarButtonItemは方法を提供していませんsendActionsForControlEvents:

しかし幸いにも、UIBarButtonItemターゲットとアクションのプロパティがあります。

 if(notHappy){        
         SEL exit = self.navigationItem.rightBarButtonItem.action;
         id  world = self.navigationItem.rightBarButtonItem.target;
         [world performSelector:exit];
 }

ここでrightBarButtonItemは、タイプUIBarButtonItemです。


UIBarButtonItemを使用する場合は、[self doAction:self.navigationItem.rightBarButtonItem]だけを使用できます。//-doAction:is.navigationItem.rightBarButtonItemのトグルアクション名です。
2013


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.