Should I test that?

Should I test generated code?

Verdict

No

Do not write tests for code that a widely used generator produces from a schema or annotations; test the code that calls the generated classes, and check the schema that feeds the generator in CI.

Why

Do not write tests for generated code; test the code that calls it. For the typical case, protobuf stubs, an OpenAPI client or Lombok accessors that the build regenerates, Blast radius is users and Change frequency is rarely, because the classes carry data for user features and change only with the schema or the generator version. Detectability is immediately: a changed signature fails the compiler at every call site, and a broken client fails the tests of its callers in CI. Reversibility is trivial because a revert regenerates the old code, and Test cost is moderate because each regeneration rewrites what the tests assert, so rule R8 gives Do not test.

When the decision changes
WhenDecisionWhy
Your team maintains the generator or its templates, such as a custom OpenAPI Generator templateTest the generator with golden-file tests of its output for sample schemasChange frequency rises to regularly, Detectability to eventually and Reversibility to with-effort: a template bug writes plausible wrong code into every generated file
Developers edit the generated files by hand after the first generationTest each edited method as hand-written codeDetectability moves to eventually and Test cost to trivial: a hand edit can store a plausible value in the wrong field
Installed mobile apps or services on older versions read the messages that the generated code writesTest minimally: one CI check that compares the schema with the last released versionDetectability moves to eventually and Reversibility to with-effort: only clients on old versions misread a renumbered field
Spring Data or another ORM generates queries from method names that you writeTest: one database test per declared query methodChange frequency rises to regularly, Detectability to eventually and Reversibility to with-effort: a method named with Or in place of And returns plausible wrong rows
A generated client, built from a payment provider's OpenAPI schema, sends the amounts that the provider chargesTest mandatory: assert the exact request body for amounts such as 0.10 and 19.99Blast radius rises to money, Detectability to eventually and Reversibility to costly: a wrong charge is refunded by hand

What breaks if you don't test

Generated code without tests of its own breaks nothing that the build misses, because your own tests run through it. The failures that reach users sit at the input of the generator, such as a schema change that the compiler accepts. A renumbered protobuf field compiles on both sides of the repository, while apps already installed on phones show the building name in the city line, and users report wrong addresses days later.

What you lose if you over-test

On a schema with 80 objects, a test per generated model class means 80 test files that repeat the schema. A generator upgrade that renames a getter breaks all of them at once, and none of them fails for a reason the compiler misses. These tests also lift coverage over code that nobody on the team wrote, which hides hand-written code without tests.

What to do instead

Test the code that calls the generated classes in its own unit and integration tests, using the generated types as they are. Pin the generator version and upgrade it in its own change, so review sees the output diff. If the generated files are committed, let CI regenerate them and fail on git diff --exit-code. Exclude generated classes from coverage: JaCoCo 0.8.3 and later skips code annotated with an annotation whose name contains Generated, as its change log records. For protobuf schemas that older clients read, keep field numbers fixed, as the protobuf language guide requires, and run buf breaking against the last release.

When the answer changes

  • Someone edits the generated files by hand, or your team owns the generator templates.
  • The input to the generator carries logic, such as query method names or a grammar.
  • Clients that you cannot update read what the generated code writes, or it carries money.

Code example

The field number that moved

Here the generated classes are correct and the schema change is the bug:

// v1: the version that installed apps were built with
message Address {
  string street = 1;
  string city = 2;
  string postcode = 3;
}

// v2: a teammate adds a field and renumbers the rest in order
message Address {
  string street = 1;
  string building = 2;
  string city = 3;
  string postcode = 4;
}

The server and the app in the repository regenerate from v2, so every class compiles and every test passes. An app on v1 decodes by field number: it reads the building as the city and the city as the postcode, and ignores field 4. Nothing crashes, and a test of the generated Address class compares v2 with v2. The FIELD_SAME_NAME rule of buf breaking fails the build when a field number changes its name. The fix is string building = 4; with the old numbers left alone.

FAQ

Should one test generated code?

No, code that a widely used generator produces needs no tests of its own; test the code that calls it and check the schema that feeds the generator. A generator that your team maintains is the exception and gets golden-file tests.

Should I unit test generated Java code?

No, generated Java classes such as protobuf messages, JAXB bindings or Lombok accessors need no unit tests of their own. Unit test the classes that use them.

Should generated code count toward code coverage?

No, generated code should not count toward coverage, because tests over it raise the number without checking code that the team wrote. Exclude the generated package in the coverage settings.

Should I test my own code generator?

Yes, test a code generator that your team maintains: feed it sample schemas, compare the output with committed expected files, and compile that output in the same build. One test of the generator covers every file it writes.