Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
5¸ö×î¼ÑµÄAndroid²âÊÔ¿ò¼Ü£¨´øÊ¾Àý£©
 
ÒëÕߣºÐ¡·å À´Ô´£ºÂëÅ©Íø ·¢²¼ÓÚ£º 2015-04-22
  2310  次浏览      27
 

¹È¸èµÄAndroidÉú̬ϵͳÕýÔÚ²»¶ÏµØÑ¸ËÙÀ©ÕÅ¡£ÓÐÖ¤¾Ý±íÃ÷£¬ÐµÄÒÆ¶¯OEMÕýÔÚ¹¥ÏÝÊÀ½çµÄÿһ¸ö½ÇÂ䣬²»Í¬µÄÆÁÄ»³ß´ç¡¢ROM /¹Ì¼þ¡¢Ð¾Æ¬×éÒÔ¼°µÈµÈµÈµÈ£¬²ã³ö²»Çî¡£ÓÚÊǺõ£¬¶ÔÓÚAndroid¿ª·¢ÈËÔ±¶øÑÔ£¬´¦Àí´æ´¢Ë鯬±äµÃÔ½À´Ô½À§¾½¡£

²»¹ýÐÒÔ˵ÄÊÇ£¬Android£¨»¹ÓÐiOS£©¿ª·¢ÈËÔ±¿ÉÒÔÎÞÏÞÖÆµØ·ÃÎÊһЩÏȽøµÄ»ùÓÚÔÆµÄ½â¾ö·½°¸£¬ÈçTestdroid Cloud£¬¾Í¿ÉÒÔÔÚ´ó¹æÄ£µÄÕæÊµÉ豸ÉÏÖ´ÐÐ×Ô¶¯»¯²âÊÔÒÔÈ·±£ÖÊÁ¿£¬ÔÞ°É¡£´ËÍ⣬²»Í¬µÄAndroid²âÊÔ¿ò¼ÜµÄ³öÏÖÒ²´ó´ó¼õÇáÁËAndroid¿ª·¢ÈËÔ±µÄ¸ºµ£¡£

½ñÌ죬ÎÒÃǾÍҪ˵˵5¿î×î³£ÓõÄAndroid²âÊÔ¿ò¼Ü£¬²¢ÇÒÿ¸ö¿ò¼Ü¶¼¸ø³öÁË»ù±¾µÄ´úÂëʾÀý¡£

1.Robotium

²»¿É·ñÈÏ£¬RobotiumÔøÊÇAndroidÊÀ½çÖ®³õʹÓÃ×î¹ã·ºµÄAndroid²âÊÔ¿ò¼Ü£¬·çÃÒһʱ¡£ÓÉÓÚËüÓëAndroidÓÐ×ÅÏàËÆµÄSelenium£¬ËùÒÔËüÄܹ»Ê¹µÃAPIµÄ²âÊÔ±äµÃ¼òµ¥ÆðÀ´¡£

RobotiumÊÇÒ»¸öÀ©Õ¹ÓÚJUnitµÄ¿ªÔ´¿â£¬ÔËÓöàÖÖÓÐÓõķ½·¨À´Ö§³ÖAndroid UI²âÊÔ¡£ËüÌṩµÄÇ¿´óµÄ×Ô¶¯»¯ºÚÏä²âÊÔ·¶Àý£¬¿ÉÓÃÓÚAndroidÓ¦Óã¨Ô­ÉúµÄºÍ»ìºÏµÄ£©ºÍweb²âÊÔ¡£Ö»ÒªÔ´´úÂëÔÊÐí£¬Äã¾Í¿ÉÒÔͨ¹ýRobotiumд¹¦ÄÜ¡¢ÏµÍ³ºÍÑéÊÕ²âÊÔ·½°¸£¬ÒÔ¼°²âÊÔÓ¦Óá£

RobotiumµÄ´úÂëʾÀý£º

