Skip to content

Commit 52d8f65

Browse files
authored
chore: Update desktop integration tests to use app-runner module (#1165)
* Update desktop integration tests to use app-runner module * Fix readme * Fix crash capturing test invocation on Mac * Fix sample app * Fix null check
1 parent 27a564b commit 52d8f65

File tree

6 files changed

+107
-77
lines changed

6 files changed

+107
-77
lines changed

.github/workflows/integration-test-linux.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/sample-build/SentryPlayground.sh
3737
run: |
3838
cmake -B build -S .
39-
Invoke-Pester Integration.Tests.ps1 -CI
39+
Invoke-Pester Integration.Desktop.Tests.ps1 -CI
4040
4141
- name: Upload integration test output
4242
if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }}

.github/workflows/integration-test-windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/sample-build/SentryPlayground.exe
3838
run: |
3939
cmake -B build -S .
40-
Invoke-Pester Integration.Tests.ps1 -CI
40+
Invoke-Pester Integration.Desktop.Tests.ps1 -CI
4141
4242
- name: Upload integration test output
4343
if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }}

integration-test/Integration.Tests.ps1 renamed to integration-test/Integration.Desktop.Tests.ps1

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,50 @@
1-
# Integration tests for Sentry Unreal SDK
1+
# Integration tests for Sentry Unreal SDK on desktop platforms
2+
#
3+
# Usage:
4+
# Invoke-Pester Integration.Desktop.Tests.ps1
5+
#
26
# Requires:
37
# - Pre-built SentryPlayground application
48
# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN, SENTRY_UNREAL_TEST_APP_PATH
59

610
Set-StrictMode -Version Latest
711
$ErrorActionPreference = 'Stop'
812

