diff --git a/CLAUDE.md b/CLAUDE.md index fc68a469..0ea50a5e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ Tests are in the `tests/` directory. There are two types: unit tests and manual ./tests/unittest.sh tests/test_shared_preferences.py ./tests/unittest.sh tests/test_intent.py ./tests/unittest.sh tests/test_package_manager.py -./tests/unittest.sh tests/test_start_app.py +./tests/unittest.sh tests/test_graphical_start_app.py # Run a specific test on connected device (via mpremote) ./tests/unittest.sh tests/test_shared_preferences.py --ondevice @@ -196,7 +196,7 @@ The `unittest.sh` script: - `test_shared_preferences.py`: Tests for `mpos.config.SharedPreferences` (configuration storage) - `test_intent.py`: Tests for `mpos.content.intent.Intent` (intent creation, extras, flags) - `test_package_manager.py`: Tests for `PackageManager` (version comparison, app discovery) -- `test_start_app.py`: Tests for app launching (requires SDL display initialization) +- `test_graphical_start_app.py`: Tests for app launching (graphical test with proper boot/main initialization) - `test_graphical_about_app.py`: Graphical test that verifies About app UI and captures screenshots **Graphical tests** (UI verification with screenshots): diff --git a/tests/test_graphical_start_app.py b/tests/test_graphical_start_app.py new file mode 100644 index 00000000..8d7c088e --- /dev/null +++ b/tests/test_graphical_start_app.py @@ -0,0 +1,71 @@ +""" +Test for app launching functionality. + +This test verifies that the app starting system works correctly, +including launching existing apps and handling non-existent apps. + +Works on both desktop and ESP32 by using the standard boot/main +initialization pattern. + +Usage: + Desktop: ./tests/unittest.sh tests/test_graphical_start_app.py + Device: ./tests/unittest.sh tests/test_graphical_start_app.py --ondevice +""" + +import unittest +import mpos.apps +import mpos.ui +from graphical_test_helper import wait_for_render + + +class TestStartApp(unittest.TestCase): + """Test suite for app launching functionality.""" + + def setUp(self): + """Set up test fixtures before each test method.""" + print("\n=== Test Setup ===") + # No custom initialization needed - boot.py/main.py already ran + + def tearDown(self): + """Clean up after each test method.""" + # Navigate back to launcher to close any opened apps + try: + mpos.ui.back_screen() + wait_for_render(5) # Allow navigation to complete + except: + pass # Already on launcher or error + + print("=== Test Cleanup Complete ===\n") + + def test_normal(self): + """Test that launching an existing app succeeds.""" + print("Testing normal app launch...") + + result = mpos.apps.start_app("com.micropythonos.launcher") + wait_for_render(10) # Wait for app to load + + self.assertTrue(result, "com.micropythonos.launcher should start") + print("Normal app launch successful") + + def test_nonexistent(self): + """Test that launching a non-existent app fails gracefully.""" + print("Testing non-existent app launch...") + + result = mpos.apps.start_app("com.micropythonos.nonexistent") + + self.assertFalse(result, "com.micropythonos.nonexistent should not start") + print("Non-existent app handled correctly") + + def test_restart_launcher(self): + """Test that restarting the launcher succeeds.""" + print("Testing launcher restart...") + + result = mpos.apps.restart_launcher() + wait_for_render(10) # Wait for launcher to load + + self.assertTrue(result, "restart_launcher() should succeed") + print("Launcher restart successful") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_start_app.py b/tests/test_start_app.py deleted file mode 100644 index ce6c060a..00000000 --- a/tests/test_start_app.py +++ /dev/null @@ -1,37 +0,0 @@ -import unittest - -import sdl_display -import lcd_bus -import lvgl as lv -import mpos.ui -import task_handler -import mpos.apps -import mpos.ui.topmenu -import mpos.config -from mpos.ui.display import init_rootscreen - -class TestStartApp(unittest.TestCase): - - def __init__(self): - - TFT_HOR_RES=320 - TFT_VER_RES=240 - - bus = lcd_bus.SDLBus(flags=0) - buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) - mpos.ui.main_display = sdl_display.SDLDisplay(data_bus=bus,display_width=TFT_HOR_RES,display_height=TFT_VER_RES,frame_buffer1=buf1,color_space=lv.COLOR_FORMAT.RGB565) - mpos.ui.main_display.init() - init_rootscreen() - mpos.ui.topmenu.create_notification_bar() - mpos.ui.topmenu.create_drawer(mpos.ui.main_display) - mpos.ui.task_handler = task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop (less results in lower framerate) - - - def test_normal(self): - self.assertTrue(mpos.apps.start_app("com.micropythonos.launcher"), "com.micropythonos.launcher should start") - - def test_nonexistent(self): - self.assertFalse(mpos.apps.start_app("com.micropythonos.nonexistent"), "com.micropythonos.nonexistent should not start") - - def test_restart_launcher(self): - self.assertTrue(mpos.apps.restart_launcher(), "restart_launcher() should succeed") diff --git a/tests/unittest.sh b/tests/unittest.sh index f382ae64..42ea9583 100755 --- a/tests/unittest.sh +++ b/tests/unittest.sh @@ -10,12 +10,16 @@ fs="$mydir"/../internal_filesystem/ ondevice="" onetest="" -for arg in "$@"; do - if [ "$arg" = "--ondevice" ]; then - ondevice="yes" - else - onetest="$arg" - fi +while [ $# -gt 0 ]; do + case "$1" in + --ondevice) + ondevice="yes" + ;; + *) + onetest="$1" + ;; + esac + shift done @@ -68,7 +72,7 @@ result = unittest.main() ; sys.exit(0 if result.wasSuccessful() else 1) " fi result=$? else - # Device execution + echo "Device execution" # NOTE: On device, the OS is already running with boot.py and main.py executed, # so we don't need to (and shouldn't) re-run them. The system is already initialized. cleanname=$(echo "$file" | sed "s#/#_#g") @@ -103,6 +107,7 @@ else: } failed=0 +ran=0 if [ -z "$onetest" ]; then echo "Usage: $0 [one_test_to_run.py] [--ondevice]" @@ -120,19 +125,22 @@ if [ -z "$onetest" ]; then echo "\n\n\nWARNING: test $file got error $result !!!\n\n\n" failed=$(expr $failed \+ 1) exit 1 + else + ran=$(expr $ran \+ 1) fi done < <( find "$testdir" -iname "test_*.py" ) else + echo "doing $onetest" one_test $(readlink -f "$onetest") [ $? -ne 0 ] && failed=1 fi if [ $failed -ne 0 ]; then - echo "ERROR: $failed .py files have failing unit tests" + echo "ERROR: $failed of the $ran tests failed" exit 1 else - echo "GOOD: no .py files have failing unit tests" + echo "GOOD: none of the $ran tests failed" exit 0 fi