Top Banner
Автоматизация Тестирования Мобильных Приложений Андрей Дзыня
58

Mobile automation uamobile

May 15, 2015

Download

Technology

UA Mobile
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Mobile automation uamobile

Автоматизация Тестирования Мобильных Приложений

Андрей Дзыня

Page 2: Mobile automation uamobile

Andrii Dzynia

http://adzynia.com

Test Engineer/Consultant/Trainer

@adzynia

Page 3: Mobile automation uamobile

Сегодня

Почему я начал заниматься автоматизацией мобильных приложений?

Какие есть инструменты?

Какие проблемы решены, а какие нет?

Page 4: Mobile automation uamobile

Мой опыт

Page 5: Mobile automation uamobile

Кто у нас в зале?

Page 6: Mobile automation uamobile

Особенность мобильной разработки?

Page 7: Mobile automation uamobile
Page 8: Mobile automation uamobile

Типы приложений?

Web

Native

Hybrid

OpenGL

Flash & Flex

Widgets

Page 9: Mobile automation uamobile
Page 10: Mobile automation uamobile
Page 11: Mobile automation uamobile

• Скорость

• Дизайн

• Возможности платформы

• Кроссплатформенность

Page 12: Mobile automation uamobile

Автоматизация

UI

API

Integration

Unit

Page 13: Mobile automation uamobile

Какие бывают роботы?

Page 14: Mobile automation uamobile

Multiplatform tools

Native tools UI Automation, iPhone

WebDriver, NativeDriver, Frank, TAF, KIF, calabash

Android WebDriver, NativeDriver, Robotium,

calabash

Record’n’play

Инструменты

Page 15: Mobile automation uamobile

Дорого и ненадежно

Page 16: Mobile automation uamobile

Device Anywhere

Page 17: Mobile automation uamobile
Page 18: Mobile automation uamobile

Бесплатно и ненадежно

@Test public void testFindInROI() throws Exception { JButtons frame = new JButtons(); Screen scr = new Screen();

Match m = scr.wait("test-res/network.png", 10);

scr.setRect(new Rectangle(m.x-9, m.y-10, m.w+10, m.h+11));

Match m2 = scr.doFind("test-res/network.png");

assertEquals(m, m2); frame.dispose(); }

https://github.com/sikuli/sikuli

Page 19: Mobile automation uamobile

Не очень дорого но и не нужно

M-eux

Page 20: Mobile automation uamobile
Page 21: Mobile automation uamobile

Бесплатно но могло быть и лучше

Page 22: Mobile automation uamobile

Keep It Functional

