Test Evidence

Test evidence is the record of what you tested, on which build and environment, when, and what actually happened: screenshots, screen recordings, logs and a short note of the context. It turns "the leave request failed" into something a developer can check: the error on screen at 10:15, the request that returned status 504, and the request id that finds the matching lines in the server log.

Evidence is what you attach to the results recorded in a test run, above all to failed ones.

Why it matters

A failure that is not captured when it happens is often hard to show again: the data has changed, the environment was redeployed, or the problem was intermittent. Without evidence a report may be closed as "cannot reproduce", and a pass recorded without proof can be questioned in an audit or an acceptance sign-off.

Evidence also carries risk. A screenshot can show a customer's phone number, and a network export can contain a session cookie that lets anyone holding the file act as that user. Capturing only what is needed protects the people whose data the system holds.

What counts as evidence, and how much

Evidence is any record made during test execution that supports a test result. The ISTQB Foundation syllabus names test logs, screenshots, database dumps and recordings as material a defect report may include so that the failure can be reproduced.

Evidence needs context. A screenshot alone proves only that a screen once looked like that; with the test case, run, build, environment, account role, test data and the time with its time zone, it proves what happened in that test.

  • Failed test: enough for a developer to see the failure without asking you — actual next to expected, plus the logs from underneath.
  • Passed test: usually the recorded result is enough. Regulated work, contractual acceptance and some UAT sign-offs require proof of passes; the test plan says which tests need it and in what form.
  • Capture during execution and store the evidence with the result: evidence recreated later on another build belongs to a new test.

Screenshots and screen recordings

A screenshot is the fastest evidence of what the user saw. Capture the whole window with the address and the logged-in account visible, not a tight crop around the error; when the failure is a change, take one before and one after. Mark the problem on a copy and keep the original.

A recording shows what a screenshot cannot: order and timing. Use it for multi-step flows, flicker, slow responses and intermittent failures; keep it short and note the second the failure appears.

  • Also copy error messages as text so that they can be searched; extracting text from a screenshot with OCR is the fallback.

Try it: Image to Text

Logs: browser console, network and server

Logs show what happened beneath the screen. For a web application three logs cover most failures, and the first two are in the browser's developer tools (DevTools), opened with F12 or Ctrl+Shift+I (Cmd+Option+I on a Mac).

The web testing module teaches DevTools, and the HTTP module teaches requests, headers and status codes, in depth. For now, know that each time a page talks to the server, the browser sends a request and receives a response with a three-digit status code (2xx success, 4xx a problem with the request, 5xx a failure on the server side) and headers: named lines of extra information, such as the cookie that keeps the user logged in.

  • Console: JavaScript errors, failed resource loads and warnings. Copy the error as text with its file, line and time; turn on timestamps in the console settings if they are hidden.
  • Network panel: every request with its method, URL, status, timing, headers and bodies. Open it before the first step and turn on Preserve log (Firefox: Persist Logs) so that a page change does not clear it. Export a HAR file (HTTP Archive, a JSON format) or copy only the failing request.
  • Server logs: often out of a tester's reach. Give the developer the exact time with its time zone, since many servers log in UTC (10:14 in Riyadh, UTC+3, is 07:14 UTC), and any request id the response returned, for example in a header such as X-Request-Id (names vary). Attach the lines they find, not the whole file.

Try it: JSON Tree Viewer Try it: Timezone Converter

Privacy and security when capturing evidence

Evidence copies data into places with wider access: defect trackers, chat, email, supplier tickets. A HAR file can hold every header and body of the session, including the cookies and tokens that let anyone with the file act as that user while they remain valid. Personal data in evidence is still personal data, covered by laws such as the Saudi Personal Data Protection Law (PDPL) and by your organisation's policies.

A password, token or personal data in a log is itself a finding (the OWASP Logging Cheat Sheet says passwords, session identifiers, access tokens and sensitive personal data should not be recorded directly in logs): report it without pasting the value.

  • Use test accounts and generated data, capture the browser window rather than the whole desktop, and silence notifications before recording.
  • Mask with a solid, opaque box, not a light blur. In a PDF a box drawn on top leaves the text underneath; use real redaction.
  • In a HAR (one entry, before cleaning, is shown below), remove the values of Cookie, Set-Cookie and Authorization, the cookies arrays that repeat them, and passwords or personal data in bodies. Chrome 130 and later leave those three headers out by default (its "sanitized" export), but the bodies stay and other browsers may keep everything, so check every file. Logging out ends many sessions, but some tokens stay valid until they expire.
  • Keep evidence in the team's access-controlled tools, never in public channels, and delete it when the agreed retention period ends.
{
  "startedDateTime": "2026-09-30T07:14:52.118Z",
  "request": {
    "method": "POST",
    "url": "https://staging.example.test/api/leave-requests",
    "headers": [
      { "name": "Authorization", "value": "Bearer eyJhbGciOi..." },
      { "name": "Cookie", "value": "sid=4f9c..." }
    ],
    "cookies": [{ "name": "sid", "value": "4f9c..." }],
    "postData": {
      "mimeType": "application/json",
      "text": "{\"type\":\"annual\",\"days\":3}"
    }
  },
  "response": {
    "status": 504,
    "headers": [{ "name": "X-Request-Id", "value": "8b1f0c2e" }]
  }
}

