Skip to content

Improve test automation - #871

Open
forsyth2 wants to merge 34 commits into
mainfrom
issue-869-improve-test-automation
Open

forsyth2 wants to merge 34 commits into
mainfrom
issue-869-improve-test-automation

Conversation

@forsyth2

Copy link
Copy Markdown
Collaborator

Summary

Improve test automation by updating the test automation script tests/main_branch_testing/run_integration_test.bash to:

  1. Write the Markdown report.
  2. When producing results, include an environment description for each task. For example, global_time_series/env_description.txt would include the commit hash of zppy-interfaces it was using, and a printout of the conda environment package versions.
  3. Run the tests of the tests (e.g., tests/images/test_image_checker.py, tests/images/test_image_severity.py)
  4. Auto-launch the image checker test rather than having that be a manual step.

Additionally, updates docs/source/dev_guide/tests/automated_test.rst to explain how to auto-launch this test script via a weekly cron job.

Issue resolution:

Select one: This pull request is...

  • a bug fix: increment the patch version
  • a small improvement: increment the minor version
  • a new feature: increment the minor version
  • an incompatible (non-backwards compatible) API change: increment the major version

Big Change

  • To merge, I will use "Create a merge commit". That is, this change is large enough to require multiple units of work (i.e., it should be multiple commits).

1. Does this do what we want it to do?

Required:

  • Product Management: I have confirmed with the stakeholders that the objectives above are correct and complete.
  • Testing: I have added or modified at least one "min-case" configuration file to test this change. Every objective above is represented in at least one cfg.
  • Testing: I have considered likely and/or severe edge cases and have included them in testing.

If applicable:

  • Testing: this pull request introduces an important feature or bug fix that we must test often. I have updated the weekly-test configuration files, not just a "min-case" one.
  • Testing: this pull request adds at least one new possible parameter to the cfg. I have tested using this parameter with and without any other parameter that may interact with it.

2. Are the implementation details accurate & efficient?

Required:

  • Logic: I have visually inspected the entire pull request myself.
  • Logic: I have left GitHub comments highlighting important pieces of code logic. I have had these code blocks reviewed by at least one other team member.

If applicable:

  • Dependencies: This pull request introduces a new dependency. I have discussed this requirement with at least one other team member. The dependency is noted in zppy/conda, not just an import statement.

3. Is this well documented?

Required:

  • Documentation: by looking at the docs, a new user could easily understand the functionality introduced by this pull request.

4. Is this code clean?

Required:

  • Readability: The code is as simple as possible and well-commented, such that a new team member could understand what's happening.
  • Pre-commit checks: All the pre-commits checks have passed.

If applicable:

  • Software architecture: I have discussed relevant trade-offs in design decisions with at least one other team member. It is unlikely that this pull request will increase tech debt.

@forsyth2 forsyth2 self-assigned this Sep 11, 2026
@forsyth2 forsyth2 added the Testing Files in `tests` modified label Sep 11, 2026
@forsyth2
forsyth2 requested a lite review from Copilot September 11, 2026 21:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical and moderate issues remain in image-test handling, reporting accuracy, provenance, and automation reliability.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This pull request expands integration-test automation with environment provenance, Markdown reporting, automatic image checking, and weekly cron documentation.

Changes:

  • Adds report configuration and per-task environment capture.
  • Automates image-checker execution and report generation.
  • Documents weekly cron scheduling.
File summaries
File Summary
tests/main_branch_testing/zppy_test.cfg Adds report configuration options.
tests/main_branch_testing/run_integration_test.bash Implements environment capture, reporting, and automated image checking.
docs/source/dev_guide/tests/automated_test.rst Documents reports and cron-based execution.
Review details

Suppressed comments (8)

docs/source/dev_guide/tests/automated_test.rst:91

  • The new workflow leaves tests/main_branch_testing/README.md inconsistent with this documentation: its Phase 3 section still says the script only prints instructions to run test_images.py manually, while this change launches it automatically. Please update that guide in the same change so users do not get contradictory instructions.
* Step 8: Run all Python tests, including the image checker (``pytest tests/integration/test_images.py``), which is now launched automatically on a compute node -- no manual step required.

docs/source/dev_guide/tests/automated_test.rst:337

  • The weekly driver copies the runner from $HOME/ez/zppy, but the runner itself leaves that checkout on test_zppy_<TAG> during Phase 1. On the next cron run this cp can therefore pick up the previous test branch's older runner instead of the latest main version, so automation updates to the script are not reliably adopted. Use a separate stable checkout for the driver source or explicitly update that source checkout before copying.
       cp "$HOME/ez/zppy/tests/main_branch_testing/run_integration_test.bash" .

