Skip to content

Commit 91623db

Browse files
authored
chore: fix flaky tests (#452)
- Update timeouts - Fix values for app size (for 6.3 we include new css parser in modules and new ios webkit also add ~2%) - Get host os screenshot on test fail - Log trace on some tests to debug flakyness - Minor refactoring - Fix Travis CI
1 parent d5e0bd8 commit 91623db

File tree

12 files changed

+67
-38
lines changed

12 files changed

+67
-38
lines changed

Diff for: .travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ language: python
66
python:
77
- "2.7"
88
before_install:
9+
- export DISPLAY=:0
10+
- sudo apt-get install python-xlib -y
911
- pip install -U pip
1012
install:
1113
- python -m pip install --upgrade pip

Diff for: core/base_test/tns_test.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,18 @@ def kill_emulators():
108108

109109
@staticmethod
110110
def get_screenshots():
111+
# get host snapshot
112+
base_path = os.path.join(Settings.TEST_OUT_IMAGES, TestContext.CLASS_NAME, TestContext.TEST_NAME)
113+
try:
114+
import pyautogui
115+
png_path = os.path.join(base_path, 'host.png')
116+
pyautogui.screenshot().save(png_path)
117+
except Exception:
118+
Log.warning('Failed to take screenshot of host os.')
119+
120+
# get device screenshots
111121
for device in TestContext.STARTED_DEVICES:
112122
try:
113-
base_path = os.path.join(Settings.TEST_OUT_IMAGES, TestContext.CLASS_NAME, TestContext.TEST_NAME)
114123
png_path = os.path.join(base_path, device.name + '.png')
115124
File.delete(png_path)
116125
device.get_screen(png_path)

Diff for: data/sync/master_detail_vue.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from selenium.webdriver.common.by import By
77

88
from core.enums.app_type import AppType
9-
from core.enums.platform_type import Platform
109
from core.enums.os_type import OSType
10+
from core.enums.platform_type import Platform
1111
from core.settings import Settings
1212
from core.utils.appium.appium_driver import AppiumDriver
1313
from core.utils.wait import Wait
@@ -19,11 +19,15 @@
1919
from products.nativescript.tns_paths import TnsPaths
2020

2121

22-
def sync_master_detail_vue(app_name, platform, device, bundle=True, hmr=True):
22+
def sync_master_detail_vue(app_name, platform, device):
2323
# Execute tns command
24-
result = Tns.run(app_name=app_name, platform=platform, emulator=True, wait=False, bundle=bundle, hmr=hmr)
25-
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
26-
hmr=hmr, app_type=AppType.VUE, transfer_all=True)
24+
log_trace = False
25+
if platform == Platform.IOS:
26+
# Temporary add log trace on iOS to debug an issue
27+
log_trace = True
28+
result = Tns.run(app_name=app_name, platform=platform, emulator=True, log_trace=log_trace, wait=False)
29+
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, app_type=AppType.VUE,
30+
transfer_all=True)
2731
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=360)
2832

2933
# start appium driver (need it on iOS only)
@@ -38,23 +42,23 @@ def sync_master_detail_vue(app_name, platform, device, bundle=True, hmr=True):
3842
device.get_screen(path=initial_state)
3943

4044
# Verify that application is not restarted on file changes when hmr=true
41-
if hmr and Settings.HOST_OS != OSType.WINDOWS:
45+
if Settings.HOST_OS != OSType.WINDOWS:
4246
not_existing_string_list = ['Restarting application']
4347
else:
4448
not_existing_string_list = None
4549

4650
# Edit template in .vue file
4751
Sync.replace(app_name=app_name, change_set=Changes.MasterDetailVUE.VUE_TEMPLATE)
4852
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.INCREMENTAL,
49-
bundle=bundle, hmr=hmr, app_type=AppType.VUE, file_name='CarList.vue')
53+
app_type=AppType.VUE, file_name='CarList.vue')
5054
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
5155
not_existing_string_list=not_existing_string_list)
5256
device.wait_for_text(text=Changes.MasterDetailVUE.VUE_TEMPLATE.new_text)
5357

