Skip to content

Commit 106334c

Browse files
authored
Fix android flaky tests (appium#413)
* Fix android flaky tests * Use androidSdkVer 27 for emulator * Skip find_by_accessibility_id, find_by_uiautomator * Changed from https://github.com/ki4070ma/python-client/pull/5 * Add save_appium_log.yml * Don't run flaky tests on CI * Rename class name
1 parent b4096d2 commit 106334c

27 files changed

Lines changed: 254 additions & 229 deletions

ci-jobs/functional/run_android_test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ jobs:
44
vmImage: ${{ parameters.vmImage }}
55
variables:
66
ANDROID_SDK_VERSION: ${{ parameters.sdkVer }}
7+
CI: ${{ parameters.ci }}
78
steps:
89
- template: ./run_appium.yml
910
- script: bash ci-jobs/functional/start-emulator.sh
@@ -13,3 +14,6 @@ jobs:
1314
py.test ${{ parameters.testFiles}} ${{ parameters.pytestOpt }}
1415
displayName: Run Android functional tests
1516
- template: ./publish_test_result.yml
17+
- template: ./save_appium_log.yml
18+
parameters:
19+
name: ${{ parameters.name }}

ci-jobs/functional/run_appium.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ steps:
33
inputs:
44
versionSpec: '11.x'
55
displayName: Install Node 11.x
6-
- script: npm install -g appium --chromedriver_version='2.44'
6+
- script: npm install -g appium@beta --chromedriver_version='2.44'
77
displayName: Install appium
88
- task: UsePythonVersion@0
99
inputs:
@@ -24,5 +24,5 @@ steps:
2424
appium --version
2525
node --version
2626
displayName: Check versions
27-
- script: nohup appium --relaxed-security &
27+
- script: nohup appium --relaxed-security > appium_log.txt &
2828
displayName: Run Appium in background

ci-jobs/functional/run_ios_test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ jobs:
22
- job: ${{ parameters.name }}
33
pool:
44
vmImage: ${{ parameters.vmImage }}
5+
variables:
6+
CI: ${{ parameters.ci }}
57
steps:
68
- template: ./run_appium.yml
79
- script: |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
steps:
2+
- task: CopyFiles@2
3+
condition: succeededOrFailed()
4+
inputs:
5+
contents:
6+
'**/appium_log.txt'
7+
targetFolder: $(Build.ArtifactStagingDirectory)
8+
- task: CopyFiles@2
9+
condition: succeededOrFailed()
10+
inputs:
11+
contents:
12+
'**/test_*.png'
13+
targetFolder: $(Build.ArtifactStagingDirectory)
14+
- task: PublishBuildArtifacts@1
15+
condition: succeededOrFailed()
16+
inputs:
17+
pathToPublish: $(Build.ArtifactStagingDirectory)
18+
artifactName: ${{ parameters.name }}

ci-jobs/functional_test.yml

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,87 @@
11
parameters:
22
vmImage: 'macOS-10.14'
33
pytestOpt: '--doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html'
4+
androidSdkVer: 28
5+
CI: true
6+
7+
# [Android] Need to fix and add flaky tests for activities_tests, find_by_uiautomator_tests
48

59
jobs:
610
- template: ./functional/run_ios_test.yml
711
parameters:
812
name: 'func_test_ios1'
913
vmImage: ${{ parameters.vmImage }}
1014
pytestOpt: ${{ parameters.pytestOpt }}
11-
testFiles: 'find_*.py remote_fs_tests.py safari_tests.py'
15+
testFiles: 'find_*.py remote_fs_tests.py safari_tests.py execute_driver_tests.py'
16+
CI: ${{ parameters.ci }}
1217
- template: ./functional/run_ios_test.yml
1318
parameters:
1419
name: 'func_test_ios2'
1520
vmImage: ${{ parameters.vmImage }}
1621
pytestOpt: ${{ parameters.pytestOpt }}
1722
testFiles: 'applications_tests.py hw_actions_tests.py keyboard_tests.py screen_record_tests.py webdriver_tests.py'
23+
CI: ${{ parameters.ci }}
1824
- template: ./functional/run_android_test.yml
1925
parameters:
2026
name: 'func_test_android1'
2127
vmImage: ${{ parameters.vmImage }}
2228
pytestOpt: ${{ parameters.pytestOpt }}
23-
testFiles: 'location_tests.py'
24-
sdkVer: 28
29+
testFiles: 'device_time_tests.py find_by_accessibility_id_tests.py find_by_image_tests.py'
30+
sdkVer: ${{ parameters.androidSdkVer }}
31+
CI: ${{ parameters.ci }}
32+
- template: ./functional/run_android_test.yml
33+
parameters:
34+
name: 'func_test_android2'
35+
vmImage: ${{ parameters.vmImage }}
36+
pytestOpt: ${{ parameters.pytestOpt }}
37+
testFiles: 'ime_tests.py keyboard_tests.py location_tests.py'
38+
sdkVer: ${{ parameters.androidSdkVer }}
39+
CI: ${{ parameters.ci }}
40+
- template: ./functional/run_android_test.yml
41+
parameters:
42+
name: 'func_test_android3'
43+
vmImage: ${{ parameters.vmImage }}
44+
pytestOpt: ${{ parameters.pytestOpt }}
45+
testFiles: 'chrome_tests.py'
46+
sdkVer: ${{ parameters.androidSdkVer }}
47+
CI: ${{ parameters.ci }}
48+
- template: ./functional/run_android_test.yml
49+
parameters:
50+
name: 'func_test_android4'
51+
vmImage: ${{ parameters.vmImage }}
52+
pytestOpt: ${{ parameters.pytestOpt }}
53+
testFiles: 'finger_print_tests.py screen_record_tests.py settings_tests.py'
54+
sdkVer: ${{ parameters.androidSdkVer }}
55+
CI: ${{ parameters.ci }}
56+
- template: ./functional/run_android_test.yml
57+
parameters:
58+
name: 'func_test_android5'
59+
vmImage: ${{ parameters.vmImage }}
60+
pytestOpt: ${{ parameters.pytestOpt }}
61+
testFiles: 'context_switching_tests.py remote_fs_tests.py'
62+
sdkVer: ${{ parameters.androidSdkVer }}
63+
CI: ${{ parameters.ci }}
64+
- template: ./functional/run_android_test.yml
65+
parameters:
66+
name: 'func_test_android6'
67+
vmImage: ${{ parameters.vmImage }}
68+
pytestOpt: ${{ parameters.pytestOpt }}
69+
testFiles: 'webdriver_tests.py'
70+
sdkVer: ${{ parameters.androidSdkVer }}
71+
CI: ${{ parameters.ci }}
72+
- template: ./functional/run_android_test.yml
73+
parameters:
74+
name: 'func_test_android7'
75+
vmImage: ${{ parameters.vmImage }}
76+
pytestOpt: ${{ parameters.pytestOpt }}
77+
testFiles: 'applications_tests.py'
78+
sdkVer: ${{ parameters.androidSdkVer }}
79+
CI: ${{ parameters.ci }}
80+
- template: ./functional/run_android_test.yml
81+
parameters:
82+
name: 'func_test_android8'
83+
vmImage: ${{ parameters.vmImage }}
84+
pytestOpt: ${{ parameters.pytestOpt }}
85+
testFiles: 'network_connection_tests.py'
86+
sdkVer: ${{ parameters.androidSdkVer }}
87+
CI: ${{ parameters.ci }}

test/functional/android/activities_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
from appium import webdriver
1919

2020
from .helper import desired_capabilities
21+
from .helper.test_helper import BaseTestCase
2122

2223

23-
class ActivitiesTests(unittest.TestCase):
24+
class ActivitiesTests(BaseTestCase):
2425
def setUp(self):
2526
desired_caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk')
2627
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

test/functional/android/applications_tests.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@
1616
import unittest
1717
from time import sleep
1818

19-
from appium import webdriver
2019
from appium.webdriver.applicationstate import ApplicationState
2120

22-
from .helper import desired_capabilities
21+
from .helper.test_helper import BaseTestCase
2322

2423

25-
class ApplicationsTests(unittest.TestCase):
26-
def setUp(self):
27-
desired_caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk')
28-
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
29-
30-
def tearDown(self):
31-
self.driver.quit()
24+
class ApplicationsTests(BaseTestCase):
3225

3326
def test_background_app(self):
3427
self.driver.background_app(1)

test/functional/android/chrome_tests.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ def setUp(self):
2323
'platformName': 'Android',
2424
'platformVersion': '9',
2525
'deviceName': 'Android Emulator',
26-
'browserName': 'Chrome'
26+
'browserName': 'Chrome',
27+
'uiautomator2ServerInstallTimeout': 120000,
28+
'adbExecTimeout': 120000
2729
}
2830
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
2931