// Public void for the operation
public void testRecorded() throws Exception {
// Wait for the text 'Hello!' to be shown for newbie
if (solo.waitForText("Hello!")) {
// R class ID identifier for 'Sign in' - and click it
solo.clickOnView(solo.findViewById("com.twitter.android.R.id.sign_in"));
// R class ID identifier for entering username
solo.enterText((EditText)solo.findViewById("com.twitter.android.R.id.login_username"),"username");
// R class ID identifier for entering password
solo.enterText((EditText)solo.findViewById("com.twitter.android.R.id.login_password"),"password");
// R class ID identifier for clicking log in
solo.clickOnView(solo.findViewById("com.twitter.android.R.id.login_login"));
// Wait until log in is done
solo.waitForActivity("HomeTabActivity");
}
// Activate the text field to compose a tweet
solo.clickOnView(solo.findViewById("com.twitter.android.R.id.menu_compose_tweet"));
// Type the tweet
solo.enterText((EditText) solo.findViewById("com.twitter.android.R.id.edit"), "Testdroid");
// Tweeting!
solo.clickOnView(solo.findViewById("com.twitter.android.R.id.composer_post"));
}

ΪÁ˸ø´ó¼ÒÌṩ±ã½Ý£¬»¹ÓÐÒ»¸öÓÃRobotium¹¹½¨µÄÓÃÓÚ²âÊԽű¾´´½¨µÄÒ»¸ö·Ç³£°ôµÄ¼Ç¼¹¤¾ß¡ª¡ªTestdroid Recorder¡£µ±ÄãÔÚÕæÊµÉ豸ÉÏÖ´ÐÐʵ¼ÊÐж¯Ê±£¬Ëü¿ÉÒԼǼÄãµÄÿһ¸ö²½ÖèºÍÿһ¸öÐÐΪ£¬²¢×ª»»³ÉJavaScript£¬ÒÔ±ãÓÚÄã½øÒ»²½µÄÐ޸ġ£

