From 96353b8c47684b3a2229c9f4c5238166f74e4d64 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 6 Mar 2024 13:03:34 -0500 Subject: [PATCH] Add helper decorators, spread out tests into more discrete units --- tests/cli/test_cli_about.py | 6 +-- tests/cli/test_cli_cache.py | 24 ++++----- tests/cli/test_cli_config.py | 33 ++++++------ tests/cli/test_cli_current.py | 21 ++++---- tests/cli/test_cli_install.py | 96 +++++++++++++++++++---------------- tests/cli/test_cli_query.py | 28 +++++----- tests/cli/test_cli_update.py | 79 ++++++++++++++-------------- tests/helpers.py | 43 +++++++++++++++- tests/test_backend.py | 30 +++++------ 9 files changed, 204 insertions(+), 156 deletions(-) diff --git a/tests/cli/test_cli_about.py b/tests/cli/test_cli_about.py index 6e6e7a1..e3c94eb 100644 --- a/tests/cli/test_cli_about.py +++ b/tests/cli/test_cli_about.py @@ -11,11 +11,11 @@ from circfirm.cli import cli +RUNNER = CliRunner() + def test_about() -> None: """Tests the about command.""" - runner = CliRunner() - - result = runner.invoke(cli, ["about"]) + result = RUNNER.invoke(cli, ["about"]) assert result.exit_code == 0 assert result.output == "Written by Alec Delaney, licensed under MIT License.\n" diff --git a/tests/cli/test_cli_cache.py b/tests/cli/test_cli_cache.py index 0e030ee..3f3b0d5 100644 --- a/tests/cli/test_cli_cache.py +++ b/tests/cli/test_cli_cache.py @@ -17,13 +17,13 @@ import tests.helpers from circfirm.cli import cli +RUNNER = CliRunner() + def test_cache_list() -> None: """Tests the cache list command.""" - runner = CliRunner() - # Test empty cache - result = runner.invoke(cli, ["cache", "list"]) + result = RUNNER.invoke(cli, ["cache", "list"]) assert result.exit_code == 0 assert result.output == "Versions have not been cached yet for any boards.\n" @@ -33,7 +33,7 @@ def test_cache_list() -> None: # Get full list expected response with open("tests/assets/responses/full_list.txt", encoding="utf-8") as respfile: expected_response = respfile.read() - result = runner.invoke(cli, ["cache", "list"]) + result = RUNNER.invoke(cli, ["cache", "list"]) assert result.exit_code == 0 assert result.output == expected_response @@ -42,7 +42,7 @@ def test_cache_list() -> None: "tests/assets/responses/specific_board.txt", encoding="utf-8" ) as respfile: expected_response = respfile.read() - result = runner.invoke(cli, ["cache", "list", "--board", "feather_m4_express"]) + result = RUNNER.invoke(cli, ["cache", "list", "--board", "feather_m4_express"]) assert result.exit_code == 0 assert result.output == expected_response @@ -52,7 +52,7 @@ def test_cache_list() -> None: "tests/assets/responses/specific_board.txt", encoding="utf-8" ) as respfile: expected_response = respfile.read() - result = runner.invoke(cli, ["cache", "list", "--board", fake_board]) + result = RUNNER.invoke(cli, ["cache", "list", "--board", fake_board]) assert result.exit_code == 0 assert result.output == f"No versions for board '{fake_board}' are not cached.\n" @@ -66,10 +66,9 @@ def test_cache_save() -> None: board = "feather_m4_express" version = "7.3.0" langauge = "fr" - runner = CliRunner() # Save a specific firmware (successful) - result = runner.invoke( + result = RUNNER.invoke( cli, ["cache", "save", board, version, "--language", langauge] ) assert result.exit_code == 0 @@ -78,7 +77,7 @@ def test_cache_save() -> None: shutil.rmtree(expected_path.parent.resolve()) # Save a specific firmware (unsuccessful) - result = runner.invoke( + result = RUNNER.invoke( cli, ["cache", "save", board, version, "--language", "nolanguage"] ) assert result.exit_code == 1 @@ -96,13 +95,12 @@ def test_cache_clear() -> None: board = "feather_m4_express" version = "7.1.0" langauge = "zh_Latn_pinyin" - runner = CliRunner() # Move firmware files to app directory tests.helpers.copy_firmwares() # Remove a specific firmware from the cache - result = runner.invoke( + result = RUNNER.invoke( cli, [ "cache", @@ -126,13 +124,13 @@ def test_cache_clear() -> None: assert board_folder.exists() # Remove a specific board firmware from the cache - result = runner.invoke(cli, ["cache", "clear", "--board", board]) + result = RUNNER.invoke(cli, ["cache", "clear", "--board", board]) assert result.exit_code == 0 assert result.output == "Cache cleared of specified entries!\n" assert not board_folder.exists() # Remove entire cache - result = runner.invoke(cli, ["cache", "clear"]) + result = RUNNER.invoke(cli, ["cache", "clear"]) assert result.exit_code == 0 assert result.output == "Cache cleared!\n" assert len(list(board_folder.parent.glob("*"))) == 0 diff --git a/tests/cli/test_cli_config.py b/tests/cli/test_cli_config.py index c62e662..902458a 100644 --- a/tests/cli/test_cli_config.py +++ b/tests/cli/test_cli_config.py @@ -14,6 +14,8 @@ from circfirm.cli import cli +RUNNER = CliRunner() + def get_printed_default_settings() -> None: """Get the default (template) settings as printed.""" @@ -24,58 +26,55 @@ def get_printed_default_settings() -> None: def test_config() -> None: """Tests the config view command.""" - runner = CliRunner() expected_output = get_printed_default_settings() # Test viewing all settings - result = runner.invoke(cli, ["config", "view"]) + result = RUNNER.invoke(cli, ["config", "view"]) assert result.exit_code == 0 assert result.output == expected_output # Test viewing specific setting - result = runner.invoke(cli, ["config", "view", "output.supporting.silence"]) + result = RUNNER.invoke(cli, ["config", "view", "output.supporting.silence"]) assert result.exit_code == 0 assert result.output == "false\n" # Test viewing non-existent setting - result = runner.invoke(cli, ["config", "view", "doesnotexist"]) + result = RUNNER.invoke(cli, ["config", "view", "doesnotexist"]) assert result.exit_code != 0 # Test writing a setting - runner.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) - result = runner.invoke(cli, ["config", "view", "output.supporting.silence"]) + RUNNER.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) + result = RUNNER.invoke(cli, ["config", "view", "output.supporting.silence"]) assert result.exit_code == 0 assert result.output == "true\n" - runner.invoke(cli, ["config", "edit", "output.supporting.silence", "false"]) - result = runner.invoke(cli, ["config", "view", "output.supporting.silence"]) + RUNNER.invoke(cli, ["config", "edit", "output.supporting.silence", "false"]) + result = RUNNER.invoke(cli, ["config", "view", "output.supporting.silence"]) assert result.exit_code == 0 assert result.output == "false\n" # Test writing a non-existent setting - result = runner.invoke(cli, ["config", "edit", "doesnotexist", "123"]) + result = RUNNER.invoke(cli, ["config", "edit", "doesnotexist", "123"]) assert result.exit_code != 0 # Test writing to setting tree - result = runner.invoke(cli, ["config", "edit", "output", "123"]) + result = RUNNER.invoke(cli, ["config", "edit", "output", "123"]) assert result.exit_code != 0 # Test writing bad type - runner.invoke(cli, ["config", "edit", "output.supporting.silence", "123"]) + RUNNER.invoke(cli, ["config", "edit", "output.supporting.silence", "123"]) assert result.exit_code != 0 def test_config_reset() -> None: """Tests the reseting of the config settings file.""" - runner = CliRunner() - - runner.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) - result = runner.invoke(cli, ["config", "view", "output.supporting.silence"]) + RUNNER.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) + result = RUNNER.invoke(cli, ["config", "view", "output.supporting.silence"]) assert result.exit_code == 0 assert result.output == "true\n" expected_settings = get_printed_default_settings() - result = runner.invoke(cli, ["config", "reset"]) - result = runner.invoke(cli, ["config", "view"]) + result = RUNNER.invoke(cli, ["config", "reset"]) + result = RUNNER.invoke(cli, ["config", "view"]) assert result.exit_code == 0 assert result.output == expected_settings diff --git a/tests/cli/test_cli_current.py b/tests/cli/test_cli_current.py index 7faef9c..3f7c7d4 100644 --- a/tests/cli/test_cli_current.py +++ b/tests/cli/test_cli_current.py @@ -13,25 +13,24 @@ import tests.helpers from circfirm.cli import cli +RUNNER = CliRunner() -def test_current() -> None: - """Tests the current name command.""" - runner = CliRunner() - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE) - tests.helpers.copy_boot_out() +@tests.helpers.as_circuitpy +def test_current() -> None: + """Tests the current name and version commands.""" # Test when connected in CIRCUITPY mode - result = runner.invoke(cli, ["current", "name"]) + result = RUNNER.invoke(cli, ["current", "name"]) assert result.exit_code == 0 assert result.output == "feather_m4_express\n" - result = runner.invoke(cli, ["current", "version"]) + result = RUNNER.invoke(cli, ["current", "version"]) assert result.exit_code == 0 assert result.output == "8.0.0-beta.6\n" - tests.helpers.delete_mount_node(circfirm.BOOTOUT_FILE) - tests.helpers.copy_uf2_info() - # Test when connected in bootloader mode - result = runner.invoke(cli, ["current", "name"]) +@tests.helpers.as_bootloader +def test_current_in_bootloader() -> None: + """Tests the current command whenn connected in bootloader mode.""" + result = RUNNER.invoke(cli, ["current", "name"]) assert result.exit_code != 0 diff --git a/tests/cli/test_cli_install.py b/tests/cli/test_cli_install.py index dae3ea0..ddd7ec4 100644 --- a/tests/cli/test_cli_install.py +++ b/tests/cli/test_cli_install.py @@ -17,57 +17,67 @@ import tests.helpers from circfirm.cli import cli +RUNNER = CliRunner() -def test_install() -> None: - """Tests the install command.""" - version = "8.0.0-beta.6" - runner = CliRunner() - - # Test successfully installing the firmware - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE) - tests.helpers.copy_boot_out() - threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() - result = runner.invoke(cli, ["install", version]) - assert result.exit_code == 0 - expected_uf2_filename = circfirm.backend.get_uf2_filename( - "feather_m4_express", version - ) - expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) - assert os.path.exists(expected_uf2_filepath) - os.remove(expected_uf2_filepath) - - # Test using cached version of firmware - result = runner.invoke(cli, ["install", version, "--board", "feather_m4_express"]) - assert result.exit_code == 0 - assert "Using cached firmware file" in result.output - os.remove(expected_uf2_filepath) - - ERR_NOT_FOUND = 1 - ERR_FOUND_CIRCUITPY = 2 - ERR_IN_BOOTLOADER = 3 - ERR_UF2_DOWNLOAD = 4 - - # Test not finding the mounted drive - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE) - result = runner.invoke(cli, ["install", version, "--board", "feather_m4_express"]) +ERR_NOT_FOUND = 1 +ERR_FOUND_CIRCUITPY = 2 +ERR_IN_BOOTLOADER = 3 +ERR_UF2_DOWNLOAD = 4 + +VERSION = "8.0.0-beta.6" + + +@tests.helpers.as_circuitpy +def test_install_successful() -> None: + """Tests the successful use of the install command.""" + try: + # Test successfully installing the firmware + threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() + result = RUNNER.invoke(cli, ["install", VERSION]) + assert result.exit_code == 0 + expected_uf2_filename = circfirm.backend.get_uf2_filename( + "feather_m4_express", VERSION + ) + expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) + assert os.path.exists(expected_uf2_filepath) + os.remove(expected_uf2_filepath) + + # Test using cached version of firmware + result = RUNNER.invoke( + cli, ["install", VERSION, "--board", "feather_m4_express"] + ) + assert result.exit_code == 0 + assert "Using cached firmware file" in result.output + os.remove(expected_uf2_filepath) + + finally: + board_folder = circfirm.backend.get_board_folder("feather_m4_express") + if board_folder.exists(): + shutil.rmtree(board_folder) + + +@tests.helpers.as_not_present +def test_install_no_mount() -> None: + """Tests the install command when a mounted drive is not found.""" + result = RUNNER.invoke(cli, ["install", VERSION, "--board", "feather_m4_express"]) assert result.exit_code == ERR_NOT_FOUND - # Test finding the mounted drive as CIRCUITPY - tests.helpers.copy_boot_out() - result = runner.invoke(cli, ["install", version, "--board", "feather_m4_express"]) + +@tests.helpers.as_circuitpy +def test_install_as_circuitpy() -> None: + """Tests the install command when a mounted CIRCUITPY drive is found.""" + result = RUNNER.invoke(cli, ["install", VERSION, "--board", "feather_m4_express"]) assert result.exit_code == ERR_FOUND_CIRCUITPY - # Test using bad board version - tests.helpers.delete_mount_node(circfirm.BOOTOUT_FILE) - tests.helpers.copy_uf2_info() - result = runner.invoke( + +@tests.helpers.as_bootloader +def test_install_bad_version() -> None: + """Tests the install command using a bad board version.""" + result = RUNNER.invoke( cli, ["install", "doesnotexist", "--board", "feather_m4_express"] ) assert result.exit_code == ERR_UF2_DOWNLOAD # Test using install when in bootloader mode - result = runner.invoke(cli, ["install", version]) + result = RUNNER.invoke(cli, ["install", VERSION]) assert result.exit_code == ERR_IN_BOOTLOADER - - board_folder = circfirm.backend.get_board_folder("feather_m4_express") - shutil.rmtree(board_folder) diff --git a/tests/cli/test_cli_query.py b/tests/cli/test_cli_query.py index 2fdf78e..f7938b2 100644 --- a/tests/cli/test_cli_query.py +++ b/tests/cli/test_cli_query.py @@ -18,6 +18,8 @@ import tests.helpers from circfirm.cli import cli +RUNNER = CliRunner() + def simulate_no_connection(arg: str) -> NoReturn: """Simulate a network error by raising requests.ConnectionError.""" @@ -26,8 +28,6 @@ def simulate_no_connection(arg: str) -> NoReturn: def test_query_boards(monkeypatch: pytest.MonkeyPatch) -> None: """Tests the ability to query the boards using the CLI.""" - runner = CliRunner() - # Test an unauthenticated request with supporting text boards = tests.helpers.get_boards_from_git() pre_expected_output = "".join([f"{board}\n" for board in boards]) @@ -40,33 +40,33 @@ def test_query_boards(monkeypatch: pytest.MonkeyPatch) -> None: ] ) - result = runner.invoke(cli, ["query", "boards"]) + result = RUNNER.invoke(cli, ["query", "boards"]) assert result.exit_code == 0 assert result.output == expected_output # Test an authenticated request without supporting text - result = runner.invoke( + result = RUNNER.invoke( cli, ["config", "edit", "token.github", os.environ["GH_TOKEN"]] ) assert result.exit_code == 0 - result = runner.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) + result = RUNNER.invoke(cli, ["config", "edit", "output.supporting.silence", "true"]) assert result.exit_code == 0 - result = runner.invoke(cli, ["query", "boards"]) + result = RUNNER.invoke(cli, ["query", "boards"]) assert result.exit_code == 0 assert result.output == pre_expected_output # Test a request with a faulty token - result = runner.invoke(cli, ["config", "edit", "token.github", "badtoken"]) + result = RUNNER.invoke(cli, ["config", "edit", "token.github", "badtoken"]) assert result.exit_code == 0 - result = runner.invoke(cli, ["query", "boards"]) + result = RUNNER.invoke(cli, ["query", "boards"]) assert result.exit_code != 0 - result = runner.invoke(cli, ["config", "reset"]) + result = RUNNER.invoke(cli, ["config", "reset"]) assert result.exit_code == 0 # Tests failure when cannot fetch results due to no network connection monkeypatch.setattr(circfirm.backend, "get_board_list", simulate_no_connection) - result = runner.invoke(cli, ["query", "boards"]) + result = RUNNER.invoke(cli, ["query", "boards"]) assert result.exit_code != 0 assert ( result.output.split("\n")[-2] @@ -85,8 +85,7 @@ def test_query_versions() -> None: ] expected_output = "".join([f"{version}\n" for version in expected_versions]) - runner = CliRunner() - result = runner.invoke( + result = RUNNER.invoke( cli, [ "query", @@ -107,8 +106,7 @@ def test_query_latest() -> None: expected_output = "6.2.0-beta.2\n" # Test without pre-releases included - runner = CliRunner() - result = runner.invoke( + result = RUNNER.invoke( cli, [ "query", @@ -122,7 +120,7 @@ def test_query_latest() -> None: assert result.output == "" # Test with pre-releases included - result = runner.invoke( + result = RUNNER.invoke( cli, ["query", "latest", board, "--language", language, "--pre-release"], ) diff --git a/tests/cli/test_cli_update.py b/tests/cli/test_cli_update.py index 87ee498..4ccff0a 100644 --- a/tests/cli/test_cli_update.py +++ b/tests/cli/test_cli_update.py @@ -18,47 +18,52 @@ import tests.helpers from circfirm.cli import cli +RUNNER = CliRunner() +ORIGINAL_VERSION = "6.0.0" + + +@tests.helpers.as_circuitpy def test_update() -> None: - """Tests the update command.""" - runner = CliRunner() - original_version = "6.0.0" + """Test the update command when in CIRCUITPY mode.""" + try: + tests.helpers.set_firmware_version(ORIGINAL_VERSION) + + threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() + result = RUNNER.invoke(cli, ["update", "--language", "cs"]) + expected_version = "6.1.0" + expected_uf2_filename = circfirm.backend.get_uf2_filename( + "feather_m4_express", expected_version, language="cs" + ) + expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) + assert result.exit_code == 0 + assert os.path.exists(expected_uf2_filepath) + os.remove(expected_uf2_filepath) - # Test the update command when in CIRCUITPY mode - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE) - tests.helpers.copy_boot_out() - tests.helpers.set_firmware_version(original_version) + finally: + board_folder = circfirm.backend.get_board_folder("feather_m4_express") + if board_folder.exists(): + shutil.rmtree(board_folder) - threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() - result = runner.invoke(cli, ["update", "--language", "cs"]) - expected_version = "6.1.0" - expected_uf2_filename = circfirm.backend.get_uf2_filename( - "feather_m4_express", expected_version, language="cs" - ) - expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) - assert result.exit_code == 0 - assert os.path.exists(expected_uf2_filepath) - os.remove(expected_uf2_filepath) - # Test the update command when in CIRCUITPY mode with the pre-release flag - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE) - tests.helpers.copy_boot_out() - tests.helpers.set_firmware_version(original_version) +@tests.helpers.as_circuitpy +def test_update_pre_release() -> None: + """Tests the update command when in CIRCUITPY mode with the pre-release flag.""" + try: + tests.helpers.set_firmware_version(ORIGINAL_VERSION) - threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() - result = runner.invoke(cli, ["update", "--language", "cs", "--pre-release"]) - expected_version = "6.2.0-beta.2" - expected_uf2_filename = circfirm.backend.get_uf2_filename( - "feather_m4_express", expected_version, language="cs" - ) - expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) - assert result.exit_code == 0 - assert os.path.exists(expected_uf2_filepath) - os.remove(expected_uf2_filepath) + threading.Thread(target=tests.helpers.wait_and_set_bootloader).start() + result = RUNNER.invoke(cli, ["update", "--language", "cs", "--pre-release"]) + expected_version = "6.2.0-beta.2" + expected_uf2_filename = circfirm.backend.get_uf2_filename( + "feather_m4_express", expected_version, language="cs" + ) + expected_uf2_filepath = tests.helpers.get_mount_node(expected_uf2_filename) + assert result.exit_code == 0 + assert os.path.exists(expected_uf2_filepath) + os.remove(expected_uf2_filepath) - # Reset state after tests - tests.helpers.delete_mount_node(circfirm.BOOTOUT_FILE, missing_ok=True) - tests.helpers.delete_mount_node(circfirm.UF2INFO_FILE, missing_ok=True) - tests.helpers.copy_uf2_info() - board_folder = circfirm.backend.get_board_folder("feather_m4_express") - shutil.rmtree(board_folder) + finally: + board_folder = circfirm.backend.get_board_folder("feather_m4_express") + if board_folder.exists(): + shutil.rmtree(board_folder) diff --git a/tests/helpers.py b/tests/helpers.py index 9b8dfea..2e6b9a3 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -12,11 +12,52 @@ import platform import shutil import time -from typing import List +from typing import Callable, List, TypeVar import circfirm import circfirm.backend +_T = TypeVar("_T") + + +def as_circuitpy(func: Callable[..., _T]) -> Callable[..., _T]: + """Decorator for running a function with a device connected in CIRCUITPY mode.""" # noqa: D401 + + def as_circuitpy_wrapper(*args, **kwargs) -> _T: + delete_mount_node(circfirm.BOOTOUT_FILE, missing_ok=True) + delete_mount_node(circfirm.UF2INFO_FILE, missing_ok=True) + copy_boot_out() + result = func(*args, **kwargs) + delete_mount_node(circfirm.BOOTOUT_FILE, missing_ok=True) + return result + + return as_circuitpy_wrapper + + +def as_bootloader(func: Callable[..., _T]) -> Callable[..., _T]: + """Decorator for running a function with a device connected in bootloader mode.""" # noqa: D401 + + def as_bootloader_wrapper(*args, **kwargs) -> _T: + delete_mount_node(circfirm.BOOTOUT_FILE, missing_ok=True) + delete_mount_node(circfirm.UF2INFO_FILE, missing_ok=True) + copy_uf2_info() + result = func(*args, **kwargs) + delete_mount_node(circfirm.UF2INFO_FILE, missing_ok=True) + return result + + return as_bootloader_wrapper + + +def as_not_present(func: Callable[..., _T]) -> Callable[..., _T]: + """Decorator for running a function without a device connected in either CIRCUITPY or bootloader mode.""" # noqa: D401 + + def as_not_present_wrapper(*args, **kwargs) -> _T: + delete_mount_node(circfirm.BOOTOUT_FILE, missing_ok=True) + delete_mount_node(circfirm.UF2INFO_FILE, missing_ok=True) + return func(*args, **kwargs) + + return as_not_present_wrapper + def wait_and_set_bootloader() -> None: """Wait then add the boot_out.txt file.""" diff --git a/tests/test_backend.py b/tests/test_backend.py index 7d112b0..58fa3d7 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -17,37 +17,39 @@ import tests.helpers +@tests.helpers.as_circuitpy def test_find_circuitpy() -> None: - """Tests finding a CircuitPython device.""" - # Test when boot_out.txt is preset - boot_out = tests.helpers.get_mount_node(circfirm.BOOTOUT_FILE) - tests.helpers.touch_mount_node(boot_out) - + """Tests finding a CircuitPython device when boot_out.txt is present.""" mount_location = tests.helpers.get_mount() circuitpy = circfirm.backend.find_circuitpy() assert circuitpy == mount_location - # Test when boot_out.txt is absent - os.remove(boot_out) + +@tests.helpers.as_not_present +def test_find_circuitpy_absent() -> None: + """Tests finding a CircuitPython device when boot_out.txt is absent.""" + tests.helpers.delete_mount_node(circfirm.BOOTOUT_FILE) circuitpy = circfirm.backend.find_circuitpy() assert circuitpy is None +@tests.helpers.as_bootloader def test_find_bootloader() -> None: - """Tests finding a CircuitPython device in bootloader mode.""" - # Test when info_uf2.txt is preset + """Tests finding a CircuitPython device in bootloader mode when info_uf2.txt is present.""" mount_location = tests.helpers.get_mount() bootloader = circfirm.backend.find_bootloader() assert bootloader == mount_location - # Test when info_uf2.txt is absent - uf2_info = tests.helpers.get_mount_node(circfirm.UF2INFO_FILE, True) - os.remove(uf2_info) + +@tests.helpers.as_not_present +def test_find_bootloader_absent() -> None: + """Tests finding a CircuitPython device in bootloader mode when info_uf2.txt is absent.""" bootloader = circfirm.backend.find_bootloader() assert bootloader is None tests.helpers.copy_uf2_info() +@tests.helpers.as_circuitpy def test_get_board_info() -> None: """Tests getting the board name and firmware version from the UF2 info file.""" # Setup @@ -75,10 +77,6 @@ def test_get_board_info() -> None: with pytest.raises(ValueError): circfirm.backend.get_board_info(mount_location) - # Clean up - tests.helpers.delete_mount_node(circfirm.BOOTOUT_FILE) - tests.helpers.copy_uf2_info() - def test_get_board_folder() -> None: """Tests getting UF2 information."""