Skip to main content

How tests map to applications

This page explains how Proofarc organizes test artifacts — API scenarios, UI tests, performance scenarios, mobile tests — and the relationship between Projects, Applications, and the Tests themselves.

If you've used Proofarc before and want to understand the model behind what you see in the UI, this is the page for you. QA, automation engineers, and anyone writing tests should read it once.

The short version

Three things you need to know:

  1. An Application is a separate, top-level thing. Not a child of a Project. The same User Service API is one canonical Application, regardless of how many Projects reference it.
  2. A Project is a grouping concept. It's the team or release context that uses one or more Applications. Projects link to Applications through memberships.
  3. A Test belongs to an Application (and currently still to a Project too, for backward compatibility). The Application link is the new, canonical relationship — it's what answers the question "what does this test cover?"

The model

┌─────────────────────────────────────────────────────────────────┐
│ Application (top-level, one canonical row per real-world app) │
│ name "User Service API" │
│ type REST_SERVICE │
│ git_url github.com/acme/user-service │
│ default_branch main │
│ jira_project UMP │
└────────────────────────────────────────────────────────────────┘
▲ ▲
│ │ application_id (NEW)
│ │
┌─────────────────┴─────────┐ ┌──┴──────────────────────┐
│ Project Application │ │ Test artifacts │
│ Membership │ │ (API Scenario, UI │
│ project_id │ │ Test, Perf Scenario, │
│ application_id │ │ Mobile Test) │
│ tracking_mode │ │ Each has its own │
│ tracked_branch │ │ application_id FK. │
└─────────────────┬─────────┘ └─────────────────────────┘


┌────────────────────┐
│ Project │
│ name │
│ branch_strategy │
└────────────────────┘

Reading the diagram

  • One Application can be referenced by many memberships and many test artifacts.
  • One Project can link to many Applications (via memberships) and contains its own grouping context.
  • A Test artifact points directly at the Application it tests.

Why this is a better model

Before

Every Project had its own copy of every Application. Three projects that wanted to test user-service meant three duplicated Application rows — each with its own git URL, its own Jira key, its own credential tag, all of which had to be kept in sync by hand. Same for tests: the same login scenario lived in each project, duplicated.

Now

One canonical Application. Many Projects link to it through memberships. Tests reference the Application directly. You can ask the platform:

  • "What tests cover user-service?"SELECT * FROM api_scenarios WHERE application_id = (...) UNION ...
  • "Which Projects own user-service?"SELECT project_id FROM project_application_memberships WHERE application_id = (...)
  • "For this release of user-service, what should we re-run?" → every test where application_id = (...), regardless of Project.

What you see in the UI

Configuration → Applications (/applications)

The top-level Application registry. Each row is one canonical Application. The Linked Projects column shows which Projects track this Application (and on which branch).

Configuration → Projects → project → Applications card

The per-project view: "which Applications does this Project track?" Adding a row here creates a project_application_memberships join row.

Test artifact detail pages

Open any API scenario, UI test, or performance scenario. There's an Application field on the page, showing the linked Application's name. It's populated:

  • Automatically when you create the test on a Project that has at least one Application linked. The platform picks the first active membership and assigns it.
  • Manually if you explicitly set applicationId on the create request, or pick a different Application in the UI dropdown (when available). An explicit override wins over the auto-pick.

If the test was created before this feature shipped, the backfill migration attached it retroactively.

The seeded example

The seeded User Management Platform project links to two Applications:

ApplicationTypeGit
User Service APIREST_SERVICEgithub.com/acme/user-service
User Service UIWEB_APPgithub.com/acme/user-service-ui

Every API scenario you create on that project auto-links to User Service API (the first active membership, by membership id ASC). Every UI test auto-links to User Service UI. To override, set applicationId explicitly.

Working with the API

Create a test that auto-picks the Application

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "List users",
"projectId": 2,
"environmentId": 1,
"baseUrl": "http://user-service:8080",
"steps": [
{"stepOrder": 1, "name": "GET /users",
"httpMethod": "GET", "endpointPath": "/api/users",
"expectedStatusCodes": [200]}
]
}' "$URL/api/scenarios" | jq '.applicationId, .applicationName'
1
"User Service API"

Create a test with an explicit Application

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Smoke against UI app",
"projectId": 2,
"applicationId": 2,
"environmentId": 1,
"baseUrl": "http://user-service-ui",
"steps": [...]
}' "$URL/api/scenarios"

The test is linked to User Service UI, not the project's first membership.

Read an existing test's Application

curl -s -H "Authorization: Bearer $TOKEN" \
"$URL/api/scenarios/49" | jq '{name, projectId, applicationId, applicationName}'
{
"name": "Platform API Coverage — health",
"projectId": 11,
"applicationId": 4,
"applicationName": "[DOGFOOD] Cloud Security Scanner Repo"
}

Backfill and orphans

When the model rolled out, every existing test on a Project with active Application memberships was retroactively linked:

EntityTests backfilled on prodTests left unlinked
API Scenarios68
UI Tests2858
Performance Scenarios30

A test is left unlinked (application_id = NULL) when its Project has no Application linked. These tests still work — they show up in project-scoped views, run normally, produce findings. They're just filtered out of Application-scoped queries until you fix the underlying issue: attach an Application to the Project.

To find your own orphans:

SELECT 'api_scenario' AS kind, id, name, project_id
FROM api_scenarios WHERE application_id IS NULL AND project_id IS NOT NULL
UNION ALL
SELECT 'ui_test', id, name, project_id
FROM ui_test WHERE application_id IS NULL AND project_id IS NOT NULL
UNION ALL
SELECT 'performance_scenario', id, name, project_id
FROM performance_scenarios WHERE application_id IS NULL AND project_id IS NOT NULL;

Or via the API:

curl -s -H "Authorization: Bearer $TOKEN" "$URL/api/scenarios" \
| jq '[.[] | select(.applicationId == null)] | length'

What about Mobile Tests?

Mobile tests inherit their Application from the Mobile App they're associated with. The Mobile App itself carries application_id — modeled as a 1:1 join (application_mobile_metadata) on top of the canonical Application row. See Applications & branch tracking for the metadata side and Mobile testing for the test side.

What about Pipelines and Scans?

Today, pipelines and security scans are still scoped to Projects, not Applications directly. This is the next phase of the refactor (Phase E). Once it lands, you'll be able to ask "what scans cover user-service?" the same way you can ask about tests today.

Common questions

Q: Can a test belong to more than one Application? No. The relationship is many tests → one Application. If two Applications need the same test, duplicate the test for now. Better test-reuse primitives are on the roadmap (workflows, Phase F).

Q: What happens to my test if I delete its Application? Deleting an Application is a soft-delete (is_active = false). Tests keep their application_id FK; they still resolve to the deleted Application but the UI marks them with a "(deleted)" badge. Restore the Application to clean it up.

Q: Can I change a test's Application after it's created? Yes — re-PUT the test with a new applicationId. The auto-link logic only runs on create, never on update.

Q: Why is the application name on a test sometimes empty? The test is an orphan — see Backfill and orphans. Link an Application to the test's Project, then re-run the backfill migration or update the test directly with applicationId.