²¢ÇÒ£¬Ä㻹¿ÉÒÔȫȨÏÂÔØºÍʹÓÃËüµÄÀ©Õ¹¿â¡ª¡ªExtSolo£¬ËüÀïÃæ°üº¬Á˶àÖÖ»¹Ã»Óб»ÄÉÈëµ½RobotiumÖеÄʵÓ÷½·¨£¬ÀýÈ磺

  • Ö§³ÖÈÎÒâ·Ö±æÂʵÄx¡¢Yµã»÷×Ô¶¯Ëõ·Å
  • ¶à·¾¶Í϶¯
  • ²âÊÔ¹ÊÕÏʱ×Ô¶¯½ØÍ¼
  • Ä£ÄâµØµã
  • ¸ü¸ÄÉ豸ÓïÑÔ
  • ¿ØÖÆWiFiÁ¬½Ó
  • ¹Ù·½ÍøÕ¾£ºhttps://code.google.com/p/robotium/

    2.uiautomator

    ËäÈ»RobotiumÊÇÒ»¸öºÜºÃµÄ²âÊÔ¿ò¼Ü£¬µ«ÊÇuiautomatorÄÜÈÃÄãÔÚ²âÊÔAndroidÓ¦ÓúÍAndroidÓÎϷʱ×öµÃ¸ü¶à¡£¹È¸èµÄ²âÊÔ¿ò¼ÜÔÊÐíÄãÔÚÒ»¸ö»ò¶à¸öÉ豸ÉϲâÊÔÔ­ÉúAndroidÓ¦ÓõÄÓû§½çÃæ£¨UI£©¡£UiautomatorµÄÁíÒ»¸öÓŵãÊÇ£¬ËüÔËÐеÄJUnit²âÊÔÓÃÀýÊÇÓÐÌØÊâȨÏ޵ģ¬ÕâÒâζ×ŲâÊÔÓÃÀý¿ÉÒÔ¿çÔ½²»Í¬µÄ½ø³Ì¡£Ëü»¹ÌṩÁËÎåÖÖ²»Í¬µÄÀà¸ø¿ª·¢ÈËԱʹÓãº

    com.android.uiautomator.core.UiCollection;
    com.android.uiautomator.core.UiDevice;
    com.android.uiautomator.core.UiObject;
    com.android.uiautomator.core.UiScrollable;
    com.android.uiautomator.core.UiSelector

    Òź¶µÄÊÇ£¬uiautomatorÖ»Äܹ¤×÷ÓÚAPI16»ò¸ü¸ß¼¶±ðµÄAndroidÉ豸ÉÏ¡£ËüµÄÁíÒ»¸öȱµãÊDz»Ö§³ÖwebÊÓͼ£¬Ò²Ã»Óа취ֱ½Ó·ÃÎÊAndroid¶ÔÏó¡£

    uiautomatorµÄ´úÂëʾÀý£º

    // Public void for the operation
    public void testSignInAndTweet() throws Exception {
    // Starting application:
    getUiDevice().wakeUp(); // Press Home button to ensure we're on homescreen
    getUiDevice().pressHome(); // Select 'Apps' and click button
    new UiObject(new UiSelector().description("Apps")).click(); // Select 'Twitter' and click
    new UiObject(new UiSelector().text("Twitter")).click(); // Locate and select 'Sign in'
    UiSelector signIn = new UiSelector().text("Sign In"); // If button is available, click
    UiObject signInButton = new UiObject(signIn);
    if (signInButton.exists()) {
    signInButton.click(); // Set the username
    new UiObject(new
    UiSelector().className("android.widget.EditText").instance(0)).setText("username");
    new UiObject(new
    UiSelector().className("android.widget.EditText").instance(1)).setText("password");
    new UiObject(new UiSelector().className("android.widget.Button").
    text("Sign In").instance(0)).click(); // Wait Sign in progress window
    getUiDevice().waitForWindowUpdate(null, 2000); // Wait for main window
    getUiDevice().waitForWindowUpdate(null, 30000);
    }
    new UiObject(new UiSelector().description("New tweet")).click(); // Typing text for a tweet
    new UiObject(new UiSelector().className("android.widget.LinearLayout").instance(8)).
    setText("Awesome #Testdroid!"); // Tweeting!
    new UiObject(new UiSelector().text("Tweet")).click();


    ¹Ù·½ÍøÕ¾£ºhttp://developer.android.com/tools/help/uiautomator/index.html

    3.Espresso

    EspressoÊÇÓÉGoogle¿ªÔ´µÄÒ»¿î×îеÄAndroid×Ô¶¯»¯²âÊÔ¿ò¼Ü£¬ÓÐÖúÓÚÓÚ¿ª·¢ÈËÔ±ºÍ²âÊÔÈËÔ±´¸Á¶³öÖÐÒâµÄÓû§½çÃæ¡£EspressoµÄAPIÌå»ýС¡¢¿ÉÔ¤¼û¡¢¼òµ¥Ò×ѧ£¬¹¹½¨ÔÚAndroidÒDZí¿ò¼ÜµÄ»ù´¡ÉÏ¡£Ê¹ÓÃËü£¬ÄÜÈÃÄã¿ìËÙ±àд³ö¼ò½à¿É¿¿µÄAndroid UI²âÊÔ¡£ËüÖ§³ÖAPI level 8¼¶£¨Froyo£©¡¢10£¨Gingerbread£©£¬ºÍ15£¨Ice Cream Sandwich£©¼°ºóÐø¡£

    Ò»·½ÃæËüÏ൱¿É¿¿£¬ÒòΪºÍUIÏß³ÌÊÇͬ²½µÄ£¬ÁíÒ»·½ÃæÓַdz£Ö®¿ì£¬ÒòΪûÓÐÈκÎ˯ÃߵıØÒª£¨µ±Ä³¸öºÁÃ룬ӦÓóÌÐò¿Õתʱ£¬ÔËÐвâÊÔ£©¡£²»¹ýËüͬÑù²»Ö§³ÖwebÊÓͼ¡£

    EspressoµÄ´úÂëʾÀý£º

    public void testEspresso() {
    // Check if view with the text 'Hello.' is shown
    onView(withText("Hello.")).check(matches(isDisplayed()));
    // R class ID identifier for 'Sign in' - and click it
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/sign_in", null, null))).perform(click());
    // R class ID identifier for entering username
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/login_username", null, null))).perform((typeText("username")));
    // R class ID identifier for entering password
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/login_password", null, null))).perform((typeText("password")));
    // R class ID identifier for clicking log in
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/login_login", null, null))).perform(click());
    // Activate the text field to compose a tweet
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/menu_compose_tweet", null, null))).perform(click());
    // Type the tweet
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/edit", null, null))).perform((typeText(¡±#Testdroid")));
    // Tweeting!
    onView(withId(getInstrumentation().getTargetContext().getResources()
    .getIdentifier("com.twitter.android:id/composer_post", null, null))).perform(click());
    }


    ¹Ù·½ÍøÕ¾£ºhttps://code.google.com/p/android-test-kit/wiki/Espresso

    4.Calabash

    CalabashÊÇÒ»¿î¿çƽ̨µÄ×Ô¶¯»¯²âÊÔ¿ò¼Ü£¬Ö§³ÖAndroidºÍiOSÔ­ÉúºÍ»ìºÏµÄÓ¦ÓóÌÐò¡£CalabashÒ×ÓÚÀí½âµÄÓï·¨£¬Ê¹µÃ¼´Ê¹ÊǷǼ¼ÊõÈËÔ±Ò²¿ÉÒÔÔÚÕâÁ½¸öÒÆ¶¯Æ½Ì¨ÉÏΪapp´´½¨ºÍÖ´ÐÐ×Ô¶¯»¯ÑéÊÕ²âÊÔ¡£CalabashµÄ²âÊÔÃèÊöÓÚCucumber£¬È»ºóÔÚÔËÐÐʱת»¯ÎªRobotium»òFrank¡£ËüÖ§³ÖÔ¼80ÖÖ²»Í¬µÄ×ÔÈ»ÓïÑÔÖ¸Á¿ØÖÆÆ÷£©£¬²¢ÇÒ¿ÉÒÔʹÓÃRubyºÍJavaʵÏÖеĿØÖÆÆ÷¡£

    CalabashµÄ´úÂëʾÀý£º

    Feature: Login feature
    Scenario: As a valid user I can log into my app
    I wait for text "Hello"
    Then I press view with id "Sign in"
    Then I enter text "username" into "login_username"
    Then I enter text "password" into "login_password"
    Then I wait for activity "HomeTabActivity"
    Then I press view with id "menu_compose_tweet"
    Then I enter text "Testdroid" into field with id "edit"
    Then I press view with id "composer_post"=16


    ¹Ù·½ÍøÕ¾£ºhttp://calaba.sh/

    5.Appium

    AppiumÊÇÒ»¿îÒÆ¶¯µÄ×Ô¶¯»¯²âÊÔ¿ò¼Ü£¨ºÍ¹¤¾ß£©£¬Ö§³ÖiOSºÍAndroidÔ­ÉúºÍ»ìºÏµÄÒÆ¶¯WebÓ¦ÓóÌÐò¡£ËüÄÚ²¿Ê¹ÓõÄJSONWireProtocolͨ¹ýSeleniumµÄWebDriver£¬À´ÓëiOSºÍAndroidÓ¦ÓýøÐн»»¥¡£Ëüͨ¹ýuiautomator£¨API level 16»ò¸ü¸ß£©ºÍSeledroid£¨API level µÍÓÚ16£©Ö§³ÖAndroid£¬Í¨¹ýUI AutomationÖ§³ÖiOS£¬»¹ÓÐAndroidºÍiOS¶¼Ö§³ÖµÄÒÆ¶¯webÈçSelenium driver¡£

    AppiumµÄ×î´óÓŵãÔÚÓÚÄ㼸ºõ¿ÉÒÔÓÃÈÎÒâÒ»ÖÖ±à³ÌÓïÑÔ£¨ÀýÈ磬Java¡¢Objective-C¡¢JavaScript¡¢PHP¡¢Ruby¡¢PythonºÍC££µÈ£©À´±àдAppium½Å±¾¶ø²»±ØÑ¡Ôñ¹¤¾ß£¬¼æÈÝ×îÖØÒªµÄƽ̨£¨AndroidºÍiOS£©¶ø²»±Ø°²×°ºÍÅäÖÃÉ豸ÊÊÓ¦²âÊԵȵȡ£²¢ÇÒ£¬Èç¹ûÄãÊìϤSeleniumµÄ»°£¬ÄÇôʹÓÃAppiumÓÃÓÚÒÆ¶¯app²âÊÔ¶ÔÄã¶øÑÔ½«ÊÇÇá¶øÒ×¾ÙµÄÒ»¼þÊ¡£ÒòΪËüÃÇʹÓÃÏàͬµÄWebDriver£¬²¢ÇÒÒÔͬÑùµÄ·½Ê½Ê¹ÓÃDesiredCapabilities¡£ËùÒÔAppiumÓëSeleniumÔÚÅäÖÃÓ¦ÓóÌÐòÔËÐÐʱÓÐÖî¶àÏàËÆÖ®´¦¡£

    AppiumµÄ´úÂëʾÀý£º

    # wait for hello
    sleep(3)
    textFields = driver.find_elements_by_tag_name('textField')
    assertEqual(textFields[0].get_attribute("value"), "Hello")
    # click sign-in button
    driver.find_elements_by_name('Sign in')[0].click()
    # find the text fields again, and enter username and password
    textFields = driver.find_elements_by_tag_name('textField')
    textFields[0].send_keys("twitter_username")
    textFields[1].send_keys("passw0rd")
    # click the Login button (the first button in the view)
    driver.find_elements_by_tag_name('button')[0].click()
    # sleep
    sleep(3)
    # click the first button with name "Compose"
    driver.find_elements_by_name('Compose')[0].click()
    # type in the tweet message
    driver.find_elements_by_tag_name('textField')[0].send_keys(¡±#Testdroid is awesome!")
    # press the Send button
    driver.find_elements_by_name('Send')[0].click()
    # exit
    driver.quit()


    ¹Ù·½ÍøÕ¾£ºhttp://appium.io/

    ×ܽá

    ÒÔÉϾÍÊÇÎÒÃÇÁгöµÄ5¿î×î°ôµÄ²âÊÔ¿ò¼Ü£¬¿ÉÓÃÓÚÈÕ³£µÄAndroid¹¹½¨£¬´´Á¢ºÍÐ޸ġ£µ±È»£¬Ã¿Ò»ÖÖ¿ò¼Ü¶¼ÓÐÆäÓÅÊÆºÍȱÏÝ¡£Appium¿ÉÒÔͬʱ²âÊÔÄãµÄAndroidºÍiOS°æ±¾¡£µ«Èç¹ûÄãÊÇÒ»¸öÖÒʵµÄAndroid¿ª·¢ÈËÔ±Ö»¿ª·¢°²×¿°æ±¾µÄapp£¬ÄÇô£¬Ê¹ÓÃRobotium¾ÍºÜ²»´íµÄ¡£Testdroid Recorder»¹¿ÉΪÎÒÃÇÔÚÉú³É²âÊԽű¾½ÚÊ¡´óÁ¿µÄʱ¼äºÍ½ðÇ®£¨ÕâÊÇÃâ·ÑµÄŶ£¡£©¡£Òò´Ë£¬ºÃºÃ˼¿¼ÏÂÄãµÄ²âÊÔÐèÇ󡪡ª¹¦ÄܲâÊÔ¡¢¼æÈÝÐÔ²âÊÔ¡¢UI²âÊԵȵȡª¡ªÈ»ºóΪ×Ô¼ºÑ¡È¡×îÊʺϺÍ×î¼ÑµÄAndroid²âÊÔ¿ò¼Ü¡£

       
    2310 ´Îä¯ÀÀ       27
     
    Ïà¹ØÎÄÕÂ

    ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
    ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
    iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
    AndroidÊÖ»ú¿ª·¢£¨Ò»£©
     
    Ïà¹ØÎĵµ

    Android_UI¹Ù·½Éè¼Æ½Ì³Ì
    ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
    androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
    Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
    Ïà¹Ø¿Î³Ì

    Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
    Androidϵͳ¿ª·¢
    AndroidÓ¦Óÿª·¢
    ÊÖ»úÈí¼þ²âÊÔ
    ×îл¼Æ»®
    DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
    DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
    UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
    AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
    »ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
    ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

    androidÈË»ú½çÃæÖ¸ÄÏ
    AndroidÊÖ»ú¿ª·¢£¨Ò»£©
    AndroidÊÖ»ú¿ª·¢£¨¶þ£©
    AndroidÊÖ»ú¿ª·¢£¨Èý£©
    AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
    iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
    ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
    ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
    ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


    Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
    AndroidÓ¦Óÿª·¢
    Androidϵͳ¿ª·¢
    ÊÖ»úÈí¼þ²âÊÔ
    ǶÈëʽÈí¼þ²âÊÔ
    AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


    ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
    ±±¾© Android¿ª·¢¼¼Êõ½ø½×
    ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
    ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
    °¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
    °¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
    Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