A local kata judge for Java. Point it at a kata directory with a solution and JUnit tests, and it compiles both, runs the tests, and shows a clear pass/fail report. Tracks your progress across katas. Compatible with CI via strict mode.
Live site: llerandi.github.io/java-kata-judge
The companion tool is java-runner, which compiles and runs single Java files without any project structure.
Tip
If you just want to compile and run Java files without any test infrastructure, check out java-runner - a command-line tool that wraps javac and java into one step, no IDE or build system required.
java-kata-judge wraps javac and the JUnit Platform Console Standalone jar into a single command. It compiles Solution.java and SolutionTest.java together into a temporary directory, runs the tests, and reports which ones pass and which fail. It also maintains a .progress file that tracks which katas you have fully completed.
No Maven, no Gradle, no IDE required.
| Tool | Purpose | Notes |
|---|---|---|
| Java JDK | Compile and run | Version 11 or higher |
| Bash | Run judge.sh |
Version 4+. Linux and macOS only. |
| JUnit 5 jar | Run tests | Place in lib/ - see Installation |
Windows users should use
judge.bat. Bash is not required on Windows.
Make sure you have the JDK installed, not just the JRE. You can verify with
javac -version.
git clone https://github.com/llerandi/java-kata-judge.git
cd java-kata-judge
chmod +x judge.shThen download the JUnit Platform Console Standalone jar and place it in lib/:
mkdir -p lib
curl -L -o lib/junit-platform-console-standalone-1.10.2.jar \
https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/1.10.2/junit-platform-console-standalone-1.10.2.jarThe jar is listed in .gitignore so it is not committed to the repository.
# Run a specific kata
./judge.sh katas/01-fizzbuzz
# Run in strict mode - exits with code 1 if any test fails (useful for CI)
./judge.sh katas/01-fizzbuzz --strict
# Run all katas and show progress
./judge.sh --all
# Run all katas in strict mode
./judge.sh --all --strict
# Show help
./judge.sh --helpjudge.bat katas\01-fizzbuzz
judge.bat katas\01-fizzbuzz --strict
judge.bat --all
judge.bat --all --strictFrom PowerShell, prefix with .\:
.\judge.bat katas\01-fizzbuzz
.\judge.bat --all --strictEach kata lives in its own directory under katas/. The directory must contain exactly two files:
katas/
└── 01-fizzbuzz/
├── Solution.java # Your implementation
└── SolutionTest.java # JUnit 5 tests
The naming convention for directories is NN-kata-name where NN is a zero-padded number. This keeps the katas sorted in a logical order.
Solution.java contains the class to implement:
public class Solution {
public String fizzBuzz(int n) {
// TODO: implement
return "";
}
}SolutionTest.java contains the JUnit 5 tests:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class SolutionTest {
private final Solution solution = new Solution();
@Test
void returnsFizzForMultipleOfThree() {
assertEquals("Fizz", solution.fizzBuzz(3));
}
}When tests fail:
Kata: 01-fizzbuzz
--------------------------------------------------
Compiling...
Compiled successfully
Running tests...
FAIL returnsFizzForMultipleOfThree()
FAIL returnsBuzzForMultipleOfFive()
FAIL returnsFizzBuzzForMultipleOfBoth()
FAIL returnsNumberAsString()
--------------------------------------------------
4 of 4 test(s) failed
Progress: 0 / 2 kata(s) completed
--------------------------------------------------
[ ] 01-fizzbuzz
[ ] 02-palindrome
When all tests pass:
Kata: 01-fizzbuzz
--------------------------------------------------
Compiling...
Compiled successfully
Running tests...
PASS returnsFizzForMultipleOfThree()
PASS returnsBuzzForMultipleOfFive()
PASS returnsFizzBuzzForMultipleOfBoth()
PASS returnsNumberAsString()
--------------------------------------------------
All 4 test(s) passed
Progress: 1 / 2 kata(s) completed
--------------------------------------------------
[DONE] 01-fizzbuzz
[ ] 02-palindrome
The judge maintains a .progress file in the project root. A kata is marked as done when all its tests pass, and unmarked if you run it again and tests fail. The file is listed in .gitignore so your local progress is not committed.
Strict mode causes the script to exit with code 1 if any test fails. This makes the judge compatible with CI pipelines.
./judge.sh katas/01-fizzbuzz --strict
echo $? # 0 if all pass, 1 if any failEvery push to main or dev, and every pull request targeting main, triggers the CI pipeline defined in .github/workflows/ci.yaml. It runs on Ubuntu, macOS, and Windows in parallel. Each job installs JDK 21, downloads the JUnit jar, and runs the test suite via test.sh or test.bat.
To run the test suite locally:
# Linux and macOS
chmod +x test.sh
./test.sh
# Windows
test.batThe tests cover the judge infrastructure: passing kata exits 0, failing kata exits 1 with --strict, failing kata exits 0 without --strict, and missing directory exits non-zero. The same suite runs automatically on every push via the CI pipeline.
- Create a new directory under
katas/following the naming convention:katas/NN-kata-name/ - Add
Solution.javawith the class stub and a doc comment describing the problem - Add
SolutionTest.javawith JUnit 5 tests covering the expected behavior - Run
./judge.sh katas/NN-kata-nameto verify the stub compiles and the tests fail as expected
java-kata-judge/
├── .github/
│ └── workflows/
│ ├── ci.yaml # CI pipeline - Linux, macOS, Windows
│ └── pages.yaml # GitHub Pages deployment
├── docs/
│ └── index.html # GitHub Pages site
├── katas/
│ ├── 01-fizzbuzz/
│ │ ├── Solution.java # Implementation stub
│ │ └── SolutionTest.java # JUnit 5 tests
│ └── 02-palindrome/
│ ├── Solution.java
│ └── SolutionTest.java
├── lib/
│ └── junit-platform-console-standalone-*.jar # Not committed
├── tests/
│ ├── passing/
│ │ ├── Solution.java # CI fixture: correct implementation
│ │ └── SolutionTest.java
│ └── failing/
│ ├── Solution.java # CI fixture: intentionally wrong
│ └── SolutionTest.java
├── .gitattributes
├── .gitignore
├── judge.bat # Windows script
├── judge.sh # Linux and macOS script
├── test.bat # Test suite for Windows
├── test.sh # Test suite for Linux and macOS
└── README.md
-
judge.shfor Linux and macOS -
judge.batfor Windows - JUnit 5 standalone integration - no Maven, no Gradle
-
--strictmode - CI-compatible exit code -
--allmode - run every kata in one command - Progress tracker -
.progressfile, survives between runs - CI pipeline - Ubuntu, macOS, and Windows in parallel
- Sample katas - 01-fizzbuzz, 02-palindrome
- GitHub Pages documentation site
- More katas - reverse string, two sum, roman numerals, ...
-
--listflag - show all katas with their current status -
--resetflag - clear the.progressfile - Watch mode - rerun tests automatically on file save
- ANSI color output on Windows via VT100
MIT. Free to use, modify, and share.