Flaky Test Quarantine: Owners, Expiry, and Nonblocking CI Results
A confirmed flaky test can block unrelated changes without providing a dependable release signal. Removing that obstruction is reasonable only if someone still sees…
A title-validation test starts with one save workflow, then gains cases for empty input and surrounding spaces. Another test needs to save, reopen, and edit the note. Putting both changes into a larger spreadsheet can leave the automation harder to understand: some columns describe inputs, while others quietly control which actions run.
Data-driven testing reuses a procedure across input and expected-output variations. Keyword-driven testing expresses a procedure through named, reusable actions backed by implementations. Choose the representation around what changes in your tests. The two patterns can coexist, and neither removes the need for reliable setup, useful assertions, or maintained automation code.
In a data-driven design, the procedure owns the steps and a dataset supplies their parameters. Adding an input variation should not require copying the procedure. The dataset might live beside the test code or in a separate file; an external spreadsheet is not the defining feature. A versioned dataset can also be reused by compatible tests, provided its fields retain the same meaning and expected behavior.
In a keyword-driven design, a test author assembles actions such as Enter Title or Submit Draft. Each action has an interface and an implementation. The interface tells authors what arguments to supply; the implementation handles the underlying interaction. Reuse occurs when different scenarios call the same meaningful operation rather than reproducing its implementation.
These are separate design choices. pytest documents parametrization as supplying argument sets to test functions, leaving the function body to define the behavior. Robot Framework's data-driven style uses a higher-level keyword as a Test Template and supplies case names and arguments beneath it. A keyword-based workflow can therefore be data-driven too. These examples explain mechanisms, not a ranking of the frameworks.
Avoid assigning authoring ability by category. A tester can maintain reviewed data rows without changing executable steps. Someone composing existing keywords may avoid writing their implementations, but still needs to understand their contracts. New actions, unusual assertions, and broken adapters require engineering work in either design.
Consider a fictional scratch-note editor. Its deliberately narrow policy is to remove ordinary leading and trailing spaces when saving a title. Here, “space” means the U+0020 character, not every Unicode whitespace character. If nothing remains, the editor displays Title required and stores no note. Otherwise, it displays Saved and stores exactly the trimmed title.
Each case begins with an empty draft and an empty scratch store in its own isolated scope. The workflow resets that state, enters the raw title, submits once, and checks both the message and stored state. This is an unexecuted design illustration, not an observed application test, runnable framework example, or maintenance benchmark.
Case ID | Title Input | Expected Message | Expected Stored Title |
|---|---|---|---|
TITLE-plain | Release Notes | Saved | Release Notes |
TITLE-trim | One space + Release Notes + one space | Saved | Release Notes |
TITLE-empty | Empty string | Title required | No note |
TITLE-spaces | Three spaces | Title required | No note |
The input descriptions name exact string contents; the plus signs are explanatory notation, not characters to enter. No note means absence of a stored record, not a note whose title is the text “No note.” The expectations come from the declared policy. They should not be generated by calling the same title-normalization implementation being tested.
Both representations below use these same inputs, starting conditions, and expected outcomes. Changing the application behavior or relaxing the assertions would make the comparison misleading.
Separate the case definition from the machinery that drives the editor. For this example, the difference is where authors see the procedure and which interfaces they must understand. The underlying reset, entry, submission, and observation still need implementations.
A data-driven procedure accepts a case ID, raw title, expected message, and expected stored title. It establishes the empty starting state, enters the supplied string unchanged, submits, and compares the observations with the expected fields. Every row follows that sequence. TITLE-trim must reach the editor with its surrounding spaces intact, or the test cannot check the editor's trimming behavior.
An author adding another ordinary title variation edits the dataset and supplies a reviewed expectation. The procedure owner need not add another save sequence. Stable case IDs keep the variation identifiable when rows are reordered or moved between files.
The procedure can call shared helpers or a page object. Data driving does not require placing locators directly in the test, nor does it prevent reuse of action libraries. Its advantage here is a clear boundary: the procedure describes the behavior, and the rows describe variations of that behavior.
That boundary weakens when rows gain flags such as reopen, cancel, or skip validation. Those fields change the procedure rather than its input. A small number of well-defined variants can be reasonable, but a growing set of action switches makes the data file an undocumented programming language. Separate the save-and-edit workflow when its intent and steps differ.
A keyword-driven author could express the same save workflow using this conceptual action plan. These are proposed operation names and contracts, not executable syntax or a recorded trace:
For TITLE-trim, Enter Title receives the space-padded Release Notes string, while Check Result receives Saved and the unpadded Release Notes string. For TITLE-empty and TITLE-spaces, Check Result receives Title required and an explicit absent-record expectation. The action sequence stays the same.
A dispatcher resolves each operation name to its library implementation. Reset Draft owns isolation, Enter Title owns the input interaction, and Submit Draft owns submission and completion handling. Check Result belongs to the test assertion layer. A lower-level page or service adapter should expose observations rather than decide what the business result ought to be.
The library contract must distinguish text from missing values. An absent-record marker must not become the literal string “null” during file parsing. Document required arguments, accepted types, return values, preconditions, and failure behavior. Robot's syllabus, for example, qualifies typed user-keyword arguments as a feature introduced in version 7.3; do not assume identical syntax on older installations.
Existing keywords can make supported workflows easier to compose and review. They do not make an unsupported action available automatically. Before an author can add Reopen Note, someone must define its behavior, implement it, and test its success and failure paths.
A useful failure identifies both the scenario and the operation. “Save test failed” is inadequate when the same procedure runs with different inputs. pytest's parametrization examples show per-case IDs for identifying failing variations; a keyword layer should preserve that identity as execution enters its nested actions.
Suppose TITLE-trim reports Saved but the stored title still contains surrounding spaces. That hypothetical mismatch points toward persistence or normalization behavior. If the stored title is correct but the completion signal never arrives, the investigation is different. If Enter Title removed the spaces before submission, a passing result would not establish that the application met the policy at all.
Keep these failure classes distinguishable:
Record the case ID, dataset version, action or procedure location, library revision, and expected versus actual observations. Make whitespace visible in diagnostics using a quoted or escaped representation. Preserve the original exception beneath any higher-level failure message, while redacting secrets and sensitive application data.
Parameterization itself does not establish isolation. pytest explicitly warns that parameter values are passed as-is without copying; mutating a supplied list or dictionary can affect subsequent calls. Application state needs its own boundary too. A new data row must not inherit the note saved by the preceding row. Fail setup visibly rather than misreporting a contaminated starting state as a title-validation defect.
Compare the same change against both representations. Maintenance depends on which interfaces remain stable, where details are duplicated, and how many callers depend on a shared implementation. A pattern name alone cannot determine the effort.
If the title field's locator changes but its behavior does not, update the shared page adapter used by Enter Title or by the data-driven procedure. Selenium's page-object guidance separates page-specific locators and layout from test code. Either representation can use that boundary, so neither needs a copy of the locator in every case row.
The same reasoning applies to a compatible API route change hidden behind a service adapter. It stops being a local transport edit when the response shape, authorization requirements, or business behavior changes. Then observations, setup, action contracts, and expectations may all need review. Keeping a keyword name unchanged does not preserve its meaning automatically.
Do not weaken Check Result to make every affected case green after a redesign. Determine whether the requirement changed, the adapter broke, or the assertion exposed a real regression. If the trimming policy changes, review the expected values against that policy independently of the implementation repair.
Suppose saving now requires a confirmation step. In the data-driven view, amend the stable procedure and retain the case rows if their meaning remains valid. In the keyword-driven view, update the shared workflow sequence or add a confirmation action. If the action does not exist, its implementation is new work. Reordering keyword calls is a configuration edit only when the resulting sequence satisfies their preconditions.
Changing Enter Title from one text argument to separate document and title arguments affects its callers. So can renaming it, making an optional argument mandatory, changing a return value, or changing how missing values are interpreted. Validate these contracts before execution where practical, pin compatible dataset and library revisions, and provide a deliberate migration for incompatible changes.
Shared implementations reduce duplicated edits but increase the impact of a bad edit. A faulty Reset Draft can contaminate every dependent scenario; an overly permissive Check Result can conceal failures across them. Test the library operations themselves, review their callers, and rerun affected scenarios. A single passing title case does not demonstrate that a shared change is safe everywhere.
Over-abstraction has costs as well. A universal keyword accepting an action name, target, value, condition, and expected result may be harder to diagnose than a small set of meaningful operations. Conversely, one keyword per entire test merely moves duplicated procedures behind new names. Choose boundaries that have a stable purpose and more than one plausible caller.
A hybrid automation framework can keep the keyword-defined save sequence and supply the table's values to it. The workflow owns action order; the dataset owns case variations; the library owns executable actions. Robot Framework's Test Template mechanism demonstrates this combination directly. Loading an external CSV through its DataDriver library is a separate extension, not an automatic consequence of using templates.
The combination is useful when several scenarios reuse meaningful actions and each scenario also needs input variations. Keep a separate workflow for canceling or editing a saved note, while reusing suitable operations. Avoid placing arbitrary keyword names in the title-input column or silently changing the meaning of the data schema.
Versioned definitions should still produce isolated execution state. In a real system, reset must cover every relevant store and side effect, not only the visible form. For a broader treatment of those boundaries, use the test data management guide. Adding a keyword layer does not supply provisioning, cleanup, or a reliable result oracle by itself.
Start with data-driven execution when the dominant need is more input and expected-output variations of a stable workflow. Introduce a keyword layer when authors repeatedly compose the same meaningful actions across different workflows and the team can maintain their interfaces. Combine them when both needs exist, without building a custom interpreter merely to claim a hybrid design.
Before expanding the abstraction, try a bounded pilot in your own environment. Add a data row, change a locator or service adapter, introduce a new step, and deliberately trigger a failure. Review which artifacts needed editing, whether existing callers remained valid, and whether the failure identified its cause. Those observations provide a more useful basis for the decision than promises of automatic maintenance savings. Keep the simplest representation that makes the next change explicit and the resulting evidence understandable.
A confirmed flaky test can block unrelated changes without providing a dependable release signal. Removing that obstruction is reasonable only if someone still sees…
A tester reviewing a Jira issue may need a fresh smoke run without opening GitLab and choosing pipeline parameters. A manually triggered Jira Cloud…
A regression-results worker receives HTTP 429 while reading Jira issues. Sleeping that worker may be necessary, but it will not help if other workers…
Create traceable test cases, prepare release-specific test runs, and keep approved coverage current as the product changes.