your programing

여러 활동에서 Android 애플리케이션을 어떻게 테스트합니까?

lovepro 2020. 10. 10. 10:46
반응형

여러 활동에서 Android 애플리케이션을 어떻게 테스트합니까?


우리는 많은 활동에 분산 된 많은 화면과 워크 플로로 구성된 복잡한 Android 애플리케이션을 구축하고 있습니다. 우리의 워크 플로우는 은행의 ATM 기계에서 볼 수있는 것과 유사합니다. 예를 들어 사용자의 선택에 따라 다른 활동으로 전환 할 수 Activity있는 메인 메뉴로 전환하는 로그인 Activity이 있습니다.

워크 플로가 너무 많기 때문에 워크 플로를 끝에서 끝까지 테스트 할 수 있도록 여러 활동에 걸쳐 자동화 된 테스트를 만들어야합니다. 예를 들어, ATM 예제를 사용하여 유효한 PIN을 입력하고, 우리를 메인 메뉴로 보내는 지 확인하고, 현금 인출을 선택하고, 우리가 현금 인출 화면에 있는지 등을 확인하고, 결국 우리 자신을 찾을 수 있습니다. 메인 메뉴로 돌아가거나 "로그 아웃"했습니다.

우리는 Android (예 ActivityInstrumentationTestCase2) 및 Positron함께 제공되는 테스트 API를 가지고 놀았 지만 둘 다 하나의 범위를 넘어서 테스트 할 수있는 것 같지 않으며 Activity이러한 도구에서 일부 단위 테스트를위한 유틸리티를 찾을 수 있지만 이겼습니다. 여러 활동에 걸쳐있는 테스트 시나리오에 대한 우리의 요구를 충족하지 못합니다.

우리는 xUnit 프레임 워크, 스크립팅, GUI 레코더 / 재생 등에 대해 열려 있으며 조언을 주시면 감사하겠습니다.


내 바운티 질문에 답하는 것이 조금 어색하지만 여기에 있습니다 ...

나는 이것에 대해 높고 낮은 것을 검색했으며 어디에도 게시 된 답변이 없다는 것을 믿을 수 없습니다. 나는 아주 가까이 왔습니다. 지금은 활동에 걸친 테스트를 확실히 실행할 수 있지만, 제 구현에는 테스트가 항상 안정적으로 통과하지 못하는 타이밍 문제가있는 것 같습니다. 이것은 여러 활동에서 성공적으로 테스트한다는 것을 알고있는 유일한 예입니다. 내 추출 및 익명화로 인해 오류가 발생하지 않았기를 바랍니다. 이것은 로그인 활동에 사용자 이름과 비밀번호를 입력 한 다음 다른 "환영"활동에 적절한 환영 메시지가 표시되는 것을 관찰하는 간단한 테스트입니다.

package com.mycompany;

import android.app.*;
import android.content.*;
import android.test.*;
import android.test.suitebuilder.annotation.*;
import android.util.*;
import android.view.*;
import android.widget.*;

import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsNull.*;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.*;
import static com.mycompany.R.id.*;

public class LoginTests extends InstrumentationTestCase {

   @MediumTest
   public void testAValidUserCanLogIn() {

      Instrumentation instrumentation = getInstrumentation();

      // Register we are interested in the authentication activiry...
      Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(AuthenticateActivity.class.getName(), null, false);

      // Start the authentication activity as the first activity...
      Intent intent = new Intent(Intent.ACTION_MAIN);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      intent.setClassName(instrumentation.getTargetContext(), AuthenticateActivity.class.getName());
      instrumentation.startActivitySync(intent);

      // Wait for it to start...
      Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);
      assertThat(currentActivity, is(notNullValue()));

      // Type into the username field...
      View currentView = currentActivity.findViewById(username_field);
      assertThat(currentView, is(notNullValue()));
      assertThat(currentView, instanceOf(EditText.class));
      TouchUtils.clickView(this, currentView);
      instrumentation.sendStringSync("MyUsername");

      // Type into the password field...
      currentView = currentActivity.findViewById(password_field);
      assertThat(currentView, is(notNullValue()));
      assertThat(currentView, instanceOf(EditText.class));
      TouchUtils.clickView(this, currentView);
      instrumentation.sendStringSync("MyPassword");