9-
function script:Invoke-SentryUnrealTestApp {
10-
[CmdletBinding()]
11-
param(
12-
[Parameter(Mandatory)]
13-
[string[]]$Arguments,
14-
15-
[Parameter(Mandatory)]
16-
[string]$TestName,
17-
18-
[Parameter()]
19-
[int]$TimeoutSeconds = 300
20-
)
21-
22-
# Generate timestamp and output file paths
23-
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
24-
$stdoutFile = "$script:OutputDir/$timestamp-$TestName-stdout.log"
25-
$stderrFile = "$script:OutputDir/$timestamp-$TestName-stderr.log"
26-
$resultFile = "$script:OutputDir/$timestamp-$TestName-result.json"
27-
28-
$exitCode = -1
29-
30-
try {
31-
$process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments `
32-
-PassThru -NoNewWindow `
33-
-RedirectStandardOutput $stdoutFile `
34-
-RedirectStandardError $stderrFile
35-
36-
if ($process.WaitForExit($TimeoutSeconds * 1000)) {
37-
$exitCode = $process.ExitCode
38-
} else {
39-
Write-Host "Process timed out after $TimeoutSeconds seconds. Killing process..." -ForegroundColor Red
40-
$process.Kill($true)
41-
$exitCode = -1
13+
BeforeDiscovery {
14+
# Detect current platform and add as test target
15+
function Get-CurrentDesktopPlatform {
16+
if ($IsWindows) {
17+
return 'Windows'
18+
}
19+
elseif ($IsMacOS) {
20+
return 'MacOS'
21+
}
22+
elseif ($IsLinux) {
23+
return 'Linux'
24+
}
25+
else {
26+
return $null
4227
}
43-
} catch {
44-
Write-Host "Process execution failed: $_" -ForegroundColor Red
45-
$exitCode = -1
46-
}
47-
48-
# Read output from files to ensure we get everything that was written
49-
$stdout = @()
50-
$stderr = @()
51-
52-
if (Test-Path $stdoutFile) {
53-
$stdout = Get-Content $stdoutFile -ErrorAction SilentlyContinue
5428
}
5529

56-
if (Test-Path $stderrFile) {
57-
$stderr = Get-Content $stderrFile -ErrorAction SilentlyContinue
58-
}
30+
# Define test targets
31+
function Get-TestTarget {
32+
param(
33+
[string]$Platform,
34+
[string]$ProviderName
35+
)
5936

60-
$result = @{
61-
ExitCode = $exitCode
62-
Output = $stdout
63-
Error = $stderr
37+
return @{
38+
Platform = $Platform
39+
ProviderName = $ProviderName
40+
}
6441
}
6542

66-
# Save full output to result JSON
67-
$result | ConvertTo-Json -Depth 10 | Out-File $resultFile
68-
69-
return $result
43+
# Only test the current desktop platform
44+
$TestTargets = @()
45+
$currentPlatform = Get-CurrentDesktopPlatform
46+
$currentPlatform | Should -Not -Be $null
47+
$TestTargets += Get-TestTarget -Platform $currentPlatform -ProviderName $currentPlatform
7048
}
7149

7250
BeforeAll {
@@ -99,23 +77,37 @@ BeforeAll {
9977
throw "Environment variable SENTRY_UNREAL_TEST_APP_PATH must be set"
10078
}
10179

102-
# Connect to Sentry API
103-
Write-Host "Connecting to Sentry API..." -ForegroundColor Yellow
104-
Connect-SentryApi -DSN $script:DSN -ApiToken $script:AuthToken
105-
10680
# Validate app path
10781
if (-not (Test-Path $script:AppPath)) {
10882
throw "Application not found at: $script:AppPath"
10983
}
11084

85+
# Connect to Sentry API
86+
Write-Host "Connecting to Sentry API..." -ForegroundColor Yellow
87+
Connect-SentryApi -DSN $script:DSN -ApiToken $script:AuthToken
88+
11189
# Create output directory
11290
$script:OutputDir = "$PSScriptRoot/output"
11391
if (-not (Test-Path $script:OutputDir)) {
11492
New-Item -ItemType Directory -Path $script:OutputDir | Out-Null
11593
}
11694
}
11795

118-
Describe "Sentry Unreal Integration Tests" {
96+
Describe "Sentry Unreal Desktop Integration Tests (<Platform>)" -ForEach $TestTargets {
97+
98+
BeforeAll {
99+
# Connect to desktop device (required to create corresponding provider)
100+
Write-Host "Connecting to $Platform..." -ForegroundColor Yellow
101+
Connect-Device -Platform $Platform
102+
}
103+
104+
AfterAll {
105+
# Disconnect from desktop device
106+
Write-Host "Disconnecting from $Platform..." -ForegroundColor Yellow
107+
Disconnect-Device
108+
109+
Write-Host "Integration tests complete on $Platform" -ForegroundColor Green
110+
}
119111

120112
Context "Crash Capture Tests" {
121113
BeforeAll {
@@ -126,12 +118,19 @@ Describe "Sentry Unreal Integration Tests" {
126118

127119
# Build arguments and execute application:
128120
# -crash-capture: Triggers integration test crash scenario in the sample app
121+
# -init-only: Only initializes the app to flush captured events and quit right after
129122
# -nullrhi: Runs without graphics rendering (headless mode)
130123
# -unattended: Disables user prompts and interactive dialogs
131124
# -stdout: Ensures logs are written to stdout on Linux/Unix systems
132125
# -nosplash: Prevents splash screen and dialogs
133-
$appArgs = @('-crash-capture', '-nullrhi', '-unattended', '-stdout', '-nosplash')
134-
$script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'crash'
126+
$appArgs = @('-nullrhi', '-unattended', '-stdout', '-nosplash')
127+
$script:CrashResult = Invoke-DeviceApp -ExecutablePath $script:AppPath -Arguments ((@('-crash-capture') + $appArgs) -join ' ')
128+
129+
# On macOS, the crash is captured but not uploaded immediately (due to Cocoa’s behavior),
130+
# so we need to run the test app again to send it to Sentry
131+
if ($Platform -eq 'MacOS') {
132+
Invoke-DeviceApp -ExecutablePath $script:AppPath -Arguments ((@('-init-only') + $appArgs) -join ' ')
133+
}
135134

136135
Write-Host "Crash test executed. Exit code: $($script:CrashResult.ExitCode)" -ForegroundColor Cyan
137136

@@ -147,10 +146,12 @@ Describe "Sentry Unreal Integration Tests" {
147146
try {
148147
$script:CrashEvent = Get-SentryTestEvent -TagName 'test.crash_id' -TagValue "$crashId"
149148
Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green
150-
} catch {
149+
}
150+
catch {
151151
Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red
152152
}
153-
} else {
153+
}
154+
else {
154155
Write-Host "Warning: No event ID found in output" -ForegroundColor Yellow
155156
}
156157
}
@@ -171,7 +172,12 @@ Describe "Sentry Unreal Integration Tests" {
171172

172173
It "Should have correct event type and platform" {
173174
$script:CrashEvent.type | Should -Be 'error'
174-
$script:CrashEvent.platform | Should -Be 'native'
175+
if ($Platform -eq 'MacOS') {
176+
$script:CrashEvent.platform | Should -Be 'cocoa'
177+
}
178+
else {
179+
$script:CrashEvent.platform | Should -Be 'native'
180+
}
175181
}
176182

177183
It "Should have exception information" {
@@ -217,7 +223,7 @@ Describe "Sentry Unreal Integration Tests" {
217223
# -stdout: Ensures logs are written to stdout on Linux/Unix systems
218224
# -nosplash: Prevents splash screen and dialogs
219225
$appArgs = @('-message-capture', '-nullrhi', '-unattended', '-stdout', '-nosplash')
220-
$script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'message'
226+
$script:MessageResult = Invoke-DeviceApp -ExecutablePath $script:AppPath -Arguments ($appArgs -join ' ')
221227

222228
Write-Host "Message test executed. Exit code: $($script:MessageResult.ExitCode)" -ForegroundColor Cyan
223229

@@ -231,10 +237,12 @@ Describe "Sentry Unreal Integration Tests" {
231237
try {
232238
$script:MessageEvent = Get-SentryTestEvent -EventId $eventIds[0]
233239
Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green
234-
} catch {
240+
}
241+
catch {
235242
Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red
236243
}
237-
} else {
244+
}
245+
else {
238246
Write-Host "Warning: No event ID found in output" -ForegroundColor Yellow
239247
}
240248
}
@@ -260,7 +268,12 @@ Describe "Sentry Unreal Integration Tests" {
260268
}
261269

262270
It "Should have correct platform" {
263-
$script:MessageEvent.platform | Should -Be 'native'
271+
if ($Platform -eq 'MacOS') {
272+
$script:MessageEvent.platform | Should -Be 'cocoa'
273+
}
274+
else {
275+
$script:MessageEvent.platform | Should -Be 'native'
276+
}
264277
}
265278

266279
It "Should have message content" {
@@ -288,5 +301,6 @@ Describe "Sentry Unreal Integration Tests" {
288301
AfterAll {
289302
Write-Host "Disconnecting from Sentry API..." -ForegroundColor Yellow
290303
Disconnect-SentryApi
304+
291305
Write-Host "Integration tests complete" -ForegroundColor Green
292306
}

integration-test/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ $env:SENTRY_UNREAL_TEST_APP_PATH = "path/to/SentryPlayground.exe"
9191
9292
# Run tests
9393
cd integration-test
94-
Invoke-Pester Integration.Tests.ps1
94+
Invoke-Pester Integration.Desktop.Tests.ps1
9595
```
9696

9797
### Linux
@@ -104,7 +104,7 @@ export SENTRY_UNREAL_TEST_APP_PATH="./path/to/SentryPlayground.sh"
104104

105105
# Run tests
106106
cd integration-test
107-
pwsh -Command "Invoke-Pester Integration.Tests.ps1"
107+
pwsh -Command "Invoke-Pester Integration.Desktop.Tests.ps1"
108108
```
109109

110110
### Android
@@ -136,7 +136,7 @@ Invoke-Pester Integration.Android.Tests.ps1
136136

137137
The integration tests cover:
138138

139-
### Crash Capture Tests _(Windows/Linux)_
139+
### Crash Capture Tests
140140
- Application crashes with non-zero exit code
141141
- Event ID is captured from output (set via `test.crash_id` tag)
142142
- Crash event appears in Sentry
@@ -148,7 +148,7 @@ The integration tests cover:
148148

149149
**Note**: Crash capture tests are currently disabled on Android due to a known issue with tag persistence across app sessions.
150150

151-
### Message Capture Tests _(All platforms)_
151+
### Message Capture Tests
152152
- Application exits cleanly (exit code 0 on Windows/Linux, Android doesn't report exit codes)
153153
- Event ID is captured from output
154154
- TEST_RESULT indicates success

sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ void USentryPlaygroundGameInstance::Init()
2525
// Check for expected test parameters to decide between running integration tests
2626
// or launching the sample app with UI for manual testing
2727
if (FParse::Param(*CommandLine, TEXT("crash-capture")) ||
28-
FParse::Param(*CommandLine, TEXT("message-capture")))
28+
FParse::Param(*CommandLine, TEXT("message-capture")) ||
29+
FParse::Param(*CommandLine, TEXT("init-only")))
2930
{
3031
RunIntegrationTest(CommandLine);
3132
}
@@ -74,6 +75,10 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const FString& CommandLin
7475
{
7576
RunMessageTest();
7677
}
78+
else if (FParse::Param(*CommandLine, TEXT("init-only")))
79+
{
80+
RunInitOnly();
81+
}
7782
}
7883

7984
void USentryPlaygroundGameInstance::RunCrashTest()
@@ -116,6 +121,16 @@ void USentryPlaygroundGameInstance::RunMessageTest()
116121
CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete"));
117122
}
118123

124+
void USentryPlaygroundGameInstance::RunInitOnly()
125+
{
126+
USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem<USentrySubsystem>();
127+
128+
// Ensure events were flushed
129+
SentrySubsystem->Close();
130+
131+
CompleteTestWithResult(TEXT("init-only"), true, TEXT("Test complete"));
132+
}
133+
119134
void USentryPlaygroundGameInstance::ConfigureTestContext()
120135
{
121136
USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem<USentrySubsystem>();

sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class SENTRYPLAYGROUND_API USentryPlaygroundGameInstance : public UGameInstance
2323
void RunIntegrationTest(const FString& CommandLine);
2424
void RunCrashTest();
2525
void RunMessageTest();
26+
void RunInitOnly();
2627

2728
void ConfigureTestContext();
2829

0 commit comments

Comments
 (0)