Skip to main content
Test Design5 min readQAEverest Team

We wrote the login step 340 times before we noticed

Sixty-eight test cases, five identical setup steps each. Then the button changed. Here's the fix, and the three things we got wrong on the way to it — including the one that logs your user in twice.

A checkout suite. Sixty-eight test cases. Every single one of them starts the same way:

Open the app. Click Sign in. Enter the email. Enter the password. Click Submit.

Five steps, sixty-eight times. Three hundred and forty steps that have nothing to do with checkout.

Nobody typed them three hundred and forty times, obviously. Someone wrote the first test case properly, and everyone after that copied it — which is the correct instinct, and it's what a new joiner will do on their first day too.

Then somebody renamed the button from Sign in to Log in.

You know what happens next. Sixty-eight edits for one product change that had nothing to do with any of the sixty-eight things being tested.

The cost isn't the typing

It's what those steps do to everything around them.

  • Every change to login is a suite-wide edit. New MFA screen, a cookie banner, a redirect — one product change, sixty-eight test cases to touch.
  • The test case stops being readable. Open one and the first thing you see is five lines of setup. The two steps that describe the actual behaviour are below the fold, in a file that is 70% preamble.
  • Failures point at the wrong place. A case fails at step 3. Step 3 is the password field. That tells you nothing about checkout, but it still costs someone a triage.
  • The pattern spreads. The next person copies the most recent case, including its setup. Nobody decided this; it just compounds.

The setup isn't part of the test. It's the price of admission the test has to pay before it can start.

The fix is boring, which is the point

Write the setup once, on the suite. It runs before every test case in that suite. Any single case can opt out.

That's the whole feature. Sixty-eight test cases now start at the thing they actually test, and the login flow lives in exactly one place. The button rename is one edit.

Boring features are the good ones. But three things about this one are not obvious until you build it, and they're the reason this post exists.

Trap 1: don't store it as a hidden test case

The tempting shortcut is to make the pre-steps a test case that the suite owns and the UI hides. Zero new storage, zero new plumbing, and everything that already reads test cases keeps working.

It's a trap. Every query in the product that fetches "the test cases in this suite" now has to exclude that one — and there are around thirty of them. Counts, exports, reports, run history, the picker in a scheduler, the API. Miss a single one and a customer opens their suite and sees a phantom test case they never created, or a count that's off by one, or a report with an extra row.

The failure mode isn't a crash you'd catch. It's a quiet wrongness in someone else's account, in a place you weren't looking. Prerequisite steps got their own storage instead.

Trap 2: the double login

Here's the one that will actually bite you in week one.

You add "log in" as a suite pre-step. Fine for sixty-five of the cases. But three of them log in themselves — because they're testing login, or because they need a different role.

Those three now log in twice. Sometimes that's harmless. Sometimes the second attempt lands on a dashboard rather than a login form, the step fails, and you've broken three passing tests by adding a convenience feature.

An opt-out toggle isn't enough on its own, because a toggle that defaults wrong is a toggle nobody sets. So the cases that already log in are detected and pre-unticked before you ever see the dialog — you review a decision rather than make sixty-eight of them.

The subtlety underneath: whatever rule decides "this case already logs in" has to be the *same rule* the runner uses when it decides whether to start a test case with a fresh browser session. Two similar-but-different heuristics for the same question is a bug that shows up months later, in one customer's suite, on one test case.

Trap 3: don't renumber the steps someone wrote

Injecting five steps at the top of a test case looks like it should shift every other step down by five. Step 1 becomes step 6, and so on.

Don't. Step numbers show up in reports, in bug tickets people have already filed, in screenshots, in the conversation someone had last Tuesday about "the failure at step 4". Renumbering rewrites all of that retroactively.

Pre-steps get numbers *below* the first authored step instead — they sort first and everything you wrote keeps the number it has always had. It costs one line of ordering logic and saves a category of confusion that would have been impossible to explain to a customer.

Two smaller things that mattered

Variables have to resolve. A pre-step is a real step, so `{$Customer.email}` inside one has to work exactly like it does anywhere else. That's a question of *where* the setup gets injected — before the variable resolution runs, not after it. Get the order wrong and pre-steps are the only steps in the product where dynamic data silently doesn't work.

A test case with no steps of its own must not pass. If a draft case is empty and the suite has pre-steps, running it would log in successfully and report green. A test that passes by logging in is worse than a test that doesn't run. Empty cases skip pre-steps entirely.

Where this doesn't help

If only half your suite shares the setup, the suite is the wrong container. Prerequisite steps make an honest suite better; they don't rescue a suite that's really three suites in a trenchcoat. Split it and give each one its own setup.

Re-running one step doesn't re-run the setup. When you re-run a single step to check a fix, you get that step, not five minutes of login first. That's the right default, but it does mean a single-step re-run is not a full reproduction.

And setup that genuinely differs per case still belongs in the case. Shared means identical. The moment you find yourself adding conditions to a pre-step, it isn't one.

None of this is clever. It's the thing every automation framework figured out decades ago under the name "setup" or "before hook", arriving somewhere it hadn't yet: a UI where people who don't write code build suites.

Which is worth saying plainly. If your test cases each begin with the same five lines, you don't have sixty-eight tests. You have sixty-eight copies of your login flow, and sixty-eight tests attached to them.

See it on your own stories

1000+ free credits on signup, no card required — roughly 100 test-case generations before you pay for anything.

Start free