{% extends "base.html" %} {% import "repo_tabs.html" as m %} {% block title %}Tests · {{ repo.owner }}/{{ repo.name }}{% endblock %} {% block tabs %}{% call m::tabs(repo, "tests") %}{% endblock %} {% block content %} {% if let Some(r) = report %}

Tests

{% if bookmarks.len() > 1 %}
{% else %}on {{ bookmark }}{% endif %} · run #{{ r.run_number }} · job {{ r.job }} ·
{% if r.broken() > 0 %}{{ r.broken() }} failing{% else %}{{ self.rate(r) }}{% endif %}
{% if r.broken() > 0 %}{{ self.rate(r) }} of {{ r.tests - r.skipped }} passed{% else %}of {{ r.tests - r.skipped }} tests passed{% endif %}
{% if runs > 1 %}
{{ rate_chart|safe }}
{% endif %}
Tests{{ r.tests }}{% if let Some(d) = self.count_delta() %} {{ self.signed(d) }}{% endif %}
Passed{{ r.passed }}
Failed{{ r.failed }}
{% if r.errors > 0 %}
Errored{{ r.errors }}
{% endif %}
Skipped{{ r.skipped }}
Test time{{ self.time(r.time_ms) }}{% if let Some(d) = self.time_delta() %} {{ d }}{% endif %}
{% if let Some(t) = first_ms %}
Reporting since
{% endif %}

This run

{% if !broke.is_empty() %}

Newly failing

{% endif %} {% if !fixed.is_empty() %}

Fixed

{% endif %}

Flaky failed and passed in the last {{ flaky_runs }} runs

{% if flaky.is_empty() %}

None: every test kept its result.

{% else %} {% for f in flaky %}{% endfor %}
{{ f.title() }}{{ f.failed }} ✕ {{ f.passed }} ✓
{% endif %}
{% if !failures.is_empty() %}

Failures {{ r.broken() }} in run #{{ r.run_number }}{% if r.broken() > failures.len() as i64 %}, the first {{ failures.len() }} shown{% endif %}

{% for f in failures %}
{% if f.status == "error" %}!{% else %}✕{% endif %} {{ f.title() }} history{% if !f.message.is_empty() %} {{ f.message }}{% endif %} {% if !f.output.is_empty() %}
{{ f.output }}
{% endif %}
{% endfor %}
{% endif %} {% if runs > 1 %}

Tests run passed failed

{{ count_chart|safe }}
{% endif %}

Slowest tests in run #{{ r.run_number }}

{% for c in slowest %}{% endfor %}
TestTime
{{ c.title() }}{% if c.status != "passed" %} {{ c.status }}{% endif %}{{ self.time(c.time_ms) }}
{% if recent.len() > 1 %}

Recent runs on {{ bookmark }}

{% for x in recent %} {% endfor %}
RunJobPassingTestsFailedTimeWhen
#{{ x.report.run_number }} {{ x.report.job }} {{ self.rate(x.report) }} {{ x.report.tests }}{% if let Some(d) = x.delta %}{% if *d != 0 %} {{ self.signed(d) }}{% endif %}{% endif %} {% if x.report.broken() > 0 %}{{ x.report.broken() }}{% else %}0{% endif %} {{ self.time(x.report.time_ms) }}
{% endif %} {% else %}

Tests of {{ bookmark }}

No test report for {{ bookmark }} yet.

Give a job in .flow/pipeline.kdl an artifact named junit holding a JUnit XML report, kept with when "always" so a failing run still sends it. For pytest:

job "test" {
    sandbox "python"
    exec "pytest" "--junitxml=/src/out/junit.xml"
    output {
        artifact "junit" {
            path "/src/out/junit.xml"
            when "always"
        }
    }
}

cargo-nextest (a junit profile), Jest's junit reporter and gotestsum write JUnit XML too.

{% endif %} {% endblock %}