Should I test that?

Should developers write their own tests?

Answer

Yes, the developer who changes the code writes its unit and integration tests in the same pull request, with expected values taken from the ticket, and the reviewer checks those cases against the ticket, not against the code.

Verdict on the code under testYes

Why

Yes, the developer who writes the code writes its tests, and the reviewer checks the cases. My typical case is a product team developer changing a customer-facing feature, with code review and CI. Blast radius is users and Change frequency is regularly, because the feature changes monthly. Detectability is eventually, since a wrong rule returns a plausible value and raises no error, and Reversibility is with-effort, because stored results need a repair script. Test cost is moderate for the developer, who already knows how to call the code, so rule R11 gives Test.

When the decision changes
WhenDecisionWhy
The code calculates invoice totals, discounts or refundsTest mandatory: the developer writes the tests, and a second person checks every expected amount against the pricing rulesBlast radius rises to money and Reversibility to costly, because a wrong charge ends in refunds
The code decides which customer account may read which recordsTest mandatory: the developer writes a test that another account's request is denied, and a second person reviews the testsBlast radius rises to safety-or-legal and Detectability to never, because a leaked record raises no error
A developer writes a one-time script that fills a new column for existing recordsTest the script differently: the developer rehearses it on a copy of production data, and a second person reviews the resultChange frequency falls to once, so a test in the suite would never run again
A signup flow crosses three teams' services, no environment runs all three together, and a broken hand-off leaves new accounts without their first projectTest the whole flow differently: each team tests its own service, and an alert fires when fewer signups reach a first projectTest cost rises to heavy, because an end-to-end test needs all three services running together, and Detectability stays eventually, because the signup succeeds and nobody reports the missing project
The code is a prototype that only its author runsDo not test the prototype; the author looks at the result and writes tests once someone else uses the codeBlast radius falls to none, because the author alone bears a failure

What breaks if you don't test

When a developer leaves testing to a QA team, the tests arrive days after the merge and go through the user interface, where most branches of a rule are hard to reach. A later change breaks a rule that no code-level test checks, and customers find the wrong values weeks later.

What you lose if you over-test

When a tester re-checks every pull request by hand, merges wait in a queue while the tester repeats what the unit tests already prove. When a developer tests a rule in a unit test and QA tests it again end to end, one change to the rule breaks both suites.

How to test

  1. The developer writes unit tests for rules and integration tests for queries in the same pull request as the code.
  2. Expected values come from the ticket, never from the code's output. Name each test after the sentence in the ticket it checks.
  3. The reviewer reads the test names against the ticket and asks for the missing case. Google expects every change to include code and tests and reviewers to check both, as Software Engineering at Google, chapter 11 describes.
  4. A tester, if the team has one, picks cases before coding and explores flows across features instead of writing unit tests for someone else's code.

When the answer changes

  • The code moves money or decides who may see a record.
  • The failure shows only in a flow that crosses services owned by other teams.
  • Nobody but the author runs the code.

Real incident + Code example

The archive rule both halves agreed on

On a project management product I worked on, a ticket asked for a nightly job that archived projects with no activity for 90 days. The developer read "activity" as the project's updatedAt, which changes only when someone edits the project's settings; task edits live in another table. His tests used the same reading and passed. The code and tests agreed, so the reviewer approved. The first night the job archived 214 projects whose teams edited tasks every day. Customers reported it by 9 a.m., and restoring projects and answering tickets took the rest of the day. The ticket's case fails on the old code:

import { expect, it } from "vitest";
import { shouldArchive } from "./archive";

const today = new Date("2026-06-01");

// The developer's case: "activity" read as updatedAt
it("archives a project untouched for 91 days", () => {
  const project = { updatedAt: new Date("2026-03-02"), lastTaskEditAt: null };
  expect(shouldArchive(project, today)).toBe(true);
});

// The ticket's case: a task edit counts as activity
it("keeps an old project whose tasks changed yesterday", () => {
  const project = {
    updatedAt: new Date("2026-01-10"),
    lastTaskEditAt: new Date("2026-05-31"),
  };
  expect(shouldArchive(project, today)).toBe(false);
});

Since then, reviewers on that team write one case from the ticket before they open the diff.

FAQ

Should QA write unit tests?

No, QA engineers should not write unit tests for a developer's code, because a unit test must run in the same pull request as the code. QA engineers pick cases from the requirements before coding and explore flows that cross features.

Who should write tests?

The developer who writes the code should write its unit and integration tests in the same pull request. The reviewer or a tester checks the cases against the requirement, because a developer who misread it writes the same misreading into the tests.

Should a developer also act as a tester?

Yes, a developer should test their own code with automated tests and look at the result before asking for review. A separate tester adds cases the developer missed instead of repeating the developer's checks by hand.

Can developers test their own code objectively?

Developers cannot check their own reading of a requirement, because code and tests come from the same understanding. Expected values from the ticket and a reviewer who compares test names with the ticket give the requirement a second reading before the merge.