-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add unit tests for C# source generators #82955
Add unit tests for C# source generators #82955
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks!
I'm not sure if the sample project would still have a reason to exist once a proper testing pipeline is set up?
My idea was to replace the sample project with the tests project, so I'd remove it when we're done.
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/BaseTest.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/OutputWriter.cs
Outdated
Show resolved
Hide resolved
...les/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs
Outdated
Show resolved
Hide resolved
...les/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs
Outdated
Show resolved
Hide resolved
I see what you mean, but I think writing the huge string blocks is probably the easiest way to do it. An alternative would be to parse the output with Roslyn, but I'd say using Roslyn APIs to verify the output is more complicated and error-prone. |
Yeah, I agree. Edit: |
7028646
to
6008847
Compare
Wow, this is great 🚀 you already wrote a bunch of tests, too! Maybe in another PR we could add a "test cases" project. I've found it really useful when building source generators, in addition to a separate unit testing project. The test cases are just little examples of all the things you want the generators to run on and build successfully. The idea being you add a test case that should build without errors. I add a new one every time someone files a bug, use it to debug and fix the generator, and then leave it in to prevent regressions, etc. It can be great in a pinch, too, when there isn't time or bandwidth for unit tests. You can also write unit tests for the test case examples and ofc the unit test project won't even run if the generator fails to build or builds incorrectly. Testing the test cases also lets you verify the logic of the generated code works as expected, not just that it is present. |
6008847
to
73942ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for doing all this work, and sorry it took me so long to review it.
...mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs
Outdated
Show resolved
Hide resolved
...ono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MoreExportedFields.cs
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
Outdated
Show resolved
Hide resolved
.../mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPathAttributeGeneratorTests.cs
Outdated
Show resolved
Hide resolved
[Fact] | ||
public async void ScriptBoilerplate() | ||
{ | ||
await CSharpSourceGeneratorVerifier<ScriptSerializationGenerator>.VerifyNoCompilerDiagnostics( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel a bit hesitant to use CompilerDiagnostics.None
. Could this hide errors that we may want to test for? I guess we would also need to run the ScriptPropertiesGenerator to avoid the compiler errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm unsure too. My guess is at this point we're verifying if the generated sources match what we expect them to be. So the expected result should be error free already. But it'd probably be nice to also always run diagnostics in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, my thinking was we should verify that the generated code was also valid (i.e.: it compiles) which is something that the old SourceGenerators.Sample would check for because we're building the project in CI so if the generated code was invalid it would fail to build. If we assume the expected TestData is valid and compiles then I guess it's fine, although I feel like it makes the tests a bit less robust.
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
Outdated
Show resolved
Hide resolved
...s/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj
Outdated
Show resolved
Hide resolved
04bed2b
to
bf3caca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks! Oh, don't forget to squash the commits.
The next steps should be running the tests in CI and adding tests for the diagnostics we report.
- Bootstrap xUnit project to test source generators - Implement source generator tests - Better tests structure (put test data in cs files) - Enable `ScriptSerializationGeneratorTests` - Enable `ScriptPathAttributeGeneratorTests` - Fix `NesterClass` -> `NestedClass` - Use `Path.Combine` when dealing with paths - Copy test data to the output directory
bf3caca
to
b352bdc
Compare
Done.
Probably also make a quick pass to nuke the samples project at some point. |
Thanks! |
Following the discussions in #64899.
We want to be able to notice regressions / breaking changes in the C# source generators. The idea would be to base the tests on the current
Godot.SourceGenerators.Sample
project, eventually running them on CI whenGodot.SourceGenerators
is modified. I'm not sure if the sample project would still have a reason to exist once a proper testing pipeline is set up?Roslyn documentation on the subject can be found here and here.
Following is the current list of generators we'd want to have tests for:
ScriptMethodsGenerator
ScriptPathAttributeGenerator
ScriptPropertiesGenerator
ScriptPropertyDefValGenerator
ScriptSerializationGenerator
ScriptSignalsGenerator
The current draft is a simple proof of concept xUnit project that loads the appropriate assemblies and run a couple of (almost) empty tests against our
ScriptPropertiesGenerator
.I still need to decide on a good way to load test data and expected results, and avoid the huge string blocks. The less friction there is on writing tests, the better.
Edit 1:
Blocks of strings are probably fine, at least for now. I roughly pulled everything that was in the sample project into tests (see list above). A couple still need a bit of work to be usable.
Production edit: closes godotengine/godot-roadmap#49