@implementation KIFTestScenario (EXAdditions) + (id)scenarioToLogIn; { KIFTestScenario *scenario = [KIFTestScenario scenarioWithDescription:@"Test that a user can successfully log in."]; [scenario addStep:[KIFTestStep stepToReset]]; [scenario addStepsFromArray:[KIFTestStep stepsToGoToLoginPage]]; [scenario addStep:[KIFTestStep stepToEnterText:@"[email protected]" intoViewWithAccessibilityLabel:@"Login User Name"]]; [scenario addStep:[KIFTestStep stepToTapViewWithAccessibilityLabel:@"Log In"]]; // Verify that the login succeeded [scenario addStep:[KIFTestStep stepToWaitForTappableViewWithAccessibilityLabel:@"Welcome"]]; return scenario; } @end

https://github.com/square/KIF

Page 23: Mobile automation uamobile

UI Automation

Page 24: Mobile automation uamobile

Код UI Automation

// create a new account table.cells().firstWithName("twitter").tap(); mainWindow = app.mainWindow(); table = mainWindow.tableViews()[0]; userName = table.cells().firstWithName("user name"); userName.textFields()[0].setValue("mrfoobar"); finish = table.cells().firstWithName("finish"); finish.tap();

Page 25: Mobile automation uamobile

https://github.com/alexvollmer/tuneup_js

test("my test", function(target, app) { {

mainWindow = app.mainWindow(); tableViews = mainWindow.tableViews(); assertEquals(1, tableViews.length); table = tableViews[0]; assertEquals("First Name", table.groups()[0].staticTexts()[0].name()); assertEquals("Last Name", table.groups()[1].staticTexts()[0].name()); assertEquals("Fred", table.cells()[0].name()); assertEquals("Flintstone", table.cells()[1].name());

}

Page 26: Mobile automation uamobile

Jasmine

describe("Hello World App", function() {{ var target = UIATarget.localTarget(); function getLabel() { { return target.frontMostApp(). mainWindow().staticTexts()[0].value(); } it("should display \"Hello World !\" in the label after pressing the \"Click Me :)\" button", function() { target.frontMostApp(). mainWindow().buttons()["Click Me :)"].tap(); expect(getLabel()).toEqual("Hello World !"); });

});

Page 28: Mobile automation uamobile

iOS Native Driver Java Test

public void testNativeDriver() throws Exception { WebDriver driver = new IosNativeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // Type user name WebElement userName = driver.findElement(By.placeholder("User Name")); userName.clear(); userName.sendKeys("NativeDriver");

}

http://code.google.com/p/nativedriver

Page 30: Mobile automation uamobile

EPAM-Mobile-TAF

https://github.com/EPAM-Systems/EPAM-Mobile-TAF

Page 31: Mobile automation uamobile

TAF Java Code

@BeforeClass public static void beforeAll() { logger = TAFLoggerFactory. getLogger(ProjectExampleSmokeTestSet.class); setUpAllTests(); } @Test(timeout = test_timeout) @TestFixture(username=test_desktop_user, password=test_desktop_pass) public void isAuthenticateLogin() {

expecteds = AppModel.HomeScreen.getScreenModel(); actuals = ScreenFactory.getInstance().getLoginScreen(). login(username, password).getScreenModel(); Assert.assertArrayEquals(expecteds, actuals);

}

Page 32: Mobile automation uamobile

Behavior Driven

Feature: Various scenarios that exercise different parts of Frank Scenario: Scrolling to the bottom of the table Given I launch the app When I touch "Larry Stooge" And I touch "User Roles" Then I should not see "Returns" When I scroll to the bottom of the table Then I should see "Returns"

Page 33: Mobile automation uamobile

Step Definition

When /^I touch the "([^\"]*)" nav bar button$/ do |mark|

touch( "navigationButton marked:'#{mark}'" )

end

Page 35: Mobile automation uamobile

BDD is Behavior Driven not Test Steps Driven

Page 36: Mobile automation uamobile

Jenkins

https://wiki.jenkins-ci.org/display/JENKINS/iOS+Device+Connector+Plugin

Page 37: Mobile automation uamobile
Page 38: Mobile automation uamobile

Android Testing

http://developer.android.com/tools/testing/testing_android.html

Page 39: Mobile automation uamobile

Using Android SDK

Нажатия на View

• TouchUtils.tapView(view)

Нажатия на кнопки

• getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_MENU)

Ввод текста

• sendKey(“some text”)

Page 40: Mobile automation uamobile

Activity Test

@UiThreadTest public void testAdd() {

MainActivity main = (MainActivity) getActivity(); EditText val1Edit = (EditText) main.findViewById(R.id.EditText1); val1Edit.setText("3"); EditText val2Edit = (EditText) main.findViewById(R.id.EditText2); val2Edit.setText("4"); Button addButton = (Button) main.findViewById(R.id.ButtonAdd); addButton.performClick(); TextView resultText = (TextView) main.findViewById(R.id.Result); assertEquals("Result incorrect", resultText.getText(), "7");

}

Page 41: Mobile automation uamobile

В чем проблема?

Нужно знать структуру кода приложения

Очень часто приходится добавлять Thread.sleep(3000)

Большие приложения автоматизировать очень сложно

Тесты выполняются очень долго

Page 42: Mobile automation uamobile

Robotium API

getCurrentActivity()

clickOnButton(String regex)

clickInList(int line)

enterText(int index, String text)

searchText(String regex)

waitForText(), waitForActivity(), waitForView()

clickOnMenuItem(String text)

goBack(), goBackToActivity(String name)

Page 43: Mobile automation uamobile

Robotium

public void testPreferenceIsSaved() throws Exception { solo.sendKey(Solo.MENU); solo.clickOnText("Preferences"); solo.clickOnText("Edit File Extensions"); Assert.assertTrue(solo.searchText("rtf")); solo.clickOnText("txt"); solo.clearEditText(2); solo.enterText(2, "robotium"); solo.clickOnButton("Save"); solo.goBack(); solo.clickOnText("Edit File Extensions"); Assert.assertTrue(solo.searchText("application/robotium")); }

http://code.google.com/p/robotium/

Page 44: Mobile automation uamobile

Robotium with WebView

private ExtSolo solo; public void setUp() throws Exception {

super.setUp(); solo = new ExtSolo(getInstrumentation(), getActivity(), this.getClass().getCanonicalName(), getName());

} public void test() {

solo.clickOnHtmlElement(“userName”); solo.enterTextIntoHtmlElement(“User”, ”userName”); solo.htmlGoBack();

} http://docs.testdroid.com/_pages/extsolo.html

Page 45: Mobile automation uamobile

Robotium выводы

Автоматические ожидания

Автоматический поиск View

Автоматическое переключение на Activity

Сам принимает решения, например scroll

jUnit 3

Работает только с однопроцессными

приложениями

Требует базовое Activity для работы

Page 46: Mobile automation uamobile

Запуск тестов in Parallel или in Cloud

http://testdroid.com/product/testdroid-server

http://testdroid.com/product/testdroid-cloud

Page 47: Mobile automation uamobile

Jenkins

https://wiki.jenkins-ci.org/display/JENKINS/Building+an+Android+app+and+test+project

https://wiki.jenkins-ci.org/display/JENKINS/Android+Emulator+Plugin

Page 49: Mobile automation uamobile

Android Native Driver Java Test private AndroidNativeDriver driver; @Override protected void setUp() { driver = getDriver(); } @Override protected void tearDown() { driver.quit(); } protected AndroidNativeDriver getDriver() { return new AndroidNativeDriverBuilder().withDefaultServer().build(); } private void startListViewActivity() { driver.startActivity("com.google.android.testing.nativedriver." + "simplelayouts.ListViewActivity"); } public void testClickListItems_scrollsGradually() { startListViewActivity(); for (String state : states) { driver.findElement(AndroidNativeBy.text(state)).click(); }}

http://code.google.com/p/nativedriver https://github.com/alfredz/android-nativedriver

Page 50: Mobile automation uamobile

ANDROID UI API

UiScrollable settingsItem = new UiScrollable(new UiSelector() .className("android.widget.ListView"));

UiObject about = settingsItem.getChildByText(new UiSelector() .className("android.widget.LinearLayout"), "About tablet");

about.click()

http://developer.android.com/tools/help/uiautomator/index.html

http://developer.android.com/tools/testing/testing_ui.html

Page 51: Mobile automation uamobile

Monkey Runner Python device = MonkeyRunner.waitForConnection() package = 'com.example.android.notepad' device.wake() device.shell("am start -a android.intent.action.INSERT -t vnd.android.cursor.dir/contact -e name 'Vasya Pupkin' -e phone 555-1111") device.startActivity(component="com.android.contacts/.TwelveKeyDialer") device.installPackage('d:\\NotePadTraining.apk') device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP) device.type("asdsadsad")

http://developer.android.com/tools/help/monkeyrunner_concepts.html

Page 52: Mobile automation uamobile

Monkey Runner Extension

def testViewFactory_TextView(self):

attrs = {'class': 'android.widget.EditText', 'text:mText': 'Button with ID'}

view = View.factory(attrs, None, -1) self.assertTrue(isinstance(view, EditText))

https://github.com/dtmilano/AndroidViewClient

Page 53: Mobile automation uamobile

Other Android Tools

http://developer.android.com/tools/help/monkey.html

https://github.com/calabash/calabash-android

https://github.com/eing/moet

http://www.ranorex.com/mobile-automation-testing/android-test-automation.html

https://github.com/kaeppler/calculon

https://github.com/pivotal/robolectric

https://www.lesspainful.com/

Page 54: Mobile automation uamobile

Demo

Page 55: Mobile automation uamobile

For Web Applications

Page 56: Mobile automation uamobile

Selenium WebDriver

public void testGoogle() throws Exception { WebDriver driver =

new AndroidDriver() or IPhoneDriver();

driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); driver.quit(); }

Page 57: Mobile automation uamobile

Сегодня узнали

Какие есть инструменты для UI автоматизации тестирования:

• iOS приложений

• Android приложений

Какие стоит использовать, а какие нет

Page 58: Mobile automation uamobile

@adzynia

http://adzynia.com

[email protected]