mobile automation uamobile

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

Upload: ua-mobile

Post on 15-May-2015

1.934 views

Category:

Technology


0 download

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]