Try it: Redact PDF Try it: Fake User Generator

Worked example: evidence for a failed leave request

A tester runs TC-LV-009, "Submit a 3-day annual leave request", in an HR portal's Sprint 42 regression run on staging, with DevTools open and Preserve log on. The tester fills the form, takes a screenshot, starts recording the browser window and clicks Submit. A spinner turns for 30 seconds, then "Request failed. Try again." appears. The tester takes a screenshot and opens My requests: the request is listed as Pending, so a user who believes the message will submit a duplicate.

The tester exports the HAR, removes the session values, copies the console error and notes the request id. With that id the developer finds the server log lines: the request was saved, then the leave service waited on a call to the approval service, and after 30 seconds the gateway in front of it stopped waiting and returned 504 (Gateway Timeout). The package attached to the run result and to DEF-1874:

Evidence package for a failed leave request: context, three screenshots, the console error, a HAR with session values removed, server log lines found by request id, and a 41-second recording.

The package attached to the run result and to DEF-1874

Part 1:DEF-1874-evidence/   TC-LV-009 · run "Sprint 42 regression" · HR portal
  00-context.txt    build 5.2.0-rc1 · staging · Chrome 129 / Windows 11
                    account qa.employee07 (employee role) · 30 Sep 10:14:52 UTC+3
  Part 2:01-form.png       the filled form before Submit: annual leave, 12-14 Oct, 3 days
  02-error.png      after 30 s: "Request failed. Try again." (boxed in red)
  03-list.png       My requests: the same request is listed as Pending
  Part 3:04-console.txt    10:15:22 Failed to load resource: the server responded
                    with a status of 504 (Gateway Timeout)
  Part 4:05-network.har    POST /api/leave-requests -> 504 after 30.0 s
                    X-Request-Id: 8b1f0c2e · Cookie, Authorization values removed
  Part 5:06-server.txt     log lines for 8b1f0c2e, provided by the developer
  Part 6:07-steps.mp4      41 s: Submit, spinner, error at 0:31, open My requests
  1. 1Context: what, where, whenTest case, run, build, environment, browser, account role and the time with its zone. Without it, nobody could match the other files to the server log.30 Sep 10:14:52 UTC+3
  2. 2Screenshots: before, error, afterWhole window, problem boxed on a copy. The third one shows the request was saved despite the error message.mask personal data
  3. 3Browser consoleThe error copied as text with its time, so it can be searched and matched to the network request.504 (Gateway Timeout)
  4. 4Network: HAR fileProves the request, the status and the 30-second wait; the request id links it to the server log.POST /api/leave-requests -> 504remove cookies and tokens
  5. 5Server log excerptFound by the developer with the request id: the request was saved, then the wait for the approval service ran past the gateway's 30 seconds. Only the relevant lines are attached.X-Request-Id: 8b1f0c2e
  6. 6Screen recordingShows order and timing: the 30-second spinner as the user lived it, which a screenshot cannot show.silence notifications

File names and numbering are one team's convention; what matters is that every file is in order, labelled and attached to the result.

  • Left out of the package: the desktop, the session values, and the earlier login request in the HAR, whose body carried the test account's password.
Text version
DEF-1874-evidence/   TC-LV-009 · run "Sprint 42 regression" · HR portal
  00-context.txt    build 5.2.0-rc1 · staging · Chrome 129 / Windows 11
                    account qa.employee07 (employee role) · 30 Sep 10:14:52 UTC+3
  01-form.png       the filled form before Submit: annual leave, 12-14 Oct, 3 days
  02-error.png      after 30 s: "Request failed. Try again." (boxed in red)
  03-list.png       My requests: the same request is listed as Pending
  04-console.txt    10:15:22 Failed to load resource: the server responded
                    with a status of 504 (Gateway Timeout)
  05-network.har    POST /api/leave-requests -> 504 after 30.0 s
                    X-Request-Id: 8b1f0c2e · Cookie, Authorization values removed
  06-server.txt     log lines for 8b1f0c2e, provided by the developer
  07-steps.mp4      41 s: Submit, spinner, error at 0:31, open My requests

