Implements template-based project creation allowing teams to start with
professional example code instead of empty projects.
Features:
- Two templates: 'basic' (minimal) and 'testing' (45-test showcase)
- Template variable substitution ({{PROJECT_NAME}}, etc.)
- Template validation with helpful error messages
- `weevil new --list-templates` command
- Template files embedded in binary at compile time
Technical details:
- Templates stored in templates/basic/ and templates/testing/
- Files ending in .template have variables replaced
- Uses include_dir! macro to embed templates in binary
- Returns file count for user feedback
Testing template includes:
- 3 complete subsystems (MotorCycler, WallApproach, TurnController)
- Hardware abstraction layer with mock implementations
- 45 comprehensive tests (unit, integration, system)
- Professional documentation (DESIGN_AND_TEST_PLAN.md, etc.)
Usage:
weevil new my-robot # basic template
weevil new my-robot --template testing # testing showcase
weevil new --list-templates # show available templates
This enables FTC teams to learn from working code and best practices
rather than starting from scratch.
127 lines
3.3 KiB
Markdown
127 lines
3.3 KiB
Markdown
# Solution: Testing FTC Code Without Hardware
|
|
|
|
## The Problem
|
|
|
|
When you run `gradlew test`, it tries to compile ALL your code including FTC-dependent files:
|
|
```
|
|
FtcMotorController.java → needs com.qualcomm.robotcore.hardware.DcMotor
|
|
MotorCycleOpMode.java → needs com.qualcomm.robotcore.eventloop.opmode.OpMode
|
|
```
|
|
|
|
These classes don't exist on Windows → compilation fails → no tests.
|
|
|
|
## The Solution (One Line)
|
|
|
|
**Exclude FTC-dependent files from test compilation:**
|
|
|
|
```kotlin
|
|
// build.gradle.kts
|
|
sourceSets {
|
|
main {
|
|
java {
|
|
exclude(
|
|
"robot/hardware/FtcMotorController.java",
|
|
"robot/opmodes/**/*.java"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Done. That's it.
|
|
|
|
## What Happens Now
|
|
|
|
### When You Run `gradlew test`:
|
|
- ✅ Compiles: MotorController.java (interface, no FTC deps)
|
|
- ✅ Compiles: MotorCycler.java (pure Java logic)
|
|
- ✅ Compiles: MockMotorController.java (test mock)
|
|
- ✅ Compiles: MotorCyclerTest.java (tests)
|
|
- ❌ Skips: FtcMotorController.java (EXCLUDED - has FTC deps)
|
|
- ❌ Skips: MotorCycleOpMode.java (EXCLUDED - has FTC deps)
|
|
|
|
Tests run on Windows in seconds!
|
|
|
|
### When You Run `build.bat`:
|
|
- Copies ALL files to FTC SDK TeamCode directory
|
|
- FTC SDK's Gradle compiles everything (it has the FTC SDK jars)
|
|
- Creates APK with all your code
|
|
|
|
## The Architecture Pattern
|
|
|
|
```
|
|
Interface (no FTC) → Logic uses interface → Test with mock
|
|
↓
|
|
FTC Implementation (excluded from tests)
|
|
```
|
|
|
|
### Example: Motor
|
|
```java
|
|
// 1. Interface (compiles for tests)
|
|
public interface MotorController {
|
|
void setPower(double power);
|
|
}
|
|
|
|
// 2. FTC implementation (excluded from tests)
|
|
public class FtcMotorController implements MotorController {
|
|
private final DcMotor motor; // FTC SDK class
|
|
public void setPower(double p) { motor.setPower(p); }
|
|
}
|
|
|
|
// 3. Mock (test only)
|
|
public class MockMotorController implements MotorController {
|
|
private double power;
|
|
public void setPower(double p) { this.power = p; }
|
|
}
|
|
|
|
// 4. Logic (pure Java - testable!)
|
|
public class MotorCycler {
|
|
private final MotorController motor; // Uses interface!
|
|
// ... no FTC dependencies ...
|
|
}
|
|
|
|
// 5. Test
|
|
@Test
|
|
void test() {
|
|
MockMotorController mock = new MockMotorController();
|
|
MotorCycler cycler = new MotorCycler(mock, 100, 50);
|
|
cycler.update(60);
|
|
assertEquals(0.5, mock.getPower());
|
|
}
|
|
```
|
|
|
|
## Applies to Any Hardware
|
|
|
|
Same pattern for everything:
|
|
- **Motors** → MotorController interface + Ftc + Mock
|
|
- **Servos** → ServoController interface + Ftc + Mock
|
|
- **Sensors** (I2C, SPI, USB, etc.) → SensorInterface + Ftc + Mock
|
|
- **Gyros** → GyroSensor interface + Ftc + Mock
|
|
|
|
The FTC implementation is always just a thin wrapper. All your logic uses interfaces and is fully testable.
|
|
|
|
## Why This Works
|
|
|
|
**Test compilation:**
|
|
- Only compiles files WITHOUT FTC dependencies
|
|
- Pure Java logic + interfaces + mocks
|
|
- Runs on Windows JRE
|
|
|
|
**Robot compilation:**
|
|
- ALL files copied to TeamCode
|
|
- Compiled by FTC SDK (which has FTC jars)
|
|
- Creates APK with everything
|
|
|
|
Same logic runs in both places - no special test-only code!
|
|
|
|
## Quick Start
|
|
|
|
1. Create interface (no FTC deps)
|
|
2. Create FTC implementation (add to exclude list)
|
|
3. Create mock for testing
|
|
4. Write pure Java logic using interface
|
|
5. Test instantly on PC
|
|
6. Deploy to robot - everything works
|
|
|
|
See TESTING_GUIDE.md for detailed examples.
|