﻿---
title: Where files go
description: Verified files live in one folder per test project, mirroring the test file's folder, with a folder per test class: One folder per project, not one next...
url: https://docs-v3-preview.elastic.dev/reference/layout
---

# Where files go
Verified files live in one folder per test project, mirroring the test file's folder, with a folder per test class:
```text
tests/Shop.Tests/
├── Rendering/CatalogTests.cs
└── .snapshots/
    └── Rendering/
        └── CatalogTests/
            ├── Renders.verified.html
            ├── Renders.header.verified.html         {Method}.{name}
            └── RendersPage.a1b2c3d4.verified.html   {Method}.{arguments hash}
```

- **One folder per project**, not one next to each test file: source folders hold only source, and a pull request's
  snapshot changes sit under one prefix.
- **By the test file's folder**, not its namespace. Moving a test file leaves its snapshots behind;
  `snap orphans` finds them.
- **A folder per runtime class**, so `[InheritsTests]` classes that share a base class's methods get their own files.
- **The arguments hash** (eight hex digits) tells data-driven cases apart. It is stable across machines, cultures and
  versions. A fixture injected with TUnit's `[ClassDataSource<T>]`, through the constructor or a method parameter, is
  not test data and stays out of the hash, so a class with a fixture gets plain `{Method}` names. Line endings in a string
  argument are read as `\n`, so a multi-line string from a source file hashes the same on a Windows checkout (CRLF) as on
  Linux and macOS.

A snapshot can also belong to a file rather than a test. `Snapshot.MatchFile` keys it by the file's path in the
project, without the extension, so every runner of that file shares one verified file:
```text
tests/Shop.Tests/
├── journeys/checkout.journey
└── .snapshots/
    └── journeys/
        └── checkout.verified.journey             Shop.Tests/journeys/checkout
```

Received files never go into the source tree:
```text
.artifacts/.snapshots/received/{Project}/Rendering/CatalogTests/Renders.received.html   with an artifacts path
tests/Shop.Tests/obj/snapshots/received/Rendering/CatalogTests/Renders.received.html     otherwise
```

Both are ignored in practically every .NET repository already, so a received file cannot be committed by accident.
An [inline snapshot](https://docs-v3-preview.elastic.dev/formats/inline) has no verified file: its received record is `{key}.L{line}.received.inline`, and
accepting it edits the string literal in the test's source.
Files a file-keyed run writes, such as a journey's screenshots, go into a folder next to its received file,
`{received}/journeys/checkout.artifacts/`, emptied before each run (`Snapshot.ArtifactsDirectory`).

## MSBuild properties


| Property                     | Default                                                                                   |
|------------------------------|-------------------------------------------------------------------------------------------|
| `SnapshotsDirectory`         | `$(MSBuildProjectDirectory)/.snapshots`                                                   |
| `SnapshotsReceivedDirectory` | `$(ArtifactsPath)/.snapshots/received/$(MSBuildProjectName)`, or `obj/snapshots/received` |
| `SnapshotsIncludeInProject`  | `true`: the verified files show in the IDE                                                |
| `SnapshotsTUnitAutoRegister` | `true`: the TUnit adapter registers itself                                                |

The library writes only inside these two folders: every write goes through a file system scoped to them.