여기에 뭔가 빠져 있어야합니다. ActivityUnitTestCase
의 JavaDoc은이 테스트 사례가 시스템과 분리 된 활동을 테스트 할 것을 제안합니다.ActivityUnitTestCase가 Application.onCreate를 호출하지 못하게하는 방법은 무엇입니까?
이 클래스는 단일 활동에 대한 독립적 인 테스트를 제공합니다. 테스트중인 액티비티는 시스템 인프라에 최소한의 연결만으로 만들어지며 많은 액티비티 종속성의 조롱 된 버전이나 래퍼 버전을 삽입 할 수 있습니다.
실제로 응용 프로그램을 시작하지 않는 것으로 가정하고있었습니다. 또한 setApplication
도우미를 노출하여 모의 응용 프로그램을 삽입하는 데 아마도 사용할 수 있습니다.
그러나 어떤 ActivityUnitTestCase
나 (실제) 응용 프로그램을 시작하고 해당 onCreate
메서드를 호출합니다. 정확하게 말하자면, InstrumentationTestRunner
은 그 일을하고있는 것처럼 보입니다. 그렇기 때문에, 전에 setApplication
에 setUp
메쏘드에 들어갈 기회가 생겼습니다! 테스트 스위트를 실행하는 동안 심지어 Eclipse 중단 점에 도달하지 못했지만 실제로 로그에 기록하면 onCreate
이 실제로 호출되었다는 것을 알게되어 꽤 오래 동안 알 수 없었습니다.
이것은 완전히 저쪽에 있습니다. Android 테스트 주자가 실제 애플리케이션을 인스턴스화하고 실행하는 중에 mock 앱 객체를 사용하려는 이유는 무엇입니까? 이것은 계측 러너가 자체 스레드에서 실행되고이를 수행 할 때 주 응용 프로그램 스레드를 생성한다는 점을 감안할 때 더욱 문제가됩니다. 즉, 실행중인 테스트와 Application.onCreate
이 호출되는 사이에 경쟁 조건이 있음을 의미합니다. 테스트 결과에 영향을 미칠 수있는 내용이 있다면 공유 환경 설정 파일에 쓰면 테스트가 무작위로 실패하기 때문에 완전히 망가져 버립니다.
테스트 프레임 워크에서 무언가가 누락되었거나 간단하게 표시 되었습니까?
업데이트 이것은 ApplicationTestCase
에도 영향을 미치는 것으로 보입니다. 테스트 케이스가 시작되기 전에 어플리케이션 클래스 'onCreate
에서 중단 점에 도달 할 수 있습니다. 우리는 무의식적으로 AsyncTask를 시작합니다. 무의식적으로 실패 할 것이기 때문에 무작위로 실패 할 것입니다. 기억하십시오. 내 테스트 케이스에서는 setUp
이 호출되기 전에 있습니다. 저는 여기에서 onCreate이 모호한 호출 중에 참조 스택 추적은 다음과 같습니다
Thread [<1> main] (Suspended (breakpoint at line 86 in QypeRadar))
QypeRadar.onCreate() line: 86
InstrumentationTestRunner(Instrumentation).callApplicationOnCreate(Application) line: 969
ActivityThread.handleBindApplication(ActivityThread$AppBindData) line: 4244
ActivityThread.access$3000(ActivityThread, ActivityThread$AppBindData) line: 125
ActivityThread$H.handleMessage(Message) line: 2071
ActivityThread$H(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4627
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 868
ZygoteInit.main(String[]) line: 626
NativeStart.main(String[]) line: not available [native method]
이유는 무엇입니까 테스트 러너 callApplicationOnCreate
도 the docs하지만 분명히 상태 :
테스트 케이스에서 onCreate()를 할 때까지 호출 할 것이다 테스트는 createApplication()을 호출합니다. 따라서 onCreate() 전에 추가 프레임 워크 또는 테스트 논리를 설정하거나 조정할 수 있습니다.
평평한 거짓말 - 내게 기회가되지 않습니다!
내가 알 수있는 한,이 문제를 해결할 수있는 방법은 두 가지뿐입니다. 1) InstrumentationTestRunner를 다시 작성하여 callApplicationOnCreate를 호출하지 않고 테스트 케이스에 남겨 두어 원하는지 여부를 결정합니다. 하지만 다른 테스트에서 어떤 영향을 미칠지 확실하지 않습니다. 2) 우리의 onCreate 메소드를 부작용이없고 멱등 한 것으로 다시 작성하십시오. (테스트 케이스가 작동하기 때문에'createApplication'도 호출해야합니다.) 생각? – Matthias
그래서 callApplicationOnCreate를 우회하는 커스텀 테스트 러너를 만들었습니다. 이제는 모든 것이 * unit * 테스트에서 예상대로 작동합니다. 기능 테스트의 경우 전체 실행을 수행하는 기본 테스트 러너가 필요하므로 이제 테스트 용 러너가 2 개 있습니다. 이는 약간의 고통입니다. – Matthias
흥미로운 글쓰기. 적절한 테스트 케이스 유형에 대해서만'callApplicationOnCreate'를 우회하는 것만으로도 충분히 간단 할 수 있습니다. 여러분은 업스트림으로 보낼 수있는 테스트 러너 용 패치를 만들 수 있습니까? –