cswork / libraryOpen practice workspace

Articles

SHL Automata Fix Assessment: Practice Logic, Syntax, and Code-Reuse Debugging

Prepare for SHL Automata Fix with official format boundaries, original syntax and logic repairs, code-reuse examples, and regression tests for candidates.

If your invitation says Automata Fix, practice repairing existing code, not writing a solution from a blank editor. SHL's Automata Fix fact sheet describes a simulated compiler exercise in C, C++, or Java that measures syntactical-error repair, logical-error repair, and code reuse. The useful preparation loop is to reproduce a failure, make the smallest justified change, and run a boundary case that could disprove your fix.

The worked examples below are original teaching exercises, not copied assessment items.

What the official Automata Fix description confirms

The SHL fact sheet names a simulated compiler and three reported dimensions: Syntactical Errors, Logical Errors, and Code Reuse. It lists an average testing time of 14 minutes, an allowed time of 20 minutes, and at most seven questions. Those figures come from a sheet marked © 2020; they describe that documented product version, not an unconditional promise about a 2026 employer invitation. Check your own invitation for the language, timing, available tools, and instructions actually assigned to you.

An SHL sample candidate report displays separate results for those three dimensions. It does not publish a universal pass score or tell you how a particular employer uses the result. SHL also documents a different product called Automata, which centers on solving coding problems. Its language count, question count, and timer should not be transplanted onto Automata Fix.

Evidence boundary: I found the official product and sample-report documents, but no two independent, recent accounts that reliably establish a single current Automata Fix candidate experience. Accordingly, this guide does not claim that a particular employer uses these exact examples, that the interface has a specific button, or that a particular score passes. The debugging method is an inference from the officially named skills.

First classify the failure, then touch the code

Debugging under time pressure gets expensive when you edit before you know what failed. Start by identifying the first observable boundary: does the supplied program compile, run and return the wrong value, or work for one input while violating the stated reuse constraint? A compiler error is not proof that the algorithm is wrong. A passing sample is not proof that the boundary cases work.

Write down three facts before changing a line: the expected behavior from the prompt, the actual behavior you can reproduce, and the smallest input that preserves the difference. Then inspect the path from that input to the output. This turns a vague “the code is broken” into a falsifiable claim such as “the loop skips the final element when n = 1.”

Observed symptomFirst checkUseful confirming test
Build stops before executionCompiler line, declaration, type, delimiterCompile the smallest relevant unit after one edit
Program runs but returns the wrong valueInvariant, branch condition, index and boundaryA minimal counterexample plus a nearby passing case
Correct behavior is duplicated or inconsistently repairedExisting helper's contract and call sitesThe same input through both paths

This table is a triage aid, not an assertion that the assessment labels errors for you. Keep syntax, logic, and reuse distinct in your explanation even when one question combines them.

Syntax practice: fix the reported error without a rewrite

Consider this original Java exercise. A method should add a nonnegative bonus to a running total. The defective line is intentionally small:

static int addBonus(int total, int bonus) {
    if (bonus < 0) {
        throw new IllegalArgumentException("bonus");
    }
    return total + bonus
}

The missing semicolon prevents compilation. The minimal patch is return total + bonus;. The next step is to compile again, because the compiler may have hidden another error behind the first one. Do not claim the logic is correct solely because the syntax is fixed: run addBonus(4, 0) == 4, addBonus(4, 3) == 7, and a negative-bonus case that expects an exception. The guard is an example contract chosen for this drill, not an SHL rule.

In C or C++, the analogous triage is to read the first meaningful diagnostic, inspect the referenced statement and surrounding declarations, and patch locally. Compiler messages can point after the true cause: a missing brace on one line may make a later declaration appear invalid. Resist changing several unrelated lines at once. After each patch, compile again and compare the new diagnostic with the previous one. That preserves causal information.

Logic practice: an off-by-one defect that survives a happy path

Now assume an integer array must be summed. The following original Java exercise compiles and may look plausible in a hurried review:

static int sum(int[] values) {
    int result = 0;
    for (int i = 0; i < values.length - 1; i++) {
        result += values[i];
    }
    return result;
}