      // Register we are interested in the welcome activity...
      // this has to be done before we do something that will send us to that
      // activity...
      instrumentation.removeMonitor(monitor);
      monitor = instrumentation.addMonitor(WelcomeActivity.class.getName(), null, false);

      // Click the login button...
      currentView = currentActivity.findViewById(login_button;
      assertThat(currentView, is(notNullValue()));
      assertThat(currentView, instanceOf(Button.class));
      TouchUtils.clickView(this, currentView);

      // Wait for the welcome page to start...
      currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5);
      assertThat(currentActivity, is(notNullValue()));

      // Make sure we are logged in...
      currentView = currentActivity.findViewById(welcome_message);
      assertThat(currentView, is(notNullValue()));
      assertThat(currentView, instanceOf(TextView.class));
      assertThat(((TextView)currentView).getText().toString(), is("Welcome, MyUsername!"));
   }
}

이 코드는 분명히 읽기 어렵습니다. 실제로 영어와 유사한 API를 사용하여 간단한 라이브러리로 추출 했으므로 다음과 같이 말할 수 있습니다.

type("myUsername").intoThe(username_field);
click(login_button);

나는 약 4 개의 활동을 깊이 테스트했고 내가 말했듯이 접근 방식이 효과가 있다는 것에 만족한다. 가끔 내가 완전히 파악하지 못한 타이밍 문제가있는 것 같다. 활동 전반에 걸친 다른 테스트 방법에 대해 듣고 싶습니다.


Robotium 'Android 애플리케이션의 자동 블랙 박스 테스트를 즉시 사용할 수있는 Android 계측 테스트로 가능한 것보다 훨씬 빠르고 쉽게 만들기 위해 만들어진 오픈 소스 테스트 프레임 워크'를 살펴보세요
.

홈페이지 : http://www.robotium.org/
출처 : http://github.com/jayway/robotium

Robotium 프로젝트는 제가 근무하는 회사에서 관리하고 있습니다.


항상 Robotium을 사용할 수 있습니다. Selenium과 마찬가지로 Android 용 블랙 박스 테스트를 지원합니다. Robotium.org에서 찾을 수 있습니다.


아무도 선도적 인 자동화 기능 테스트 도구를 언급하지 않은 것에 놀랐습니다 . Robotium과 비교하면 Java 코드를 작성할 필요가 없습니다.

MonkeyTalk : Gorilla Logic 사가 지원하는 오픈 소스 도구입니다. 장점 : 기술이없는 사용자에게 더 쉽게 녹음 및 고급 스크립팅 언어를 제공하며 크로스 플랫폼 (iOS 포함)입니다. 이러한 이점을 요구 사항으로 고려할 때 이것이 최상의 솔루션이라는 것을 알게되었습니다. 또한Javascript를 사용하여 스크립팅 언어로 수행 할 수있는 것 이상의 사용자 정의허용합니다.

Calabash-Android : Cucumber 스타일 기능을위한 오픈 소스 도구입니다. 장점 : 비즈니스에서 읽을 수있는 Gherkin 언어로 기능을 작성하고 해당 동작이 구현되는 방법을 자세히 설명하지 않고도 소프트웨어의 동작을 설명 할 수 있습니다. cucumber-ios의 iOS에 대해 유사하지만 정확한 지원이 제공되지 않습니다. 녹음 기능은 바이너리 출력을 생성하기 때문에 좋지 않습니다.

몇 가지 다른 참조 :

  • Robotium, Monkeytalk 및 Calabash의 추가 비교 는 다음과 같습니다 . 또 다른 가능성으로 TestDroid언급합니다 .
  • 블로그 는 위의 내용과 NativeDriver 및 Bot-bot을 언급합니다.

Android 용 녹음 및 재생 도구를 만들어 GitHub에서 사용할 수 있도록했습니다 . 구성 및 사용이 쉽고 프로그래밍이 필요하지 않으며 실제 장치 (루팅 할 필요가 없음)에서 실행되며 테스트를 재생할 때 스크린 샷을 자동으로 저장합니다.


