|
| 1 | +--- |
| 2 | +title: "Running dbatools Tests Locally" |
| 3 | +date: 2026-01-24 |
| 4 | +author: "Chrissy LeMaire" |
| 5 | +slug: "testing-locally" |
| 6 | +aliases: |
| 7 | + - /testing-locally/ |
| 8 | + - /testing-locally/index.html |
| 9 | +categories: [announcements] |
| 10 | +tags: [testing, pester, contributing] |
| 11 | +draft: true |
| 12 | +--- |
| 13 | + |
| 14 | +If you're contributing to dbatools or just want to make sure your changes work before submitting a PR, running tests locally quite helpful. I've wanted to write this guide for a while because our testing infrastructure has evolved significantly, and the old docs were getting stale. |
| 15 | + |
| 16 | +Initially, our testing suite was developed with Appveyor in mind, but over the years, we've evolved to include local labs as well. Most recently, with Andreas Jordan refactored nearly 400 test files to do better with local setups and to even use scenario-based testing. |
| 17 | + |
| 18 | +Until I get VMSS + local GitHub runners working, Appveyor test runs takes about an hour and a half to run the entire testing suite, so testing locally is even more attractive now. |
| 19 | + |
| 20 | +If you're interested in testing dbatools locally, this post will get you up and running with local testing in about 15 minutes. |
| 21 | + |
| 22 | +## What Changed |
| 23 | + |
| 24 | +Instead of generic `instance1`, `instance2`, `instance3` naming, tests now use purpose-specific instance references: |
| 25 | + |
| 26 | +| Old Pattern | New Pattern | Purpose | |
| 27 | +|-------------|-------------|---------| |
| 28 | +| `$TestConfig.instance1` | `$TestConfig.InstanceSingle` | Tests needing one instance | |
| 29 | +| `$TestConfig.instance1/2` | `$TestConfig.InstanceMulti1/2` | Tests needing multiple instances | |
| 30 | +| - | `$TestConfig.InstanceCopy1/2` | Tests that copy between instances | |
| 31 | +| - | `$TestConfig.InstanceHadr` | HA/DR tests (AGs, mirroring, log shipping) | |
| 32 | +| - | `$TestConfig.InstanceRestart` | Tests that restart SQL Server | |
| 33 | + |
| 34 | +This matters because the CI can now run tests in parallel based on infrastructure requirements, and your local tests can use the same pattern. |
| 35 | + |
| 36 | +## Prerequisites |
| 37 | + |
| 38 | +Before you start, you'll need: |
| 39 | + |
| 40 | +- **PowerShell 5.1+** (Windows PowerShell) or **PowerShell 7+** |
| 41 | +- **Git** for cloning the repository |
| 42 | +- **At least one SQL Server instance** for basic tests (two for most integration tests) |
| 43 | +- **Administrator access** to your SQL instances |
| 44 | + |
| 45 | +### Run PowerShell as Administrator |
| 46 | + |
| 47 | +This is important! Many dbatools commands require local Administrator privileges. Commands like `Copy-DbaLinkedServer`, `Get-DbaService`, and anything that touches WMI will fail without it. Just right-click PowerShell and "Run as Administrator" to save yourself from cryptic permission errors 😊 |
| 48 | + |
| 49 | +## Quick Setup |
| 50 | + |
| 51 | +Navigate to your dbatools repository and run these commands: |
| 52 | + |
| 53 | +```powershell |
| 54 | +cd c:\github\dbatools |
| 55 | +
|
| 56 | +# Install dbatools.library (REQUIRED - contains SMO assemblies) |
| 57 | +Install-Module dbatools.library |
| 58 | +
|
| 59 | +# Install Pester and PSScriptAnalyzer |
| 60 | +Install-Module Pester -RequiredVersion 5.7.1 -Force -SkipPublisherCheck |
| 61 | +Install-Module PSScriptAnalyzer -RequiredVersion 1.18.2 -Force |
| 62 | +
|
| 63 | +# Copy the config template |
| 64 | +Copy-Item .\tests\constants.local.ps1.example .\tests\constants.local.ps1 |
| 65 | +``` |
| 66 | + |
| 67 | +### Configure Your Instances |
| 68 | + |
| 69 | +Edit `tests\constants.local.ps1` with your SQL Server details. Here's a simple two-instance setup: |
| 70 | + |
| 71 | +```powershell |
| 72 | +# constants.local.ps1 |
| 73 | +
|
| 74 | +# Your SQL Server instances |
| 75 | +$config['InstanceSingle'] = "YourServer\Instance1" |
| 76 | +$config['InstanceMulti1'] = "YourServer\Instance1" |
| 77 | +$config['InstanceMulti2'] = "YourServer\Instance2" |
| 78 | +$config['InstanceCopy1'] = "YourServer\Instance1" |
| 79 | +$config['InstanceCopy2'] = "YourServer\Instance2" |
| 80 | +
|
| 81 | +# SQL Authentication (or leave as $null for Windows Auth) |
| 82 | +$securePassword = ConvertTo-SecureString "YourPassword!" -AsPlainText -Force |
| 83 | +$config['SqlCred'] = New-Object PSCredential ("sa", $securePassword) |
| 84 | +
|
| 85 | +# Set defaults for all dbatools commands |
| 86 | +$config['Defaults']['*:SqlCredential'] = $config['SqlCred'] |
| 87 | +$config['Defaults']['*:SourceSqlCredential'] = $config['SqlCred'] |
| 88 | +$config['Defaults']['*:DestinationSqlCredential'] = $config['SqlCred'] |
| 89 | +``` |
| 90 | + |
| 91 | +> **Tip:** If you only have one SQL Server, just point everything to the same instance. Some multi-instance tests will skip, but you'll still be able to run most tests. |
| 92 | +
|
| 93 | +> **Remote instances?** The `$config['Temp']` path must be accessible from both your PowerShell session AND the SQL Server service accounts. Use a network share like `\\FileServer\Share\dbatools-tests`. |
| 94 | +
|
| 95 | +## Verify and Run Tests |
| 96 | + |
| 97 | +First, verify your setup: |
| 98 | + |
| 99 | +```powershell |
| 100 | +# Import the module |
| 101 | +Import-Module .\dbatools.psd1 -Force |
| 102 | +Import-Module .\dbatools.psm1 -Force |
| 103 | +
|
| 104 | +# Get test config and set defaults |
| 105 | +$TestConfig = Get-TestConfig |
| 106 | +$PSDefaultParameterValues["*:SqlCredential"] = $TestConfig.SqlCred |
| 107 | +
|
| 108 | +# Test connectivity |
| 109 | +$TestConfig.InstanceSingle | Connect-DbaInstance | Select-Object Name, Version |
| 110 | +``` |
| 111 | + |
| 112 | +If you see certificate errors, run: |
| 113 | + |
| 114 | +```powershell |
| 115 | +Set-DbatoolsConfig -FullName sql.connection.trustcert -Value $true -Register |
| 116 | +``` |
| 117 | + |
| 118 | +### Running Tests with Invoke-ManualPester |
| 119 | + |
| 120 | +The easiest way to run tests locally: |
| 121 | + |
| 122 | +```powershell |
| 123 | +# Run unit tests only (no SQL Server required) |
| 124 | +Invoke-ManualPester -Path Get-DbaDatabase |
| 125 | +
|
| 126 | +# Run integration tests (requires SQL Server) |
| 127 | +Invoke-ManualPester -Path Get-DbaDatabase -TestIntegration |
| 128 | +
|
| 129 | +# Run with code coverage |
| 130 | +Invoke-ManualPester -Path Get-DbaDatabase -TestIntegration -Coverage |
| 131 | +
|
| 132 | +# Run multiple tests matching a pattern |
| 133 | +Invoke-ManualPester -Path "*Backup*" -TestIntegration |
| 134 | +``` |
| 135 | + |
| 136 | +### Alternative: Direct Pester |
| 137 | + |
| 138 | +If you prefer running Pester directly: |
| 139 | + |
| 140 | +```powershell |
| 141 | +# Setup first |
| 142 | +Import-Module .\dbatools.psd1 -Force |
| 143 | +Import-Module .\dbatools.psm1 -Force |
| 144 | +$TestConfig = Get-TestConfig |
| 145 | +$PSDefaultParameterValues = $TestConfig.Defaults |
| 146 | +
|
| 147 | +# Run tests |
| 148 | +Invoke-Pester .\tests\Get-DbaDatabase.Tests.ps1 -Output Detailed |
| 149 | +``` |
| 150 | + |
| 151 | +## Test Scenarios |
| 152 | + |
| 153 | +Tests are organized into scenarios based on infrastructure requirements (defined in `tests\pester.groups.ps1`): |
| 154 | + |
| 155 | +| Scenario | Description | |
| 156 | +|----------|-------------| |
| 157 | +| **SINGLE** | Tests needing one instance | |
| 158 | +| **MULTI** | Tests needing multiple instances | |
| 159 | +| **COPY** | Tests that copy between instances | |
| 160 | +| **HADR** | HA/DR tests (AGs, mirroring) | |
| 161 | +| **RESTART** | Tests that restart SQL Server | |
| 162 | + |
| 163 | +The CI automatically detects which scenario each test belongs to based on which `$TestConfig` properties it uses. |
| 164 | + |
| 165 | +## CI Integration |
| 166 | + |
| 167 | +When you submit a PR, you can control which tests run using commit message patterns: |
| 168 | + |
| 169 | +```bash |
| 170 | +# Run only Get-DbaDatabase tests |
| 171 | +git commit -m "Fix database enumeration (do Get-DbaDatabase)" |
| 172 | + |
| 173 | +# Run all backup-related tests |
| 174 | +git commit -m "Update backup logic (do *Backup*)" |
| 175 | +``` |
| 176 | + |
| 177 | +For the curious, our AppVeyor builds run scenarios in parallel across multiple VMs. Check out [our AppVeyor project](https://ci.appveyor.com/project/dataplat/dbatools) to watch tests run in real-time. |
| 178 | + |
| 179 | +## Troubleshooting |
| 180 | + |
| 181 | +**"dbatools.library not found"** |
| 182 | + |
| 183 | +Reinstall it: `.\.github\scripts\install-dbatools-library.ps1 -Force` |
| 184 | + |
| 185 | +**"Cannot connect to SQL Server"** |
| 186 | + |
| 187 | +Check your instance name with `Test-DbaConnection -SqlInstance $TestConfig.InstanceSingle` and verify your credentials. |
| 188 | + |
| 189 | +**"Access denied" errors** |
| 190 | + |
| 191 | +Make sure you're running PowerShell as Administrator. This is required for WMI operations, service management, and cross-server operations. |
| 192 | + |
| 193 | +**"Access denied to temp path"** |
| 194 | + |
| 195 | +For remote instances, use a network share: `$config['Temp'] = "\\FileServer\Share\dbatools-tests"`. The SQL Server service accounts need write access. |
| 196 | + |
| 197 | +## Quick Reference |
| 198 | + |
| 199 | +```powershell |
| 200 | +# === INITIAL SETUP (one time) === |
| 201 | +.\.github\scripts\install-dbatools-library.ps1 |
| 202 | +Install-Module Pester -RequiredVersion 5.7.1 -Force -SkipPublisherCheck |
| 203 | +Copy-Item .\tests\constants.local.ps1.example .\tests\constants.local.ps1 |
| 204 | +# Edit constants.local.ps1 with your instances |
| 205 | +
|
| 206 | +# === BEFORE EACH TEST SESSION === |
| 207 | +Import-Module .\dbatools.psd1 -Force |
| 208 | +Import-Module .\dbatools.psm1 -Force |
| 209 | +$TestConfig = Get-TestConfig |
| 210 | +$PSDefaultParameterValues["*:SqlCredential"] = $TestConfig.SqlCred |
| 211 | +
|
| 212 | +# === RUN TESTS === |
| 213 | +Invoke-ManualPester -Path Get-DbaDatabase -TestIntegration |
| 214 | +``` |
| 215 | + |
| 216 | +Got questions? Hit up #dbatools on the [SQL Server Community Slack](https://aka.ms/sqlslack) and we'll help you out. |
| 217 | + |
| 218 | +\- Chrissy |
0 commit comments