For [3, 5, 8], the method returns 8 instead of 16. More revealingly, for [7] it returns 0, and for an empty array it also returns 0. The one-element case separates the defect from general arithmetic noise: the loop condition excludes the final index. Change i < values.length - 1 to i < values.length, then rerun zero-, one-, and multi-element cases. Include negative values such as [-2, 4] so a coincidental positive-only assumption does not mask another bug.

The invariant is “before iteration i, result is the sum of elements at indexes 0 through i - 1.” With the repaired bound, the invariant yields the required full sum at i == values.length. An interviewer may ask you to explain why the patch is correct; the invariant gives a stronger answer than “the tests turned green.” It also exposes why modifying initialization or adding the last element after the loop would be a needlessly fragile workaround.

Code-reuse practice: repair the shared behavior once

The fact sheet's Code Reuse dimension is easy to overinterpret. It confirms that reuse is measured; it does not publish a universal rule that every answer must extract a new helper. The safer practice is to inspect the existing contract and ask whether two paths should call the same already-correct behavior. Here is a deliberately small original scenario: an application parses a percentage in both an invoice path and a refund path. parseRate already trims whitespace and rejects values outside 0..100. One path calls it; the other duplicates Integer.parseInt(raw).

The duplicate branch appears to work for "20" but handles " 20 " differently and may accept "120" until a later calculation fails. A disciplined patch replaces the duplicate parse with parseRate(raw) after verifying that refunds use the same domain rule. If refunds legally permit a negative adjustment, reusing the helper unchanged would be wrong; first clarify the contract. The question is whether shared semantics exist, not whether a helper can be forced into every branch.

Test "20", " 20 ", "0", "100", and "120" through both call sites. A green test through only the invoice path cannot establish that the refund path changed. This call-site matrix is the key reuse asset: it catches the case where a correct helper exists but an old path still bypasses it. Finally inspect the diff to ensure there is one source of parsing behavior and no accidental change to unrelated computation.

A reproducible repair loop for a timed session

The 2020 fact sheet's allowed-time entry makes time management relevant, but it does not justify inventing a fixed number of minutes per task for your invitation. Work in a sequence that produces evidence quickly. Read the full function signature and expected return value. Reproduce the failure with the provided tests or a permitted local input. Classify compilation versus behavior versus reuse. Change the smallest causal line or call site. Re-run the failing case, a neighboring case, and a boundary case. Then review the final diff.

If several failures appear, use the first one that is independently reproducible. A syntax error may block every behavioral test; solve it first. A shared helper defect may affect multiple callers, so test all relevant paths after one fix. If a proposed change removes a guard or changes the function signature, ask whether it violates the exercise's contract before assuming that a passing visible test proves safety.

Keep your explanation concise: “Input [7] should return 7, but the loop executes zero times because the bound is length - 1; I changed it to length and checked empty, singleton, and multi-element arrays.” That statement contains a reproduction, cause, patch, and regression check. It shows reasoning without pretending to know hidden tests.

What to do when visible tests pass but confidence is low

Passing visible cases closes the specific failures you saw; it does not establish correctness over every permitted input. Derive extra tests from the contract rather than guessing hidden cases. For loops, try empty, singleton, last-index, duplicate, and negative-value inputs as appropriate. For parsing, try whitespace, null, min and max accepted values, and one value just outside the range. For code reuse, send the same representative input through every call site that is supposed to share behavior.

Do not append broad defensive behavior the prompt never requested. For example, silently treating null as an empty array may hide a contract violation if the intended behavior is an exception. Explain the assumption instead. If the assessment interface limits custom runs, reason from invariants and available diagnostics; SHL's general Automata support article discusses candidate controls for Automata broadly, but its statements should not be treated as universal current Automata Fix controls.

Before you start the actual invitation

Read the assessment name and instructions in your own invitation, including language, time limit, input method, submission rules, and permitted aids. If a rule is ambiguous, use SHL's candidate support or the hiring team rather than advice about a different Automata product. Do your preparation on original examples and public practice material; do not use unauthorized assistance during a live assessment.

For a final rehearsal, give yourself one small defect in each of the three documented categories and keep a short repair log: failing input, actual output or diagnostic, expected result, one-line hypothesis, patch, and regression result. The log forces a distinction between “I changed something” and “I demonstrated that the change solves the stated problem.”

The core skill is controlled debugging. Confirm which Automata product you were assigned, reproduce a concrete defect, and show why a small repair survives an adjacent case.

Sources and further reading