tests/main_branch_testing/run_integration_test.bash:1208

  • The || true converts any git log error (missing upstream/<branch>, invalid date, or repository failure) into an empty result, which is then rendered as None. The report can therefore claim that there were no changes when it actually could not inspect the repository; emit an unavailable/error row instead of conflating the two cases.
    local commits
    commits=$(git -C "$repo_dir" log "upstream/${branch}" --since="${EXPECTED_RESULTS_UPDATED_DATE}" --oneline 2>/dev/null || true)

    if [[ -z "$commits" ]]; then
        report_append "| [${label}](${repo_url}/commits/${branch}) | None |"

tests/main_branch_testing/run_integration_test.bash:487

  • Every CFGS_ARRAY entry already starts with weekly_ (for example, weekly_comprehensive_v3), while the generated output root is zppy_weekly_comprehensive_v3_www. This creates zppy_weekly_weekly_comprehensive_v3_www and puts env_description.txt in a new, unused tree instead of alongside the diagnostics.
            target_dir="${OUTPUT_WORKSPACE}/zppy_weekly_${cfg}_www/${UNIQUE_ID}/${case}/${task}"

tests/main_branch_testing/run_integration_test.bash:533

  • This waits on every job owned by USER, not the submitted image-checker job. An unrelated long-running job can consume the two-hour timeout, and an early squeue snapshot can miss a newly submitted image job. Poll the submitted job's state directly and handle its terminal result.
    wait_for_slurm_jobs 120 7200

tests/main_branch_testing/run_integration_test.bash:1175

  • The generated table has eight columns, but this separator row has only four cells. Markdown renderers will treat the failing-only table as malformed; emit eight separators to match the header and data rows.
        print("| --- | --- | --- | --- |")

tests/main_branch_testing/run_integration_test.bash:1171

  • by_task preserves the first task occurrence from the cfg-major summary order, which is not sorted by task (the configured task order is e3sm_diags, mpas_analysis, global_time_series, ...). The section is explicitly titled "sorted by task", so iterate over sorted(by_task.items()) or otherwise sort the task keys before rendering.
    for task, flines in by_task.items():

tests/main_branch_testing/run_integration_test.bash:129

  • The manual Perlmutter allocation above includes a one-hour walltime, but this batch directive omits --time. The automatically submitted checker therefore uses the site's default batch limit instead of the documented limit and may be terminated before the image test completes; keep the batch request consistent with the manual allocation.
        SBATCH_DIRECTIVES=$'#SBATCH --qos=interactive\n#SBATCH --time=01:00:00\n#SBATCH --constraint=cpu\n#SBATCH --account=e3sm'
  • Files reviewed: 3/3 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/main_branch_testing/run_integration_test.bash
Comment thread tests/main_branch_testing/run_integration_test.bash
Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
Comment thread tests/main_branch_testing/run_integration_test.bash Outdated

Copilot AI commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

🟡 Changes recommended

Critical and moderate issues remain in image-test handling, reporting accuracy, provenance, and automation reliability....

Addressed in 2d55a48.

@forsyth2 forsyth2 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a high-level read-through.

Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
@forsyth2

Copy link
Copy Markdown
Collaborator Author

Remaining action items:

  • On next test run for weekly testing, use this branch and confirm it behaves as expected.
  • If so, try running via a cron job. (The branch may need to be merged to main first).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate issues affect environment capture, portability, report accuracy, and automated result status.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (7)

tests/integration/image_summary_report.py:53

  • The real image-check summary rows are keyed like comprehensive_v2_e3sm_diags (image_checker.py builds <cfg>_<task>), so this split treats the entire string as one token and never matches e3sm_diags or global_time_series. As a result, every failing row is grouped under other in the generated report; match the task suffix as well.
    tokens = {token for token in re.split(r"[^A-Za-z0-9_]+", name) if token}
    for task in tasks:
        if task in tokens:

tests/main_branch_testing/run_integration_test.bash:607

  • run_image_checker is called as the condition of if ! run_image_checker, so Bash's errexit is suppressed inside the function. If sbatch fails, this assignment leaves an empty job ID and the function proceeds to poll that ID for up to two hours instead of reporting submission failure. Check the submission status explicitly before waiting.
    IMAGE_CHECKER_JOB_ID=$(sbatch --parsable "$IMAGE_CHECKER_SBATCH")
    log "Image checker job submitted: ${IMAGE_CHECKER_JOB_ID}"

