|
| 1 | +# Contributing to Mineflayer Tests as an LLM |
| 2 | + |
| 3 | +This guide explains how to add and modify tests in Mineflayer, based on the experience of working with the time-related functionality. It provides a structured approach for LLMs to help with test development and debugging. |
| 4 | + |
| 5 | +## Test Structure |
| 6 | + |
| 7 | +### Location |
| 8 | +- Tests are located in `test/externalTests/` |
| 9 | +- Each test file corresponds to a specific functionality |
| 10 | +- Test files follow the naming convention of the feature they test (e.g., `time.js` for time-related tests) |
| 11 | + |
| 12 | +### Basic Test Template |
| 13 | +```javascript |
| 14 | +const assert = require('assert') |
| 15 | +const { once } = require('../../lib/promise_utils') |
| 16 | + |
| 17 | +module.exports = () => async (bot) => { |
| 18 | + // Test implementation |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | +## Writing Tests |
| 23 | + |
| 24 | +### 1. Property Testing |
| 25 | +- Define expected properties and their types |
| 26 | +- Use `assert.strictEqual` for type checking |
| 27 | +- Verify value ranges where applicable |
| 28 | + |
| 29 | +Example: |
| 30 | +```javascript |
| 31 | +const timeProps = { |
| 32 | + doDaylightCycle: 'boolean', |
| 33 | + bigTime: 'bigint', |
| 34 | + time: 'number' |
| 35 | +} |
| 36 | + |
| 37 | +Object.entries(timeProps).forEach(([prop, type]) => { |
| 38 | + assert.strictEqual(typeof bot.time[prop], type) |
| 39 | +}) |
| 40 | +``` |
| 41 | + |
| 42 | +### 2. Helper Functions |
| 43 | +- Create reusable helper functions for common operations |
| 44 | +- Include functions for waiting and state verification |
| 45 | +- Use descriptive names that explain their purpose |
| 46 | + |
| 47 | +Example: |
| 48 | +```javascript |
| 49 | +const waitForTime = async () => { |
| 50 | + await once(bot, 'time') |
| 51 | + await bot.test.wait(200) |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +### 3. Test Cases |
| 56 | +- Organize test cases in arrays for better maintainability |
| 57 | +- Include descriptive names and expected outcomes |
| 58 | +- Group related tests together |
| 59 | + |
| 60 | +Example: |
| 61 | +```javascript |
| 62 | +const timeTests = [ |
| 63 | + { time: 18000, name: 'midnight', isDay: false }, |
| 64 | + { time: 6000, name: 'noon', isDay: true } |
| 65 | +] |
| 66 | +``` |
| 67 | + |
| 68 | +## Running Tests |
| 69 | + |
| 70 | +### Basic Test Execution |
| 71 | +```bash |
| 72 | +npm run mocha_test -- -g "mineflayer_external 1.20.4v.*time" |
| 73 | +``` |
| 74 | + |
| 75 | +### Version-Specific Testing |
| 76 | +- Test against multiple Minecraft versions |
| 77 | +- Common versions to test: 1.14.4, 1.20.4, 1.21.3 |
| 78 | +- Example: |
| 79 | +```bash |
| 80 | +# Test for 1.14.4 |
| 81 | +npm run mocha_test -- -g "mineflayer_external 1.14.4v.*time" |
| 82 | + |
| 83 | +# Test for 1.21.3 |
| 84 | +npm run mocha_test -- -g "mineflayer_external 1.21.3v.*time" |
| 85 | +``` |
| 86 | + |
| 87 | +## Debugging Tests |
| 88 | + |
| 89 | +### 1. Adding Debug Logs |
| 90 | +- Use `console.log` for debugging (remove before final commit) |
| 91 | +- Log important state changes and values |
| 92 | +- Example: |
| 93 | +```javascript |
| 94 | +console.log('Time properties:', bot.time) |
| 95 | +``` |
| 96 | + |
| 97 | +### 2. Common Issues |
| 98 | +- Timing issues: Adjust wait times if needed (default 200ms) |
| 99 | +- Version compatibility: Check packet formats across versions |
| 100 | +- State synchronization: Ensure proper event handling |
| 101 | + |
| 102 | +### 3. Test Output |
| 103 | +- Watch for server startup messages |
| 104 | +- Monitor bot commands and responses |
| 105 | +- Check for any error messages or warnings |
| 106 | + |
| 107 | +## Best Practices |
| 108 | + |
| 109 | +1. **Test Organization** |
| 110 | + - Group related tests together |
| 111 | + - Use descriptive test names |
| 112 | + - Keep tests focused and atomic |
| 113 | + |
| 114 | +2. **Error Handling** |
| 115 | + - Include clear error messages |
| 116 | + - Test edge cases |
| 117 | + - Verify state after each operation |
| 118 | + |
| 119 | +3. **Performance** |
| 120 | + - Minimize wait times |
| 121 | + - Clean up resources |
| 122 | + - Avoid redundant tests |
| 123 | + |
| 124 | +4. **Documentation** |
| 125 | + - Comment complex logic |
| 126 | + - Explain test purposes |
| 127 | + - Document version-specific behavior |
| 128 | + |
| 129 | +## Common Commands |
| 130 | + |
| 131 | +### Server Commands |
| 132 | +```javascript |
| 133 | +bot.test.sayEverywhere('/time set 0') // Set time |
| 134 | +bot.test.sayEverywhere('/gamerule doDaylightCycle false') // Toggle game rules |
| 135 | +``` |
| 136 | + |
| 137 | +### Bot Operations |
| 138 | +```javascript |
| 139 | +async function f () { |
| 140 | + await bot.test.wait(200) // Wait for specified milliseconds |
| 141 | + await once(bot, 'time') // Wait for specific event |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | +## Version Compatibility |
| 146 | + |
| 147 | +- Test against multiple Minecraft versions |
| 148 | +- Handle version-specific packet formats |
| 149 | +- Consider backward compatibility |
| 150 | +- Document version-specific behavior |
| 151 | + |
| 152 | +## Adding a New Test |
| 153 | + |
| 154 | +When adding a new test, follow these steps: |
| 155 | + |
| 156 | +1. **Create a new test file** in the `test/externalTests` directory. For example, `experience.js`. |
| 157 | +2. **Write the test logic** using async/await. Avoid using the `done` callback if possible. |
| 158 | +3. **Handle version differences** if necessary. For example, the experience command syntax differs between Minecraft versions: |
| 159 | + - For versions older than 1.13, use `/xp <amount> [player]`. |
| 160 | + - For versions 1.13 and newer, use `/xp add <player> <amount> points` or `/xp add <player> <amount> levels`. |
| 161 | +4. **Add event listeners** for debugging if needed, and ensure they are removed at the end of the test to prevent memory leaks. |
| 162 | +5. **Use `bot.chat`** to issue commands directly instead of `bot.test.runCommand`. |
| 163 | +6. **Run the test** for different Minecraft versions to ensure compatibility. |
| 164 | + |
| 165 | +Example test structure: |
| 166 | +```javascript |
| 167 | +const assert = require('assert') |
| 168 | +const { once } = require('../../lib/promise_utils') |
| 169 | + |
| 170 | +module.exports = () => async (bot) => { |
| 171 | + // Test logic here |
| 172 | + // Example: Check bot's experience state |
| 173 | + console.log('[experience test] Bot username:', bot.username) |
| 174 | + await bot.test.becomeSurvival() |
| 175 | + // ... more test logic ... |
| 176 | + // Remove event listeners at the end |
| 177 | + bot.removeListener('experience', expListener) |
| 178 | + console.log('[experience test] All checks passed!') |
| 179 | +} |
| 180 | +``` |
| 181 | + |
| 182 | +## Specific Details from Recent Experience |
| 183 | + |
| 184 | +- **Version-Specific Command Syntax**: Always check the Minecraft Wiki or existing tests for the correct command syntax for each version. For example, the experience command syntax changed in 1.13. |
| 185 | +- **Event Listener Cleanup**: Always remove event listeners at the end of the test to prevent memory leaks. Use `bot.removeListener('eventName', listenerFunction)`. |
| 186 | +- **Use `bot.chat`**: For issuing commands, use `bot.chat` directly instead of `bot.test.runCommand` to ensure commands are sent correctly. |
| 187 | +- **Debugging**: Use `console.log` for debugging, but remove these statements before finalizing the test. |
| 188 | + |
| 189 | +## Conclusion |
| 190 | + |
| 191 | +When adding or modifying tests: |
| 192 | +1. Understand the feature being tested |
| 193 | +2. Write clear, focused tests |
| 194 | +3. Test across multiple versions |
| 195 | +4. Include proper error handling |
| 196 | +5. Clean up debug code before committing |
| 197 | +6. Document any version-specific behavior |
| 198 | + |
| 199 | +Remember to remove any debugging `console.log` statements before finalizing the changes. |
0 commit comments