5458
# Edit styling in .vue file
5559
Sync.replace(app_name=app_name, change_set=Changes.MasterDetailVUE.VUE_STYLE)
5660
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.INCREMENTAL,
57-
bundle=bundle, hmr=hmr, app_type=AppType.VUE, file_name='CarList.vue')
61+
app_type=AppType.VUE, file_name='CarList.vue')
5862
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
5963
not_existing_string_list=not_existing_string_list)
6064
style_applied = Wait.until(lambda: device.get_pixels_by_color(Colors.LIGHT_BLUE) > 200)
@@ -63,7 +67,7 @@ def sync_master_detail_vue(app_name, platform, device, bundle=True, hmr=True):
6367
# Revert styling in .vue file
6468
Sync.revert(app_name=app_name, change_set=Changes.MasterDetailVUE.VUE_STYLE)
6569
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.INCREMENTAL,
66-
bundle=bundle, hmr=hmr, app_type=AppType.VUE, file_name='CarList.vue')
70+
app_type=AppType.VUE, file_name='CarList.vue')
6771
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
6872
not_existing_string_list=not_existing_string_list)
6973
style_applied = Wait.until(lambda: device.get_pixels_by_color(Colors.LIGHT_BLUE) < 200)
@@ -79,7 +83,7 @@ def sync_master_detail_vue(app_name, platform, device, bundle=True, hmr=True):
7983
device.wait_for_text(text="Price")
8084
Sync.replace(app_name=app_name, change_set=Changes.MasterDetailVUE.VUE_DETAIL_PAGE_TEMPLATE)
8185
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.INCREMENTAL,
82-
bundle=bundle, hmr=hmr, app_type=AppType.VUE, file_name='CarDetails.vue')
86+
app_type=AppType.VUE, file_name='CarDetails.vue')
8387
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
8488
not_existing_string_list=not_existing_string_list)
8589
device.wait_for_text(text=Changes.MasterDetailVUE.VUE_DETAIL_PAGE_TEMPLATE.new_text)

Diff for: products/nativescript/app.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def update(app_name, modules=True, angular=True, typescript=False, web_pack=True
8484

8585
if vue and App.is_dependency(app_name=app_name, dependency='nativescript-vue'):
8686
Npm.uninstall(package='nativescript-vue', option='--save', folder=app_path)
87-
Npm.install(package='nativescript-vue@next', option='--save --save-exact', folder=app_path)
87+
Npm.install(package='nativescript-vue', option='--save --save-exact', folder=app_path)
8888
# on win when `npm i` is executed with path to .tgz it saves in package.json unix style path
8989
# which cannot be resolved on win
9090
if Settings.HOST_OS == OSType.WINDOWS:

Diff for: requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ subprocess32>=3.5.3
1717
requests>=2.21.0
1818
pytz>=2018.9
1919
Appium-Python-Client>=0.28
20-
pyautogui==0.9.39
20+
pyautogui==0.9.39
21+
python-xlib==0.25

Diff for: requirements_darwin.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ subprocess32>=3.5.3
1919
requests>=2.21.0
2020
pytz>=2018.9
2121
Appium-Python-Client>=0.28
22-
pyautogui==0.9.39
22+
pyautogui==0.9.39
23+
python-xlib==0.25

Diff for: run_ns.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
if __name__ == '__main__':
99
run_common.prepare(clone_templates=True, install_ng_cli=False)
1010
Log.info("Running tests...")
11-
arguments = ['nosetests', '-v', '-s', '--nologcapture', '--with-doctest', '--with-xunit']
11+
arguments = ['nosetests', '-v', '-s', '--nologcapture', '--with-doctest', '--with-xunit', '--with-flaky']
1212
for i in sys.argv:
1313
arguments.append(str(i))
1414
nose.run(argv=arguments)

Diff for: tests/cli/build/android_app_bundle_tests.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from core.base_test.tns_run_android_test import TnsRunAndroidTest
44
from core.settings.Settings import TEST_SUT_HOME, TEST_RUN_HOME, AppName, Android
55
from core.utils.device.adb import Adb
6+
from core.utils.docker import Docker
67
from core.utils.file_utils import Folder, File
78
from core.utils.run import run
8-
from core.utils.docker import Docker
99
from data.templates import Template
1010
from products.nativescript.tns import Tns
1111
from products.nativescript.tns_logs import TnsLogs
@@ -60,9 +60,9 @@ def bundletool_build(bundletool_path, path_to_aab, path_to_apks):
6060

6161
@staticmethod
6262
def bundletool_deploy(bundletool_path, path_to_apks, device_id):
63-
deploy_command = ('java -jar {0} install-apks --apks="{1}" --device-id={2}').format(bundletool_path,
64-
path_to_apks,
65-
device_id)
63+
deploy_command = 'java -jar {0} install-apks --apks="{1}" --device-id={2}'.format(bundletool_path,
64+
path_to_apks,
65+
device_id)
6666
result = run(deploy_command)
6767
assert "Error" not in result.output, "deploy of app failed"
6868
assert "The APKs have been extracted in the directory:" in result.output, "deploy of app failed"
@@ -81,11 +81,11 @@ def test_100_run_android_app_bundle_compile_snapshot(self):
8181
uglify=True, verify=False, compile_snapshot=True)
8282
strings = ['Successfully generated snapshots',
8383
'The build result is located at: {0}'.format(path_to_aab)]
84-
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=180)
84+
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=300)
8585