test/functional/android/device_time_tests.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,10 @@
1717

1818
from dateutil.parser import parse
1919

20-
from appium import webdriver
20+
from .helper.test_helper import BaseTestCase
2121

22-
from .helper import desired_capabilities
23-
24-
25-
class DeviceTimeTests(unittest.TestCase):
26-
def setUp(self):
27-
desired_caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk')
28-
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
29-
30-
def tearDown(self):
31-
self.driver.quit()
3222

23+
class DeviceTimeTests(BaseTestCase):
3324
def test_device_time(self):
3425
date_time = self.driver.device_time
3526
# convert to date ought to work

test/functional/android/find_by_accessibility_id_tests.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,36 @@
1414

1515
import unittest
1616

17-
from appium import webdriver
17+
from appium.webdriver.common.mobileby import MobileBy
1818

19-
from .helper import desired_capabilities
19+
from .helper.test_helper import BaseTestCase, is_ci, wait_for_element
2020

2121

22-
class FindByAccessibilityIDTests(unittest.TestCase):
23-
def setUp(self):
24-
desired_caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk')
25-
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
26-
27-
def tearDown(self):
28-
self.driver.quit()
29-
22+
class FindByAccessibilityIDTests(BaseTestCase):
3023
def test_find_single_element(self):
31-
self.driver.find_element_by_android_uiautomator('new UiSelector().text("Accessibility")').click()
32-
self.driver.find_element_by_android_uiautomator('new UiSelector().text("Accessibility Node Querying")').click()
33-
el = self.driver.find_element_by_accessibility_id('Task Take out Trash')
24+
wait_for_element(self.driver, MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Accessibility")').click()
25+
wait_for_element(self.driver, MobileBy.ANDROID_UIAUTOMATOR,
26+
'new UiSelector().text("Accessibility Node Querying")').click()
27+
el = wait_for_element(self.driver, MobileBy.ACCESSIBILITY_ID, 'Task Take out Trash')
3428
self.assertIsNotNone(el)
3529

3630
def test_find_multiple_elements(self):
3731
els = self.driver.find_elements_by_accessibility_id('Accessibility')
3832
self.assertIsInstance(els, list)
3933

4034
def test_element_find_single_element(self):
41-
self.driver.find_element_by_android_uiautomator('new UiSelector().text("Accessibility")').click()
42-
self.driver.find_element_by_android_uiautomator('new UiSelector().text("Accessibility Node Querying")').click()
43-
el = self.driver.find_element_by_class_name('android.widget.ListView')
35+
if is_ci():
36+
self.skipTest('Need to fix flaky test during running on CI')
37+
wait_for_element(self.driver, MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Accessibility")').click()
38+
wait_for_element(self.driver, MobileBy.ANDROID_UIAUTOMATOR,
39+
'new UiSelector().text("Accessibility Node Querying")').click()
40+
el = wait_for_element(self.driver, MobileBy.CLASS_NAME, 'android.widget.ListView')
4441

4542
sub_el = el.find_element_by_accessibility_id('Task Take out Trash')
4643
self.assertIsNotNone(sub_el)
4744

4845
def test_element_find_multiple_elements(self):
46+
wait_for_element(self.driver, MobileBy.CLASS_NAME, 'android.widget.ListView')
4947
el = self.driver.find_element_by_class_name('android.widget.ListView')
5048

5149
sub_els = el.find_elements_by_accessibility_id('Animation')

0 commit comments

Comments
 (0)