You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Add more tests
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "ErrorTest",
|
||||
"publisher": "MicroPythonOS",
|
||||
"short_description": "Test app with intentional error",
|
||||
"long_description": "This app has an intentional import error for testing.",
|
||||
"icon_url": "https://apps.micropythonos.com/apps/com.micropythonos.errortest/icons/com.micropythonos.errortest_0.0.1_64x64.png",
|
||||
"download_url": "https://apps.micropythonos.com/apps/com.micropythonos.errortest/mpks/com.micropythonos.errortest_0.0.1.mpk",
|
||||
"fullname": "com.micropythonos.errortest",
|
||||
"version": "0.0.1",
|
||||
"category": "development",
|
||||
"activities": [
|
||||
{
|
||||
"entrypoint": "assets/error.py",
|
||||
"classname": "Error",
|
||||
"intent_filters": [
|
||||
{
|
||||
"action": "main",
|
||||
"category": "launcher"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from mpos.apps import ActivityDoesntExist # should fail here
|
||||
|
||||
class Error(Activity):
|
||||
|
||||
def onCreate(self):
|
||||
screen = lv.obj()
|
||||
label = lv.label(screen)
|
||||
label.set_text('Hello World!')
|
||||
label.center()
|
||||
self.setContentView(screen)
|
||||
@@ -20,7 +20,8 @@ rm "$outputjson"
|
||||
# com.micropythonos.confetti crashes when closing
|
||||
# com.micropythonos.showfonts is slow to open
|
||||
# com.micropythonos.draw isnt very useful
|
||||
blacklist="com.micropythonos.filemanager com.quasikili.quasidoodle com.micropythonos.confetti com.micropythonos.showfonts com.micropythonos.draw"
|
||||
# com.micropythonos.errortest is an intentional bad app for testing (caught by tests/test_graphical_launch_all_apps.py)
|
||||
blacklist="com.micropythonos.filemanager com.quasikili.quasidoodle com.micropythonos.confetti com.micropythonos.showfonts com.micropythonos.draw com.micropythonos.errortest"
|
||||
|
||||
echo "[" | tee -a "$outputjson"
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
"""
|
||||
Test that launches all installed apps to check for startup errors.
|
||||
|
||||
This test discovers all apps in apps/ and builtin/apps/ directories,
|
||||
launches each one, and checks for exceptions during startup.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
# This is a graphical test - needs boot and main to run first
|
||||
# Add tests directory to path for helpers
|
||||
if '../tests' not in sys.path:
|
||||
sys.path.insert(0, '../tests')
|
||||
|
||||
from graphical_test_helper import wait_for_render
|
||||
import mpos.apps
|
||||
import mpos.ui
|
||||
from mpos.content.package_manager import PackageManager
|
||||
|
||||
|
||||
class TestLaunchAllApps(unittest.TestCase):
|
||||
"""Test launching all installed apps."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures."""
|
||||
self.apps_to_test = []
|
||||
self.app_errors = {}
|
||||
|
||||
# Discover all apps
|
||||
self._discover_apps()
|
||||
|
||||
def _discover_apps(self):
|
||||
"""Discover all installed apps."""
|
||||
# Use PackageManager to get all apps
|
||||
all_packages = PackageManager.get_app_list()
|
||||
|
||||
for package in all_packages:
|
||||
# Get the main activity for each app
|
||||
if package.activities:
|
||||
# Use first activity as the main one (activities are dicts)
|
||||
main_activity = package.activities[0]
|
||||
self.apps_to_test.append({
|
||||
'package_name': package.fullname,
|
||||
'activity_name': main_activity.get('classname', 'MainActivity'),
|
||||
'label': package.name
|
||||
})
|
||||
|
||||
def test_launch_all_apps(self):
|
||||
"""Launch each app and check for errors."""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Testing {len(self.apps_to_test)} apps for startup errors")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
failed_apps = []
|
||||
passed_apps = []
|
||||
|
||||
for i, app_info in enumerate(self.apps_to_test, 1):
|
||||
package_name = app_info['package_name']
|
||||
activity_name = app_info['activity_name']
|
||||
label = app_info['label']
|
||||
|
||||
print(f"\n[{i}/{len(self.apps_to_test)}] Testing: {label} ({package_name})")
|
||||
|
||||
error_found = False
|
||||
error_message = ""
|
||||
|
||||
try:
|
||||
# Launch the app by package name
|
||||
result = mpos.apps.start_app(package_name)
|
||||
|
||||
# Wait for UI to render
|
||||
wait_for_render(iterations=5)
|
||||
|
||||
# Check if start_app returned False (indicates error during execution)
|
||||
if result is False:
|
||||
error_found = True
|
||||
error_message = "App failed to start (execute_script returned False)"
|
||||
print(f" ❌ FAILED - App failed to start")
|
||||
print(f" {error_message}")
|
||||
failed_apps.append({
|
||||
'info': app_info,
|
||||
'error': error_message
|
||||
})
|
||||
else:
|
||||
# If we got here without error, the app loaded successfully
|
||||
print(f" ✓ PASSED - App loaded successfully")
|
||||
passed_apps.append(app_info)
|
||||
|
||||
# Navigate back to exit the app
|
||||
mpos.ui.back_screen()
|
||||
wait_for_render(iterations=3)
|
||||
|
||||
except Exception as e:
|
||||
error_found = True
|
||||
error_message = f"{type(e).__name__}: {str(e)}"
|
||||
print(f" ❌ FAILED - Exception during launch")
|
||||
print(f" {error_message}")
|
||||
failed_apps.append({
|
||||
'info': app_info,
|
||||
'error': error_message
|
||||
})
|
||||
|
||||
# Print summary
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Test Summary")
|
||||
print(f"{'='*60}")
|
||||
print(f"Total apps tested: {len(self.apps_to_test)}")
|
||||
print(f"Passed: {len(passed_apps)}")
|
||||
print(f"Failed: {len(failed_apps)}")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
if failed_apps:
|
||||
print("Failed apps:")
|
||||
for fail in failed_apps:
|
||||
print(f" - {fail['info']['label']} ({fail['info']['package_name']})")
|
||||
print(f" Error: {fail['error']}")
|
||||
print()
|
||||
|
||||
# Test should detect at least one error (the intentional errortest app)
|
||||
if len(failed_apps) > 0:
|
||||
print(f"✓ Test successfully detected {len(failed_apps)} app(s) with errors")
|
||||
|
||||
# Check if we found the errortest app
|
||||
errortest_found = any(
|
||||
'errortest' in fail['info']['package_name'].lower()
|
||||
for fail in failed_apps
|
||||
)
|
||||
|
||||
if errortest_found:
|
||||
print("✓ Successfully detected the intentional error in errortest app")
|
||||
|
||||
# Verify errortest was found
|
||||
all_app_names = [app['package_name'] for app in self.apps_to_test]
|
||||
has_errortest = any('errortest' in name.lower() for name in all_app_names)
|
||||
|
||||
if has_errortest:
|
||||
self.assertTrue(errortest_found,
|
||||
"Failed to detect error in com.micropythonos.errortest app")
|
||||
else:
|
||||
print("⚠ Warning: No errors detected. All apps launched successfully.")
|
||||
|
||||
|
||||
class TestLaunchSpecificApps(unittest.TestCase):
|
||||
"""Test specific apps individually for more detailed error reporting."""
|
||||
|
||||
def _launch_and_check_app(self, package_name, expected_error=False):
|
||||
"""
|
||||
Launch an app and check for errors.
|
||||
|
||||
Args:
|
||||
package_name: Full package name (e.g., 'com.micropythonos.camera')
|
||||
expected_error: Whether this app is expected to have errors
|
||||
|
||||
Returns:
|
||||
tuple: (success, error_message)
|
||||
"""
|
||||
error_found = False
|
||||
error_message = ""
|
||||
|
||||
try:
|
||||
# Launch the app by package name
|
||||
result = mpos.apps.start_app(package_name)
|
||||
wait_for_render(iterations=5)
|
||||
|
||||
# Check if start_app returned False (indicates error)
|
||||
if result is False:
|
||||
error_found = True
|
||||
error_message = "App failed to start (execute_script returned False)"
|
||||
|
||||
# Navigate back
|
||||
mpos.ui.back_screen()
|
||||
wait_for_render(iterations=3)
|
||||
|
||||
except Exception as e:
|
||||
error_found = True
|
||||
error_message = f"{type(e).__name__}: {str(e)}"
|
||||
|
||||
if expected_error:
|
||||
# For apps expected to have errors
|
||||
return (error_found, error_message)
|
||||
else:
|
||||
# For apps that should work
|
||||
return (not error_found, error_message)
|
||||
|
||||
def test_errortest_app_has_error(self):
|
||||
"""Test that the errortest app properly reports an error."""
|
||||
success, error_msg = self._launch_and_check_app(
|
||||
'com.micropythonos.errortest',
|
||||
expected_error=True
|
||||
)
|
||||
|
||||
if success:
|
||||
print(f"\n✓ Successfully detected error in errortest app:")
|
||||
print(f" {error_msg}")
|
||||
else:
|
||||
print(f"\n❌ Failed to detect error in errortest app")
|
||||
|
||||
self.assertTrue(success,
|
||||
"The errortest app should have an error but none was detected")
|
||||
|
||||
def test_launcher_app_loads(self):
|
||||
"""Test that the launcher app loads without errors."""
|
||||
success, error_msg = self._launch_and_check_app(
|
||||
'com.micropythonos.launcher',
|
||||
expected_error=False
|
||||
)
|
||||
|
||||
if not success:
|
||||
print(f"\n❌ Launcher app has errors: {error_msg}")
|
||||
|
||||
self.assertTrue(success,
|
||||
f"Launcher app should load without errors: {error_msg}")
|
||||
|
||||
def test_about_app_loads(self):
|
||||
"""Test that the About app loads without errors."""
|
||||
success, error_msg = self._launch_and_check_app(
|
||||
'com.micropythonos.about',
|
||||
expected_error=False
|
||||
)
|
||||
|
||||
if not success:
|
||||
print(f"\n❌ About app has errors: {error_msg}")
|
||||
|
||||
self.assertTrue(success,
|
||||
f"About app should load without errors: {error_msg}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user