> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qlty.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Running Tests in Docker

When running tests inside Docker containers, you need to extract coverage data from the container to upload it to Qlty. This guide covers two common approaches: using volume mounts and using `docker cp`.

## Method 1: Volume Mounting

Volume mounting is the simplest approach where you mount your project directory into the container, allowing coverage files to be written directly to your host filesystem.

### GitHub Actions Example

```yaml lines theme={"system"}
name: Main
on:
    push:
        branches: [main]
    pull_request:

permissions:
    contents: read
    id-token: write

jobs:
    test:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout repo
              uses: actions/checkout@v4

            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3

            - name: Build Docker image
              run: docker build -t myapp-test .

            - name: Run tests in Docker
              run: |
                  docker run --rm \
                    -v "$(pwd)":/app \
                    -w /app \
                    myapp-test \
                    npm test -- --coverage

            - name: Check coverage file exists
              run: test -f coverage/lcov.info

            - name: Upload coverage to Qlty
              uses: qltysh/qlty-action/coverage@v2
              with:
                  oidc: true
                  files: coverage/lcov.info
```

### Key Points for Volume Mounting

* Mount your current directory (`$(pwd)`) to the container's working directory
* Use `--rm` to automatically remove the container after tests complete
* Coverage files are written directly to your host filesystem
* Works with any coverage format supported by Qlty

## Method 2: Docker Copy

When you can't use volume mounts (due to security restrictions or container design), you can copy coverage files out of the container after tests complete.

### GitHub Actions Example

```yaml lines theme={"system"}
name: Main
on:
    push:
        branches: [main]
    pull_request:

permissions:
    contents: read
    id-token: write

jobs:
    test:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout repo
              uses: actions/checkout@v4

            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3

            - name: Build Docker image
              run: docker build -t myapp-test .

            - name: Run tests in Docker (retain container)
              run: |
                  docker run --name test-container \
                    -w /app \
                    myapp-test \
                    npm test -- --coverage

            - name: Copy coverage files out of container
              run: |
                  docker cp test-container:/app/coverage/lcov.info coverage.lcov

            - name: Cleanup container
              run: docker rm test-container

            - name: Check coverage file exists
              run: test -f coverage.lcov

            - name: Upload coverage to Qlty
              uses: qltysh/qlty-action/coverage@v2
              with:
                  oidc: true
                  files: coverage.lcov
```

### Key Points for Docker Copy

* Don't use `--rm` flag so the container persists after tests
* Use `--name` to give the container a predictable name
* Copy files using `docker cp container_name:/path/to/file destination`
* Clean up the container manually after copying files

## Alternative CI Providers

### Using Coverage Tokens

If you're not using GitHub Actions with OIDC, replace the upload step with a coverage token:

```yaml lines theme={"system"}
- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
      files: coverage/lcov.info
```

### Manual CLI Upload

For other CI providers, install the Qlty CLI and upload manually:

```bash lines theme={"system"}
# After extracting coverage files from Docker
curl https://qlty.sh | sh
qlty coverage publish coverage/lcov.info
```

For some CI providers you may have to add `--override-commit-sha` and `--override-branch` flags with commit SHA and branch names.

```bash lines theme={"system"}
# After extracting coverage files from Docker
curl https://qlty.sh | sh
qlty coverage publish coverage/lcov.info --override-commit-sha <COMMIT_SHA> --override-branch <BRANCH_NAME>
```

## Multiple Coverage Files

If your Docker container generates multiple coverage files, you can upload them all:

### Volume Mount Approach

```yaml lines theme={"system"}
- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      oidc: true
      files: |
          coverage/unit.lcov
          coverage/integration.lcov
```

### Docker Copy Approach

```bash lines theme={"system"}
- name: Copy multiple coverage files
  run: |
    docker cp test-container:/app/coverage/unit.lcov unit.lcov
    docker cp test-container:/app/coverage/integration.lcov integration.lcov
```

## Path Fixing

When running tests in Docker, file paths in coverage reports might not match your repository structure. Use path fixing options:

```yaml lines theme={"system"}
- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      oidc: true
      files: coverage/lcov.info
      strip-prefix: /app/
```

Or with the CLI:

```bash lines theme={"system"}
qlty coverage publish --strip-prefix=/app/ coverage/lcov.info
```

## Troubleshooting

### Coverage File Not Found

* Ensure your test command actually generates coverage files
* Check that the coverage output directory matches your copy/mount paths
* Verify file permissions allow reading from the container

### Path Mismatches

* Use `--strip-prefix` to remove container-specific path prefixes
* Use `--add-prefix` if you need to add a path prefix
* Check that source paths in coverage reports match your repository structure

### Container Cleanup Issues

* Always clean up named containers when using `docker cp`
* Use `docker rm -f container_name` to force removal if needed
* Consider using `--rm` with volume mounts to avoid cleanup

## See Also

* [Coverage Tags](/coverage/tags) - Track different types of tests separately
* [CI Integration](/coverage/ci) - Automate coverage reporting in your CI pipeline
* [Path Fixing](/coverage/ci#path-fixing) - Fix path discrepancies in coverage reports
* [Coverage Formats](/coverage/formats) - Supported coverage file formats