8686
# Verify app can be deployed on emulator via nativescript
8787
# Verify app looks correct inside emulator
88-
self.emu.wait_for_text(text='TAP', timeout=240)
88+
self.emu.wait_for_text(text='TAP', timeout=60)
8989

9090
# Verify that the correct .so file is included in the package
9191
File.unzip(path_to_apks, os.path.join(self.app_name, 'apks'))

Diff for: tests/cli/preview/templates/hello_word_js_tests.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
22
import unittest
33

4+
from flaky import flaky
5+
46
from core.base_test.tns_run_test import TnsRunTest
57
from core.base_test.tns_test import TnsTest
68
from core.enums.app_type import AppType
@@ -15,8 +17,8 @@
1517
from data.templates import Template
1618
from products.nativescript.preview_helpers import Preview
1719
from products.nativescript.tns import Tns
18-
from products.nativescript.tns_logs import TnsLogs
1920
from products.nativescript.tns_assert import TnsAssert
21+
from products.nativescript.tns_logs import TnsLogs
2022

2123

2224
class TnsPreviewJSTests(TnsRunTest):
@@ -73,11 +75,13 @@ def test_100_preview_ios(self):
7375
preview_sync_hello_world_js_ts(app_type=AppType.JS, app_name=self.app_name,
7476
device=self.sim, click_open_alert=True)
7577

78+
@flaky(max_runs=3)
7679
def test_205_preview_android_no_hmr(self):
7780
"""Preview project on emulator with --no-hmr. Make valid changes in JS, CSS and XML"""
7881
preview_sync_hello_world_js_ts(app_type=AppType.JS, app_name=self.app_name,
7982
device=self.emu, hmr=False)
8083

84+
@flaky(max_runs=3)
8185
@unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
8286
def test_205_preview_ios_no_hmr(self):
8387
"""Preview project on simulator with --no-hmr. Make valid changes in JS, CSS and XML"""

Diff for: tests/cli/preview/templates/hello_word_ng_tests.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import os
22
import unittest
3-
from core.base_test.tns_test import TnsTest
3+
4+
from flaky import flaky
5+
46
from core.base_test.tns_run_test import TnsRunTest
7+
from core.base_test.tns_test import TnsTest
58
from core.enums.os_type import OSType
69
from core.enums.platform_type import Platform
710
from core.settings import Settings
811
from core.utils.file_utils import File, Folder
912
from data.sync.hello_world_ng import preview_sync_hello_world_ng
1013
from data.templates import Template
11-
from products.nativescript.tns import Tns
1214
from products.nativescript.preview_helpers import Preview
15+
from products.nativescript.tns import Tns
1316

1417

1518
class TnsPreviewNGTests(TnsRunTest):
@@ -65,11 +68,13 @@ def test_100_preview_ios(self):
6568
preview_sync_hello_world_ng(app_name=self.app_name, platform=Platform.IOS,
6669
device=self.sim, instrumented=True)
6770

71+
@flaky(max_runs=3)
6872
def test_205_preview_android_no_hmr(self):
6973
"""Preview project on emulator with --hmr. Make valid changes in TS, CSS and HTML"""
7074
preview_sync_hello_world_ng(app_name=self.app_name, platform=Platform.ANDROID,
7175
device=self.emu, hmr=False)
7276

77+
@flaky(max_runs=3)
7378
@unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
7479
def test_205_preview_ios_no_hmr(self):
7580
"""Preview project on simulator with --hmr. Make valid changes in TS, CSS and HTML"""

Diff for: tests/perf/app_size/test_app_size.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from core.base_test.tns_test import TnsTest
99
from core.enums.os_type import OSType
1010
from core.settings import Settings
11+
from core.utils.docker import Docker
1112
from core.utils.file_utils import File, Folder
1213
from core.utils.perf_utils import PerfUtils
1314
from core.utils.run import run
14-
from core.utils.docker import Docker
1515
from data.templates import Template
1616
from products.nativescript.tns import Tns
1717
from products.nativescript.tns_paths import TnsPaths
@@ -52,11 +52,11 @@ def tearDownClass(cls):
5252

