Sample

Schnappinger/junit4/junit.textui.TestRunner

Human rating uses the original dataset scale.

Human4
Lines206

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
30.4Δ 67.6
Scalabrino0.7940–1; higher is more readable
60.6Δ 37.4
Dorn0.0990–1; higher is more readable
33.0Δ 65.0
Mi0.7520–1; higher is more readable
91.1Δ 6.9
LLOC83Logical lines; fewer is more readable
27.4Δ 70.6
DeepSeek V4 Pro16.330–20; mean of three runs
53.1Δ 44.9
GPT-6.1 Sol170–20; mean of three runs
55.3Δ 42.7
BTTF0.4990–1; higher is more readable
44.6Δ 53.5
Human41–4; original rating
98.0

Views

Source code

package junit.textui; import java.io.PrintStream; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.runner.BaseTestRunner; import junit.runner.Version; /** * A command line based tool to run tests. * <pre> * java junit.textui.TestRunner [-wait] TestCaseClass * </pre> * <p> * TestRunner expects the name of a TestCase class as argument. * If this class defines a static <code>suite</code> method it * will be invoked and the returned test is run. Otherwise all * the methods starting with "test" having no arguments are run. * <p> * When the wait command line argument is given TestRunner * waits until the users types RETURN. * <p> * TestRunner prints a trace as the tests are executed followed by a * summary at the end. */ public class TestRunner extends BaseTestRunner { private ResultPrinter fPrinter; public static final int SUCCESS_EXIT = 0; public static final int FAILURE_EXIT = 1; public static final int EXCEPTION_EXIT = 2; /** * Constructs a TestRunner. */ public TestRunner() { this(System.out); } /** * Constructs a TestRunner using the given stream for all the output */ public TestRunner(PrintStream writer) { this(new ResultPrinter(writer)); } /** * Constructs a TestRunner using the given ResultPrinter all the output */ public TestRunner(ResultPrinter printer) { fPrinter = printer; } /** * Runs a suite extracted from a TestCase subclass. */ static public void run(Class<? extends TestCase> testClass) { run(new TestSuite(testClass)); } /** * Runs a single test and collects its results. * This method can be used to start a test run * from your program. * <pre> * public static void main (String[] args) { * test.textui.TestRunner.run(suite()); * } * </pre> */ static public TestResult run(Test test) { TestRunner runner = new TestRunner(); return runner.doRun(test); } /** * Runs a single test and waits until the user * types RETURN. */ static public void runAndWait(Test suite) { TestRunner aTestRunner = new TestRunner(); aTestRunner.doRun(suite, true); } @Override public void testFailed(int status, Test test, Throwable e) { } @Override public void testStarted(String testName) { } @Override public void testEnded(String testName) { } /** * Creates the TestResult to be used for the test run. */ protected TestResult createTestResult() { return new TestResult(); } public TestResult doRun(Test test) { return doRun(test, false); } public TestResult doRun(Test suite, boolean wait) { TestResult result = createTestResult(); result.addListener(fPrinter); long startTime = System.currentTimeMillis(); suite.run(result); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; fPrinter.print(result, runTime); pause(wait); return result; } protected void pause(boolean wait) { if (!wait) return; fPrinter.printWaitPrompt(); try { System.in.read(); } catch (Exception e) { } } public static void main(String args[]) { TestRunner aTestRunner = new TestRunner(); try { TestResult r = aTestRunner.start(args); if (!r.wasSuccessful()) { System.exit(FAILURE_EXIT); } System.exit(SUCCESS_EXIT); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(EXCEPTION_EXIT); } } /** * Starts a test run. Analyzes the command line arguments and runs the given * test suite. */ public TestResult start(String args[]) throws Exception { String testCase = ""; String method = ""; boolean wait = false; for (int i = 0; i < args.length; i++) { if (args[i].equals("-wait")) { wait = true; } else if (args[i].equals("-c")) { testCase = extractClassName(args[++i]); } else if (args[i].equals("-m")) { String arg = args[++i]; int lastIndex = arg.lastIndexOf('.'); testCase = arg.substring(0, lastIndex); method = arg.substring(lastIndex + 1); } else if (args[i].equals("-v")) { System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma"); } else { testCase = args[i]; } } if (testCase.equals("")) { throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class"); } try { if (!method.equals("")) { return runSingleMethod(testCase, method, wait); } Test suite = getTest(testCase); return doRun(suite, wait); } catch (Exception e) { throw new Exception("Could not create and run test suite: " + e); } } protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception { Class<? extends TestCase> testClass = loadSuiteClass(testCase).asSubclass(TestCase.class); Test test = TestSuite.createTest(testClass, method); return doRun(test, wait); } @Override protected void runFailed(String message) { System.err.println(message); System.exit(FAILURE_EXIT); } public void setPrinter(ResultPrinter printer) { fPrinter = printer; } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.5912.661−195.118
Source linesThe number of non-empty source lines.206+82.4
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.475−6.713

Intercept 8.87 + feature contributions = -110.561 (log-odds).
Score = sigmoid(-110.561) = 0.

Score0.794

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.206−6.257
Indentation frequencyHow rapidly indentation changes from line to line.165+4.97
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.165−3.365
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.204.818+2.453
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.119.99−1.417
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.119.99+1.132
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.076+0.208

Intercept 0.07 + feature contributions = -2.207 (log-odds).
Score = sigmoid(-2.207) = 0.099.

Score0.752
Score83
Run 1

The code is generally well-structured and readable. It has clear class and method separation, uses Javadoc appropriately, and maintains consistent naming conventions. The nesting depth is minimal, mostly limited to an if-else chain in the 'start' method and a try-catch block. Intent is mostly clear, with methods like 'runSingleMethod' and 'doRun' clearly describing their actions. The code is not unnecessarily long for its purpose, although some methods like 'start' could be slightly simplified. Action granularity is good, with one clear action per line in most methods. The reading flow is natural, moving from constructors to public API methods to internal helpers. Points are deducted for the empty exception handler in the 'pause' method, the slightly tangled command-line argument parsing in 'start', and some redundant catch-and-rethrow logic that could be clearer.

Run 2

The code is well-structured and readable. It has a clear class responsibility (a command-line test runner), with concise methods and purposeful Javadoc. The structure is logical: constructors, static helpers, core execution, then CLI parsing. Nesting is flat overall; the deepest logic in 'start' and 'pause' remains at 2-3 levels, which aids comprehension. Intent is clear due to descriptive method names like 'runSingleMethod' and 'createTestResult'. Code length is appropriate — no excessive boilerplate or redundant abstractions. Action granularity is mostly one action per line, particularly in 'doRun' and 'start'. Reading flow is natural, moving from high-level entry points to supporting implementation. Minor deductions: empty overridden methods (testFailed, testStarted, testEnded) add noise, and variable naming like 'fPrinter' uses a legacy prefix. The 'start' method could be split for clarity, but it remains manageable. Overall, this is clean, maintainable code with slight room for modernizing style.

Run 3

The code is generally well-structured and readable. It has logical organization with clear separation of methods, flat nesting, and good documentation via Javadoc comments. Constructors are overloaded cleanly, and methods have single responsibilities. However, a few areas reduce readability: the 'start' method contains a multi-branch argument parsing loop with moderate complexity, and some methods (like 'doRun') mix timing, listener registration, and result printing. Empty overridden methods add clutter without explanation. Action granularity is mostly one-per-line, though some lines combine multiple operations. Overall, readable but with minor opportunities for simplification.

Run 1

Code Structure: Well-organized into constructors, execution helpers, command-line handling, and output configuration, with clear separation of responsibilities. Nesting: Mostly shallow; the argument-parsing loop and conditional chain introduce only moderate complexity. Clarity of intent: Descriptive method names, named exit constants, and documentation explain the runner's purpose. Empty overrides and a silently ignored exception obscure some intent, while names such as r and fPrinter are less expressive. Code length: Most methods are concise, though constructor comments and wrapper methods add some verbosity. Action granularity: Statements generally perform one action per line; args[++i] combines index advancement with argument access, and the inline guard in pause is slightly less readable. Reading flow: Execution proceeds naturally through setup, running, reporting, and optional waiting. The longer start method, inconsistent declaration style, and scattered command-line concerns slightly interrupt otherwise strong readability.

Run 2

Code Structure: Well-separated methods handle construction, execution, argument parsing, and reporting; start combines parsing and dispatch but remains manageable. Nesting: Mostly shallow, with modest nesting in the argument loop and exception handling. Clarity of intent: Descriptive method names, exit constants, and documentation make the purpose clear; legacy names such as fPrinter, aTestRunner, and r, plus unexplained empty callbacks and a swallowed exception, reduce clarity. Code length: Generally concise, though repetitive constructor comments and wrapper methods add some verbosity. Action granularity: Nearly all statements perform one action per line; args[++i] combines index advancement with argument access, and the inline early return slightly compresses control flow. Reading flow: Consistent indentation and a natural progression from setup to execution support easy reading, with minor distractions from inconsistent modifier ordering and extra blank lines.

Run 3

Code Structure: Well-organized constructors, execution helpers, and command-line handling separate responsibilities. Nesting: Generally shallow, although start() combines a loop with a multi-branch conditional and exception handling. Clarity of intent: Descriptive methods, named exit constants, and documentation make the purpose clear; abbreviated names such as r, legacy fPrinter naming, and unexplained empty callbacks/catch blocks reduce clarity. Code length: Most methods are concise, though some comments repeat obvious behavior and argument parsing could be extracted. Action granularity: Mostly one action per line, with minor exceptions such as the inline guard return and incrementing i inside array access. Reading flow: Test execution follows a natural sequence from setup through execution, reporting, and optional pause. Mixing argument parsing and execution in start(), along with inconsistent declaration conventions, slightly interrupts an otherwise straightforward flow.