bir UIButton için bir dokunma olayı programlı olarak sahte nasıl


183

Bazı birim testleri yazıyorum ve bu uygulamanın doğası gereği UIzinciri olabildiğince yükseğe çıkarmam önemlidir . Yani, yapmak istediğim şey, sanki kullanıcı düğmeye basmış gibi programlı olarak bir düğmeye basmayı tetiklemek GUI.

(Evet, evet - ben olabilir sadece çağrı IBActionyine bu özel uygulamanın doğası yapar, seçici ama önemli ben sahte olduğunu, öyle ki gerçek düğme baskı, IBAction., Düğmesinden kendisini çağrılabilir)

Bunu yapmanın tercih edilen yöntemi nedir?


Eylem yöntemini doğrudan çağırmak yerine düğme dokunuşunu taklit etmenin neden önemli olduğunu açıklayabilir misiniz? Gerçekten pratik bir fark yok.
Jasarien

1
@Jasarien: iyi, çünkü bir fark var! ;) Uygulamamda, birkaç düğme aynı eylem yöntemini kullanır ve yöntem düğmenin etiketine göre nasıl davranacağını ayrıştırır. Bu nedenle, birim testi, yöntem yoluyla belirli bir kod yolunu test etmenin yanı sıra, (a) hepsini test etmelidir ve (b) düğmelerin doğru bağlandığını da doğrular. Ayrıca, birim test paketimi güzel bir şekilde soyutlar, ünite testlerini bir metin dosyasında şöyle bir şeyle satır olarak tanımlayabilirim: "1 + 2 = 3", burada "3" beklenen bitiş ekranı ve bundan önceki her şey hangi düğmeye basacağınızdır.
Olie

eylem yönteminizin (id) gönderen parametresi yok mu? Sadece yöntemi çağırıp düğmeyi gönderici olarak iletemez misiniz?
Jasarien

3
Çünkü benim test koşum soyut doğası nedeniyle, ben yok BİLMEK ihtiyaçlarını belirli bir düğme için çağrılacak bu yöntemi. Düğmeye girip alabilirim, ancak sendActionsForControlEvents yapmak: tüm bunları benim için, daha az hata fırsatı ile yapar ve testi soyut ve tasarım ile uyumlu tutar.
Olie

Yanıtlar:


459

Şekline dönüştü

[buttonObj sendActionsForControlEvents: UIControlEventTouchUpInside];

Bana tam da ihtiyacım olanı aldım, bu durumda.

EDIT: Kullanıcı basına benzer sonuçlar elde etmek için bunu ana iş parçacığında yapmayı unutmayın.


Swift 3 için:

buttonObj.sendActions(for: .touchUpInside)


[myController myActionMethod:myButton1];
Aramak

11
Yorum tepkilerinizde büyük bir kısıtlama var;)
Dan Rosenstark

@Jasarien, dokunma etkinliğini tüm kayıtlı hedeflere (dinleyiciler) göndereceğinden oldukça farklıdır.
htafoya

2
Ne yazık ki, bunların hiçbiri her zaman işe yaramaz - örneğin bir dokunma hareketine sahip olmak yerine alıcıya bir UIControl olduğuna güvenirler.
alet kullanıcısı

1
@ChenLiYong, Bir nedeni myActionMethod:kamuya açık değilse ve doğrudan arayamazsınız .
Iulian Onofrei

50

Swift için bu cevaba bir güncelleme

buttonObj.sendActionsForControlEvents(.TouchUpInside)

EDIT : Swift 3 için güncellendi

buttonObj.sendActions(for: .touchUpInside)

1
Bunu söyleyebilirim: buttonObj.sendActionsForControlEvents (.TouchUpInside) daha da hızlı tarzı;)
Sajjon

1
Düğme bir çalışma döngü desteği olmadan bir XCTestCase oluşturulursa bu işe yarayacağını sanmıyorum.
CopperCash

6

Bu tür bir test yapmak istiyorsanız, iOS 4'teki UI Otomasyon desteğini seveceksiniz. Dokümantasyon (özellikle başlangıç ​​kısmı) biraz olsa da, düğme basmalarını vb. Taklit etmek için JavaScript yazabilirsiniz. seyrek.


1
Evet, bu harika şeyler, ama bunu uygulama içinden yapmaya çalışıyorum, enstrümanlar üzerinden değil (demek istediğin yöntem buysa.)
Olie

Cihazlar uygulamanızla çalışır. Uygulama hala çalışıyor, Cihazlar sadece dokunmayı simüle ediyor.
Jeff Kelley

6
Aletleri anladım, Jeff - dediğim şey: Birim testlerimin dizüstü bilgisayar veya XCode veya Aletler kullanmadan cebimdeki cihazda çalışmasını istiyorum. Yoksa cihazda alet çalıştırmanın sırrını biliyor musunuz? ;)
Olie

6

Hızlı 3:

self.btn.sendActions(for: .touchUpInside)

3
Bu sadece yüksek puanları tekrarlıyor.
Pang

5

Bu durumda, UIButtontüretilmiştir UIControl. Bu, türetilmiş nesne için çalışır UIControl.

UIBarButtonItemBelirli bir kullanım durumunda " " işlemini yeniden kullanmak istedim . Burada, UIBarButtonItemyöntem sunmuyorsendActionsForControlEvents:

Ama neyse ki, UIBarButtonItemhedef ve eylem için özelliklere sahip.

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

Burada bir rightBarButtonItemtür UIBarButtonItem.


UIBarButtonItem kullanıyorsanız, sadece [self doAction: self.navigationItem.rightBarButtonItem]; // - doAction: self.navigationItem.rightBarButtonItem'in geçiş eylem adıdır.
c0ming


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.