getsentry / getsentry/sentry-dotnet
Can we run unit tests in AOT?
- Dominant language
- C#
- Stars
- 770
- Forks
- 248
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 49
Description
## Problem Statement
At the moment, the only assurance we have that Sentry is AOT compatible comes from the AOT Analysers at build time (none of which produce any warnings at the moment). Anecdotally, we're getting lots of issues related to AOT despite everything being fine from the perspective of the analysers.
This isn't super surprising, given how serialisation works in AOT. You can't possibly know, at build time, what kinds of types people will try to serialise in things like [SentryEvent.Extra](https://github.com/getsentry/sentry-dotnet/blob/bdbad695f6cfde85bda8e46a4747264e412c406b/src/Sentry/SentryEvent.cs#L174)... so there's no way to build an analyser to solve for this. When it comes to it, we won't ever be able to protect against those kinds of issues with unit tests either, but we could at least verify that all of Sentry's core functionality works when compiling AOT, using all of the types referenced by the Sentry SDK.
### Proper testing on iOS
Additionally, in order to run tests on iOS devices at the moment we have to enable the interpreter, which means we're only testing functionality on iOS simulators using Mono. This isn't how Sentry will be used the majority of time. In production, SDK users will be compiling their iOS apps AOT down to native code, which may (and very likely will) behave quite differently to how things behave in Mono on a simulator.
## Test Platform
XUnit currently relies heavily on reflection and doesn't support AOT (see [here](https://github.com/xunit/xunit/discussions/3398#discussioncomment-14376090)). So we would need to change the test framework we're using.
- [TUnit](https://tunit.dev/)
The challenge will be removing any dependencies that don't support AOT compilation because they rely on reflection.
## Mocking
We're heavily using NSubstitute in our tests at the moment for mocking. Unfortunately this uses CastleProxy and relies heavily on reflection. There are other options out there that rely on source generators, which could be used in in AOT compiled tests:
- [MockSourceGenerator ](https://github.com/hermanussen/MockSourceGenerator) looks quite nice... not sure if it would stretch to what we want to do
- [Rocks](https://github.com/JasonBock/Rocks) might be another option... although the code it generates only works for .NET 9+ so we couldn't use this to test our .NET Framework / Standard targets. AOT isn't relevant for those but it's annoying to have separate tests for those (rather than one set of tests that has multiple targets)
## Verify
We also use Verify pretty heavily across our unit tests. Currently Verify's serialisation doesn't support AOT compilation:
- https://github.com/VerifyTests/Verify/issues/1526
We might be able to work through that with Simon though.
Contributor guide
Assessment
This issue has not been assessed yet.