diff --git a/pyfrc/mains/cli_add_tests.py b/pyfrc/mains/cli_add_tests.py index 404af8d..0bb013d 100644 --- a/pyfrc/mains/cli_add_tests.py +++ b/pyfrc/mains/cli_add_tests.py @@ -48,5 +48,4 @@ def run(self, main_file: pathlib.Path, project_path: pathlib.Path): fp.write(builtin_tests) print("- builtin tests created at", builtin_tests_file) - print() - print("Robot tests can be ran via 'python3 -m robotpy test'") + print("Robot tests can be ran via 'robotpy test'") diff --git a/pyfrc/mains/cli_test.py b/pyfrc/mains/cli_test.py index 5b59f33..e8aa468 100644 --- a/pyfrc/mains/cli_test.py +++ b/pyfrc/mains/cli_test.py @@ -1,3 +1,5 @@ +import io +import re import os from os.path import abspath import inspect @@ -17,9 +19,44 @@ # could be a useful thing. Will have to consider that later. +import sys +import pathlib +from pyfrc.test_support.pytest_plugin import PyFrcPlugin +# Tests are always run from the top directory of the robot project +# so the location of robot.py should be the current working directory +sys.path.append('.') +import robot + +def pytest_configure(config): + if config.pluginmanager.has_plugin("pyfrc_plugin"): + # Avoid double registration + return + robot_class = robot.MyRobot + robot_file = './robot.py' + plugin = PyFrcPlugin(robot_class, robot_file) + config.pluginmanager.register(plugin, "pyfrc_plugin") + + class _TryAgain(Exception): pass +def count_tests(test_path='.'): + import subprocess + # Run pytest in collect-only mode to get test count + result = subprocess.run( + ['pytest', '--collect-only', '-v', test_path], + capture_output=True, + text=True + ) + print('subprocess result: ') + print(result.stdout) + + # Count lines that look like test collections + test_lines = [line for line in result.stdout.split('\n') + if re.search(r'\s*test_\w+\[?', line) and 'cachedir' not in line] + + test_count = len(test_lines) + return test_count # # main test class @@ -112,8 +149,12 @@ def _run_test( pytest_args.insert(0, abspath(inspect.getfile(basic))) try: + test_count = count_tests() + print(f'Running {test_count} parallel workers') + + args = ['-v', '-n', str(test_count)] + pytest_args retv = pytest.main( - pytest_args, + args, plugins=[pytest_plugin.PyFrcPlugin(robot_class, main_file)], ) finally: diff --git a/pyfrc/test_support/pytest_plugin.py b/pyfrc/test_support/pytest_plugin.py index 1aaf81f..0325293 100644 --- a/pyfrc/test_support/pytest_plugin.py +++ b/pyfrc/test_support/pytest_plugin.py @@ -38,6 +38,8 @@ def __init__(self, robot_class: Type[wpilib.RobotBase], robot_file: pathlib.Path robot_file.parent, ) + print('robot file: ', robot_file) + # Tests need to know when robotInit is called, so override the robot # to do that class TestRobot(robot_class): diff --git a/setup.cfg b/setup.cfg index 1b82c33..e9311e2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,6 +25,7 @@ packages = find: install_requires = pytest>=3.9 pytest-reraise + pytest-xdist>=3.6.1 pint>=0.11.0 wpilib>=2025.0.0b1,<2026