Answer
Yes, shipping code that customers use without tests is unprofessional when a failure would show as a plausible wrong value: write a test for each rule the change adds, in the same pull request, and run the suite in CI.
Verdict on the code under testYes
Why
- Blast radiususers
- Change frequencyregularly
- Detectabilityeventually
- Reversibilitywith-effort
- Test costmoderate
Yes, shipping customer-facing code without tests is unprofessional when its failures look like correct output. My typical case is a product team developer who merges a new rule into a web application, such as which tasks count as overdue, with no test. Blast radius is users and Change frequency is regularly, about once a month. Detectability is eventually, because a wrong rule returns a plausible value, and Reversibility is with-effort, since statuses saved in the meantime need a repair script. Test cost is moderate, about an hour per rule, so rule R11 gives Test.
| When | Decision | Why |
|---|---|---|
| The code is a prototype that only you run, and you delete it after the experiment | Do not test the prototype: look at its output, and write tests once someone else uses the code | Blast radius falls to none, because only you run the prototype and bear a failure |
| The change computes invoice totals, discounts or refunds | Test mandatory: every amount, the rounding and the boundary values, with a second person reviewing the tests | Blast radius rises to money and Reversibility to costly, because a wrong charge ends in refunds |
| The change decides which customer account may read which records | Test mandatory: one allowed and one denied request for each role, including another account's records | Blast radius rises to safety-or-legal and Detectability to never, because a leaked record raises no error |
| The code is a one-time script that fills a new column for existing records | Test the script differently: rehearse it on a copy of production data, check the result with a query, and keep a backup | Change frequency falls to once, so a test in the suite would never run again |
| Code with no tests yet fails with an error page that users report within hours, such as a crash on an empty field | Test minimally: one test of the main path, plus a regression test for each bug users report | Detectability moves to same-day and Reversibility to trivial, because users report the crash and it stores nothing |
What breaks if you don't test
A later change adds a case for tasks in paused projects, an old branch of the rule stops matching, and CI stays green because nothing checks it. Customers see wrong overdue flags for weeks before support traces them to the change, and the next developer finds no record of what the rule was meant to do.
What you lose if you over-test
When a team counts tests as the mark of a professional, developers test getters and each call a controller makes to a mock. Those tests fail on refactors that change no behaviour, and a green suite of them checks no value a customer sees.
How to test
- Write a test for each rule the change adds, in the same pull request, with pytest or JUnit 5 and an expected value taken from the ticket.
- Run the suite on every pull request, and add a regression test with each bug fix.
- Leave controllers and mappers to endpoint tests, as the Practical Test Pyramid describes.
- When you leave a test out, write the reason in the pull request as a factor, such as "Blast radius none: only I run this script". A reviewer can check a factor; "no time" gives nothing to check.
When the answer changes
- Only you run the code, and you delete it after the experiment.
- The code runs one time, such as a data migration.
- Your team requires a test with every change: follow the team rule.
Counterexample + Real incident + Code example
The migration with twelve green tests
The common answer says a professional tests every piece of code. On a customer support product I worked on, a developer split a full_name column into first and last names with a one-time script. He spent a day on unit tests with twelve fixture names, all in the form "First Last", and every test passed. On production, 3,900 of 180,000 contacts had names like "Garcia, Maria" or a single word, and the script stored "Garcia," as a first name. Agents noticed the wrong names nine days later, and restoring them from the backup took two of us a day.
The unit tests ran once in CI and were deleted with the script. Change frequency was once, so rule R6 gives a rehearsal instead of a test. This query on a copy of production data takes a minute and counts the 3,900 rows:
SELECT count(*) FROM contacts_rehearsal
WHERE first_name LIKE '%,' OR last_name = '';
For that script, skipping the unit tests was the professional choice, and skipping the rehearsal was the unprofessional one.
Related questions
- Should developers write their own tests?Code under test: Yes
- Is unit testing worth it?Yes
- Should beginners write unit tests?Yes
- Should I use TDD?Code under test: Yes
- Should I skip tests when the deadline is tight?Code under test: Yes
FAQ
- Is not writing tests unprofessional?
Not writing tests is unprofessional for code that customers use and that fails with plausible wrong values, such as a business rule in a web application. Skipping tests is a professional decision when you can name the reason, such as a prototype only you run.
- Do professional developers write unit tests?
Yes, professional developers write unit tests for the rules in code that other people use, in the same pull request as the code. Matthias Noback argues that code added without tests has a lower chance of surviving later changes, and accepts skipping tests only for code with a short, confirmed lifespan (Is not writing tests unprofessional?).
- When is it OK not to write tests?
Skipping tests is OK when a failure affects nobody but you, or when you see the failure at once and a revert removes it. Code that runs one time needs a rehearsal on a copy of the data instead of a test.