tests/main_branch_testing/run_integration_test.bash:600

  • These lines bypass the machine-specific initialization used elsewhere in this script (source ~/.bashrc plus CONDA_ACTIVATION_CMD). On Compy/Perlmutter, or any setup where CONDA_PROFILE is not the active installation, the batch job can fail at conda activate, so the automatic image check is not portable across the supported machines. Initialize the batch shell with the same sequence before activating ZPPY_ENV.
source ${CONDA_PROFILE}
conda activate ${ZPPY_ENV}

tests/main_branch_testing/run_integration_test.bash:631

  • test_images.py writes early_test_images_summary.md before re-raising a worker exception (see tests/integration/test_images.py:294-305), but this path only checks the final summary filename. When a worker fails, the generated report loses the partial table and only says the summary is missing; please fall back to the early summary (and clear any stale early file before submission) while retaining the failed status.
    if [[ -f "${ZPPY_DIR}/test_images_summary.md" ]]; then
        cp "${ZPPY_DIR}/test_images_summary.md" "${SCRIPT_RUN_DIR}/test_images_summary_${TAG}.md"
        log_success "Copied test_images_summary.md -> ${SCRIPT_RUN_DIR}/test_images_summary_${TAG}.md"
    else
        log_warning "test_images_summary.md not found in ${ZPPY_DIR}"

tests/main_branch_testing/run_integration_test.bash:1175

  • These bullets are unconditional and do not record any result: the integration invocations above discard exit codes with || log_warning, and the unit/status outcomes are not stored here. A passing and failing run therefore produce the same automated-results section, which makes the generated report insufficient for unattended review. Capture the outcomes and render the actual pass/fail status (or failure details) in this section.
    report_append "* zppy-interfaces unit tests: see script log for \`Running zppy-interfaces unit tests...\` / \`zppy-interfaces unit tests passed\`"
    report_append "* zppy unit tests: see script log for \`Running zppy unit tests...\` / \`zppy unit tests passed\`"
    report_append "* Image-checker/report unit tests (tests of the tests): \`tests/images/test_image_checker.py\`, \`tests/images/test_image_severity.py\`, \`tests/test_image_summary_report.py\`"
    report_append "* Output directory status files: checked automatically; see \`Checking all status files...\` in the script log"
    report_append "* Integration tests run: \`test_last_year.py\`, \`test_bash_generation.py\`, \`test_campaign.py\`, \`test_defaults.py\`, \`test_bundles.py\`"

tests/main_branch_testing/run_integration_test.bash:499

  • The generated cfgs place diagnostics under the machine's user_www root (for example, /lcrc/group/e3sm/public_html/diagnostic_output/$USER/...), while OUTPUT_WORKSPACE is the separate job-output root. This creates env_description.txt under a new .../$USER/zppy_*_www tree instead of alongside the diagnostics that test_images.py reads, so the promised per-task files are not visible with the results. Derive this target from the same web root used by the generated cfgs.
            target_dir="${OUTPUT_WORKSPACE}/zppy_${cfg#test_}_www/${UNIQUE_ID}/${case}/${task}"
            mkdir -p "$target_dir" 2>/dev/null || {
                log_warning "Could not create ${target_dir}; skipping env description for ${cfg}/${task}"
                continue
            }
            cp "$desc_file" "${target_dir}/env_description.txt"

tests/main_branch_testing/run_integration_test.bash:600

  • When Phase 3 is resumed directly with ZPPY_EXISTING_ENV set, the override at lines 820-822 is never executed, so ZPPY_ENV still has the auto-generated name. The new batch job then tries to activate a nonexistent environment instead of the configured existing one; use the existing-env fallback when generating this command.
conda activate ${ZPPY_ENV}
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
.. code-block::

Running zppy unit tests...
Running tests of the image checker itself...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the docs in 633ed2b so this section now matches the script output more precisely.

Comment thread tests/main_branch_testing/run_integration_test.bash Outdated

Copilot AI commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

🟡 Changes recommended

Unresolved critical and moderate issues affect environment capture, portability, report accuracy, and automated result status....

Addressed in f346516.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

I have used this branch to run yesterday's weekly test (9/15 test run. I've identified several edits to make to the test script, which I outlined in that post.

@forsyth2

forsyth2 commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

The second-to-last commit, fb2babb, addresses my comments here.

The last commit, 5c20e89 addresses my comments here.

@forsyth2
forsyth2 requested a lite review from Copilot September 16, 2026 19:13
Copilot AI and others added 29 commits October 1, 2026 16:40
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
The refactor that extracted `init_conda_base()` moved `set -u`
re-enablement to *before* `conda activate`, `source "${UNIFIED_ENV_CMD}"`,
and the SLURM image-checker's inline conda init — instead of *after*, as
it was previously.