Common mistakes

  • Cropping a screenshot to the error message, so nobody can tell which page, account or data it came from.
  • Attaching evidence without context: no build, environment, time zone or test data.
  • Opening DevTools only after the failure, or without Preserve log, so the failing request was never recorded.
  • Sharing a HAR, screenshot or recording that still contains tokens, cookies or personal data, in a channel or ticket that outsiders can see.
  • Capturing every passed step "just in case": it slows execution, adds data to protect, and nobody reads it.

The QA perspective

Agree the level of evidence before execution, in the test plan or the team's working agreement: what a pass and a failure need, where evidence is stored and for how long. Ask developers which logs help them and how to find a request id, and whether staging holds production data.

During execution, open DevTools with Preserve log on before steps that save data. Before attaching anything, look at it as an outsider would: does it show the failure, and anything it should not?

Practice exercise

Build a safe evidence package for a data leak

Your task

You run TC-PAY-012 on the HR portal's staging environment. The downloaded payslip shows another employee's name, employee ID and salary instead of your test account's. The names look real: staging seems to hold copied production data.

Plan the evidence package for the run result and the defect report. It must prove the failure without spreading the leaked data further.

Material
TC-PAY-012  Download the September payslip as PDF
Run:        Sprint 42 regression · staging · build 5.2.0-rc1 · Chrome 129
Account:    qa.employee07 (employee role)
Time:       30 Sep 11:02 UTC+3
Expected:   the PDF shows the name, employee ID and salary of qa.employee07
Actual:     the PDF shows another employee's name, employee ID and salary
Request:    GET /api/payslips/2026-09/pdf -> 200, Content-Type: application/pdf
Response:   X-Request-Id: 51d7a0c3
Steps
  1. Decide what proves the failure without copying the other person's data.
  2. List the files of your package, what each one shows and what you mask or remove in it.
  3. Say what you do with the downloaded PDF and whom you inform.
Show the model answer
Model answer

00-context.txt: test case, run, build, environment, browser, account role, the time with its zone and request id 51d7a0c3.

01-payslip.png: the payslip beside the portal header showing the logged-in test account, with the other person's name, employee ID and salary under solid boxes. The mismatch is the proof; you can state it without showing the data, and the developer can confirm which record was served from the request id.

02-request.txt: GET /api/payslips/2026-09/pdf, status 200 and the request id, without cookie or authorization values and without the response body, which is the leaked PDF. Server log lines only if they contain no personal data.

No recording and not the original PDF: do not attach the file anywhere. Ask the security or data protection contact whether they need it, keep it only as they instruct, then delete your copy.

Restrict the defect's visibility if the tracker allows it, tell your test lead and follow the process for a possible personal data incident. Two findings: one employee can download another's payslip, and staging holds real personal data.

Frequently asked questions

Do I need a screenshot for every passed test step?

Usually not. For most teams the result recorded in the test run is the evidence of a pass. Regulated domains, contractual acceptance and some UAT sign-offs require proof of passes, and then the test plan says which tests need it and in what form. Automated tests produce their own evidence: the report, the logs, and the screenshots or traces that many tools save when a test fails.

What is a HAR file, and is it safe to share?

A HAR (HTTP Archive) file is a JSON file exported from the browser's Network panel. It contains every recorded request and response: URLs, headers, cookies, timings and often the bodies. It is not safe to share as exported, because it can hold session cookies, access tokens, a password from a login request and personal data; Chrome 130 and later leave cookie and authorization headers out by default, but not the bodies. Remove the sensitive values first, share it only through the team's tracker, and send just the failing request when that is enough.

Should I record a video or take a screenshot?

Take a screenshot when the problem is a state: a wrong value, a broken layout, an error message. Record when the problem is the sequence or the timing: a flicker, a slow response, a multi-step flow or a failure that appears only sometimes. Often the best evidence is a short recording plus one screenshot of the key moment, so the details can be read without playing the video.

References

Practise with Mutqan tools

Extract text from photos and screenshots (JPG, PNG, WebP) with OCR in your browser — English, Arabic, Hindi; several images at once.

OCR & Text

Explore JSON as a collapsible tree with paths, types and value counts.

JSON & Data

Convert a date and time between timezones (Riyadh, Amman, Delhi, UTC, New York, London…).

Utilities

Permanently remove text and images from a PDF — draw black boxes and the redacted pages are re-rendered without the content underneath.

PDF Security & Privacy

Generate fake user records (name, username, email, password, avatar seed, role) for test accounts.

Test Data

Go deeper

Your progress on this topic

Part of the QA Roadmap