5353
def test_001_js_app_app_resources(self):
5454
folder = os.path.join(TnsPaths.get_app_path(app_name=self.js_app), 'app')
55-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder), expected=1267420, tolerance=0.1)
55+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder), expected=1268131, tolerance=0.1)
5656

5757
def test_002_js_app_node_modules(self):
5858
folder = os.path.join(TnsPaths.get_app_path(app_name=self.js_app), 'node_modules')
59-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder), expected=54883579, tolerance=0.1)
59+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder), expected=58628036, tolerance=0.1)
6060

6161
def test_003_js_app_apk(self):
6262
# Extract APK
@@ -71,26 +71,26 @@ def test_003_js_app_apk(self):
7171
run(cmd='du -hs *', cwd=lib, wait=True, log_level=logging.INFO)
7272

7373
# Verify content of APK
74-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(lib), expected=51266016, tolerance=0.05)
74+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(lib), expected=51992248, tolerance=0.05)
7575
assert PerfUtils.is_value_in_range(actual=Folder.get_size(res), expected=796627, tolerance=0.05)
76-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_app), expected=839462, tolerance=0.05)
77-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_snapshots), expected=10621384, tolerance=0.05)
76+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_app), expected=1210914, tolerance=0.05)
77+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_snapshots), expected=16023484, tolerance=0.05)
7878

7979
# Verify final apk size
80-
assert PerfUtils.is_value_in_range(actual=File.get_size(apk), expected=24304589, tolerance=0.03)
80+
assert PerfUtils.is_value_in_range(actual=File.get_size(apk), expected=25826703, tolerance=0.03)
8181

8282
@unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
8383
def test_102_js_app_ipa(self):
8484
ipa = TnsPaths.get_ipa_path(app_name=self.js_app, release=True, for_device=True)
85-
assert PerfUtils.is_value_in_range(actual=File.get_size(ipa), expected=14030096, tolerance=0.02)
85+
assert PerfUtils.is_value_in_range(actual=File.get_size(ipa), expected=14465180, tolerance=0.02)
8686

8787
def test_100_ng_app_app_resources(self):
8888
app_folder = os.path.join(TnsPaths.get_app_path(app_name=self.ng_app), 'App_Resources')
89-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder), expected=1262116, tolerance=0.1)
89+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder), expected=1262699, tolerance=0.1)
9090

9191
def test_101_ng_app_node_modules(self):
9292
app_folder = os.path.join(TnsPaths.get_app_path(app_name=self.ng_app), 'node_modules')
93-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder), expected=206440791, tolerance=0.1)
93+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder), expected=210482662, tolerance=0.1)
9494

9595
def test_102_ng_app_apk(self):
9696
# Extract APK
@@ -102,13 +102,13 @@ def test_102_ng_app_apk(self):
102102
assets_snapshots = os.path.join(extracted_apk, 'assets', 'snapshots')
103103

104104
# No asserts for lib and res, since it is same as JS project
105-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_app), expected=1636691, tolerance=0.05)
106-
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_snapshots), expected=21822104, tolerance=0.05)
105+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_app), expected=1991318, tolerance=0.05)
106+
assert PerfUtils.is_value_in_range(actual=Folder.get_size(assets_snapshots), expected=27041144, tolerance=0.05)
107107

108108
# Verify final apk size
109-
assert PerfUtils.is_value_in_range(actual=File.get_size(apk), expected=26988067, tolerance=0.03)
109+
assert PerfUtils.is_value_in_range(actual=File.get_size(apk), expected=28482168, tolerance=0.03)
110110

111111
@unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
112112
def test_102_ng_app_ipa(self):
113113
ipa = TnsPaths.get_ipa_path(app_name=self.ng_app, release=True, for_device=True)
114-
assert PerfUtils.is_value_in_range(actual=File.get_size(ipa), expected=14238596, tolerance=0.02)
114+
assert PerfUtils.is_value_in_range(actual=File.get_size(ipa), expected=14672899, tolerance=0.02)

Diff for: tests/vue/test_vue_preview.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
22
import unittest
33

4+
from flaky import flaky
5+
46
from core.base_test.tns_run_test import TnsRunTest
57
from core.enums.os_type import OSType
68
from core.enums.platform_type import Platform
@@ -12,6 +14,7 @@
1214
from products.nativescript.tns import Tns
1315

1416

17+
@flaky(max_runs=3)
1518
class VueJSPreviewTests(TnsRunTest):
1619
app_name = Settings.AppName.DEFAULT
1720
source_project_dir = os.path.join(Settings.TEST_RUN_HOME, app_name)

0 commit comments

Comments
 (0)