Part 7 · Environment & Tests · Intermediate

Test Base Classes Hub: Stable Test APIs Across Scenarios

Hub - base_test patterns, scenario inheritance, factory policy, shared run-phase flow, test library structure, and deterministic debug checklists.

Overview

A strong base_test turns test code into a stable API: scenarios override intent, while infrastructure and safety policy remain centralized.

Keep configuration, startup, and shutdown contracts in base classes so every scenario inherits predictable behavior.

Sub-lessons in this topic

  1. base-test-pattern - minimal base_test contract for every regression.

  2. scenario-inheritance - clean child-test specialization patterns.

  3. factory-overrides-test - override policy and isolation boundaries.

  4. shared-run-phase - common orchestration with controlled extension points.

  5. test-library-organization - naming/layout conventions for scale.

  6. test-base-debug - deterministic triage for broken test hierarchies.

diagram
[TEST][UVM][ENV] base-test architecture

top.sv
  -> run_test("+UVM_TESTNAME=<scenario>")
      -> base_test::build_phase()
          -> env + cfg + factory policy
      -> child_test::configure_scenario()
          -> sequence knobs / overrides
      -> base_test::run_phase()
          -> shared objection + timeout + reporting

test class should describe scenario intent, not infrastructure plumbing
systemverilog
class base_test extends uvm_test;
  `uvm_component_utils(base_test)
  my_env env;
  env_cfg cfg;

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cfg = env_cfg::type_id::create("cfg");
    push_default_cfg();
    env = my_env::type_id::create("env", this);
  endfunction

  virtual function void configure_scenario();
    // child tests override only scenario policy.
  endfunction
endclass

Key takeaways

  • Treat base_test as a public API for all scenarios.

  • Child tests should override intent hooks, not lifecycle plumbing.

  • Centralized startup/shutdown policy reduces regression noise.

Common pitfalls

  • Copy/pasting build and run logic into every child test.

  • Allowing child tests to bypass timeout/objection policy.

  • Mixing scenario behavior with infrastructure setup.


Applied Test-Base Standards

Use a consistent review checklist before promoting new tests into nightly regressions.

Release checklist

diagram
[TEST][UVM][ENV] base-test release gate

contract:
  - base_test creates env and default cfg
  - scenario hooks are virtual and documented

policy:
  - timeout + objection handled centrally
  - plusargs mapped into cfg in one place

hygiene:
  - no direct vif access in test classes
  - no hardcoded path strings in child tests
  • Document override hooks in comments near method declarations.

  • Keep child tests less than ~100 lines when possible.

  • Move repeated sequence setup into helper methods.

systemverilog
virtual task run_phase(uvm_phase phase);
  phase.raise_objection(this, "base_test start");
  configure_scenario();
  start_main_virtual_sequence();
  wait_for_end_criteria();
  phase.drop_objection(this, "base_test done");
endtask
diagram
[TEST] ownership boundaries

base_test owns:
  - env creation
  - default cfg
  - timeout and objection policy
  - common logging/reporting

child_test owns:
  - scenario knob values
  - override selection for that scenario
  - sequence choice and constraints