우선, 'InstrumentationTestCase'가 아닌 'ActivityInstrumentationTestCase2'를 기본 클래스로 사용하십시오. 저는 Robotium을 사용하고 여러 활동에서 정기적으로 테스트합니다. 로그인 활동을 제네릭 유형 (및 생성자에 대한 클래스 인수)으로 지정해야한다는 것을 알았습니다.

'ActivityInstrumentationTestCase2'생성자는 패키지 인수를 무시하고 필요하지 않습니다. 패키지를받는 생성자는 더 이상 사용되지 않습니다.

From the Javadocs: "ActivityInstrumentationTestCase2(String pkg, Class activityClass) This constructor is deprecated. use ActivityInstrumentationTestCase2(Class) instead"

Using the recommended base class allows the framework to handle certain boilerplate, like starting your activity. That's done by the call to 'getActivity()', if necessary.


Found this useful with a couple of modifications. Firstly getInstrumentation().waitForIdleSync() will cure the flakiness SingleShot speaks of and also InstrumentationTestCase has a lauchActivity function that can replace the start activity lines.


you can do it like this to avoid the flake waiting times out of sync :

final Button btnLogin = (Button) getActivity().findViewById(R.id.button);
Instrumentation instrumentation = getInstrumentation();

// Register we are interested in the authentication activity...
Instrumentation.ActivityMonitor aMonitor = 
        instrumentation.addMonitor(mynextActivity.class.getName(), null, false);

getInstrumentation().runOnMainSync(new Runnable() {
         public void run() {
             btnLogin.performClick();
         }
     });

getInstrumentation().waitForIdleSync();

//check if we got at least one hit on the new activity
assertTrue(getInstrumentation().checkMonitorHit(aMonitor, 1)); 

I'm working on pretty much the same thing, and I'll probably go with a variation on the accepted answer to this question, but I did come across Calculuon (gitHub) during my searches for a solution.


I haven't personally used it, but ApplicationTestCase looks like it might be what you're looking for.


Will accepted approach work with different Activities from different Applications, signed by different certificates? If not, Robotium the best way to test activities within same application.


There is another way to do the multiple activity using ActivityInstrumentation Class.. Its a normal automation scenario... First get the focus of what ever object you want and then send a key Simple as that sample code

button.requestFocus();
sendKeys(KeyEvent.KEYCODE_ENTER);

Only thing is understanding the every API calls will help us.


This answer is based on the accepted answer but modified to solve the timing issue which for me became consistent after adding about a half dozen tests. @pajato1 gets the credit for solving the timing issue, as cited in the accepted answer comments.

/**
 * Creates a test Activity for a given fully qualified test class name.
 *
 * @param fullyQualifiedClassName The fully qualified name of test activity class.
 *
 * @return The test activity object or null if it could not be located.
 */
protected AbstractTestActivity getTestActivity(final String fullyQualifiedClassName) {
    AbstractTestActivity result = null;

    // Register our interest in the given activity and start it.
    Log.d(TAG, String.format("Running test (%s) with main class: %s.", getName(), fullyQualifiedClassName));
    instrumentation = getInstrumentation();

    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setClassName(instrumentation.getTargetContext(), fullyQualifiedClassName);
    // Wait for the activity to finish starting
    Activity activity = instrumentation.startActivitySync(intent);

    // Perform basic sanity checks.
    assertTrue("The activity is null!  Aborting.", activity != null);
    String format = "The test activity is of the wrong type (%s).";
    assertTrue(String.format(format, activity.getClass().getName()), activity.getClass().getName().equals(fullyQualifiedClassName));
    result = (AbstractTestActivity) activity;

    return result;
}

Try the Monkey tool testing

Step 1:

open the android studio terminal(Tools-> open terminal)

Step 2:

In order to use monkey , open up a command prompt and just naviagte to the following directory.

 export PATH=$PATH:/home/adt-bundle-linux-x86-20140702/sdk/platform-tools

Step 3:

add this monkey command into terminal and press enter..

see the magic in your emulator.

adb shell monkey -p com.example.yourpackage -v 500

500- it is the frequency count or the number of events to be sent for testing.

you can change this count..

More reference,

http://www.tutorialspoint.com/android/android_testing.htm

http://androidtesting.blogspot.in/2012/04/android-testing-with-monkey-tool.html

참고URL : https://stackoverflow.com/questions/1759626/how-do-you-test-an-android-application-across-multiple-activities

반응형