This causes activation scripts that reference unset variables without
defaults (e.g. `cartopy_offline_data-activate.sh`'s `CARTOPY_DATA_DIR`)
to abort with "unbound variable" errors.

Restore `set -u` to fire only after environment activation completes in:

- `activate_env`
- `activate_unified_env`
- the image-checker SBATCH heredoc in `run_image_checker`

Generated with Claude
Fixes errors noted in 9/15 test.
Most of this commit was generated by Claude.
Co-authored-by: forsyth2 <30700190+forsyth2@users.noreply.github.com>
…ate tracking

- Split ZI_EXPECTED_RESULTS_DATE into
  ZI_GLOBAL_TIME_SERIES_EXPECTED_RESULTS_DATE and
  ZI_PCMDI_DIAGS_EXPECTED_RESULTS_DATE. zppy-interfaces bundles two
  tasks that get refreshed independently (e.g. global_time_series on
  8/14 vs. pcmdi_diags on 9/14), so a single date masked whichever
  task was staler. The Step 2 report table now shows these as two
  separate rows, each with its own "Since" date and commit list.

- Rename E3SM_TO_CMIP_EXPECTED_RESULTS_DATE ->
  E3SM_TO_CMIP_LAST_TESTED_DATE and ZPPY_EXPECTED_RESULTS_DATE ->
  ZPPY_LAST_TESTED_DATE. These two dependencies produce no per-task
  output directory, so there's no "expected results" to track for
  them -- only whether anything has changed since the last time each
  was tested. The new name reflects that; detection/fallback behavior
  (earliest production date across all tasks) is unchanged.

- Updated run_integration_test.bash (variable defaults, auto-detection,
  warning messages, and Markdown report generation/_report_repo_changes,
  which now takes the relevant date-variable name so its "couldn't
  determine a date" message points at the right one), zppy_test.cfg,
  and docs/source/dev_guide/tests/automated_test.rst to match.

Generated by Claude.
- Drop step numbers from report headers (out of sync with manual docs
  page); reword intro line to "See [docs page] for info on setup."
- Skip test_images_summary.md's own H1 when embedding it, so it no
  longer breaks the report's heading hierarchy
- Replace repeated per-task "_www" path notes with a single table of
  each cfg's "_www" prefix
- Show actual `grep -v "OK" *status` output for any failing output
  directory instead of just "failed"
- Include commits made on the expected-results date itself when
  reporting upstream changes (--since now anchors to that day's
  00:00:00, not a bare date)

Generated by Claude.
- check_status_files: populate STATUS_FILE_ERRORS on every failure
  path (missing directory, no *status files, or actual non-OK
  entries), not just the last one. Previously a "failed" result
  could reach the Markdown report with no explanation whenever the
  failure was due to a missing/empty output directory rather than
  an actual bad status line, forcing readers to re-run
  `grep -v "OK" "${dir}"/*status` themselves to find out why.

- Add any_bundle_cfg_configured() and use it in Phase 3 to only run
  test_bundles.py when CFGS_TO_RUN actually includes a *_bundles
  cfg. It can't meaningfully pass against jobs that were never
  submitted; it's now recorded as
  "test_bundles.py: skipped (no _bundles cfg in CFGS_TO_RUN)" and
  no longer counts as a failure for partial test runs.

- Update zppy_test.cfg and automated_test.rst comments/docs to
  reflect both changes.

Generated by Claude.
…rable

check_status_files() previously checked every hard-coded output
directory (v2, v3, bundles, and their legacy variants) unconditionally,
so the Markdown report listed "directory not found" for cfgs that were
never submitted in the first place -- e.g. weekly_comprehensive_v2 being
reported missing even though CFGS_TO_RUN didn't include it. The function
now takes an optional cfg-name argument and, via a new cfg_was_run()
helper, skips the check entirely when that cfg isn't in CFGS_TO_RUN
rather than reporting a false failure. All 12 call sites in Phase 2 and
Phase 3 now pass their matching cfg name.

Also stop hard-coding TEST_SPECIFICS["nco_path"] as "" in the generated
utils.py. It's now sourced from a new NCO_PATH cfg variable (default
empty, matching current behavior) so runs that need a specific NCO
installation can set it.

Updated zppy_test.cfg and automated_test.rst accordingly.

Generated by Claude.
wait_for_slurm_jobs previously only called scancel when every remaining
job in the queue had DependencyNeverSatisfied. In practice, a single
failed upstream job (e.g. e3sm_to_cmip) typically leaves only some
downstream jobs (e.g. pcmdi_diags) stuck in that state while other,
unrelated jobs keep running fine -- so the all-or-nothing check never
fired, and the script just polled until it hit the full max_wait timeout
(up to 4 hours) with the stuck jobs still sitting in the queue.

Now, on each poll, any job seen in DependencyNeverSatisfied is cancelled
immediately by job ID, leaving healthy jobs untouched. Once the queue
drains, the function returns failure right away if any jobs were
cancelled along the way, instead of only failing via the max_wait
timeout path.

Also documents this fail-fast behavior in automated_test.rst.

Generated by Claude.
…g to this run

wait_for_slurm_jobs polled squeue unfiltered, so it could pick up stale
DependencyNeverSatisfied jobs left over from a prior run and misattribute
them to the current one. Worse, its call sites invoked it bare under
`set -e`, so any cancellation killed the whole script before phase 2/3 ever
ran, even when the current run had actually finished fine.

- Scope wait_for_slurm_jobs to only the job IDs a phase just submitted
  (snapshot before/after submission, diff, pass into squeue/scancel via
  `-j`), so stale jobs from earlier runs are never touched or counted.
- phase_1_setup / phase_2_bundles_part2 now check its return value instead
  of calling it bare: a cancellation sets SLURM_JOBS_INCOMPLETE=true and
  logs a warning, but the run continues so phase 3 can report on whatever
  actually completed. Genuine timeouts (jobs still running) still exit
  directly, since resuming later is the right call there.
- Surface SLURM_JOBS_INCOMPLETE in phase 3's logs and as a new section in
  the generated Markdown report.
- phase_3_validation now records pass/fail in a global (PHASE3_OVERALL_OK)
  instead of via its own return code, so main() always prints "Integration
  test automation complete!" and writes the report before exiting 1 on
  failure -- rather than set -e killing the script at that point.
- Update automated_test.rst to match.

Generated by Claude.
…DA_INSTALL_LINE

Previously, ensure_test_branch() always ran for every dependency
(e3sm_to_cmip, e3sm_diags, MPAS-Analysis, zppy-interfaces, zppy),
even when a *_EXISTING_ENV override was set. If that env was built
against a local branch that was never pushed to GitHub, a later run
with a fresh TAG would try to fetch/create a new test branch from
upstream and fail -- or switch away from the very branch the existing
env was built against.

*_EXISTING_ENV was also only honored when the matching *_ENV_TYPE was
"dev", so setting an existing env while ENV_TYPE was "unified" silently
fell back to the unified env instead.

Changes:
- ensure_test_branch() now takes an optional existing_env arg and
  returns immediately (no fetch/checkout) when it's set.
- Each dependency's env-selection logic now checks *_EXISTING_ENV
  first, independent of *_ENV_TYPE: an existing env always wins, since
  _ENV_TYPE only matters for deciding how to build an env in the first
  place.
- get_env_cmd() now keys off env-name presence instead of env_type, so
  config generation picks the right activation command for an existing
  env even when _ENV_TYPE isn't "dev".
- All 9 call sites of ensure_test_branch (per-dependency setup, config
  generation, phase_2, phase_3) updated accordingly.

Also add optional *_CONDA_INSTALL_LINE cfg parameters (one per
dependency) to pin/override package versions without standing up a
dedicated branch or custom env. Each is forwarded to
`conda install -n <env> <line> --yes` right after that env is
activated, whether freshly built or reused. Ignored with a warning for
a dependency using the shared unified env with no existing env set.

Updates zppy_test.cfg and automated_test.rst to document both changes.

Generated by Claude.
The v2 and bundles legacy cfgs differ from the current cfgs
only in a trivial manner. We can therefore delete them,
keeping the legacy cfgs only for v3.
When the package(s) being changed by CONDA_INSTALL_LINE ship
activate.d/deactivate.d hooks (e.g. geometric_features), `conda install`
reactivates the currently active env in-place -- sourcing those hooks in
the same shell. The hooks assume nounset is off (they reference
conda-internal variables like _CONDA_SET_GEOMETRIC_DATA_DIR with no
default), so under this script's `set -u` they abort with "unbound
variable" right after the install itself succeeds.

init_conda_base/activate_env already disable nounset around `conda
activate` for the same reason; apply_conda_install_line needs the same
guard around `conda install`.

Generated by Claude.
@forsyth2
forsyth2 force-pushed the issue-869-improve-test-automation branch from c7dbac3 to 107f7d0 Compare October 1, 2026 21:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Testing Files in `tests` modified

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Automate execution of complete run test

3 participants