diff --git a/TUnit.Core.SourceGenerator/CodeGenerators/InfrastructureGenerator.cs b/TUnit.Core.SourceGenerator/CodeGenerators/InfrastructureGenerator.cs
index bf25fae8cf..281ea2e7ba 100644
--- a/TUnit.Core.SourceGenerator/CodeGenerators/InfrastructureGenerator.cs
+++ b/TUnit.Core.SourceGenerator/CodeGenerators/InfrastructureGenerator.cs
@@ -187,8 +187,8 @@ private static bool ShouldLoadAssembly(IAssemblySymbol assembly, Compilation com
return false;
}
- // Only load assemblies with physical locations
- if (!HasPhysicalLocation(assembly, compilation))
+ // Only load assemblies that will be available at runtime
+ if (!IsLoadableAtRuntime(assembly, compilation))
{
return false;
}
@@ -223,12 +223,24 @@ private static bool IsTUnitFrameworkAssembly(IAssemblySymbol assembly)
name.StartsWith("TUnit.Assertions.", StringComparison.Ordinal);
}
- private static bool HasPhysicalLocation(IAssemblySymbol assembly, Compilation compilation)
+ ///
+ /// Determines if an assembly will be loadable at runtime via Assembly.Load().
+ /// Any assembly that has a corresponding reference in the compilation will be available
+ /// at runtime because it will either be:
+ /// - A compiled DLL in the output directory (for project references)
+ /// - A NuGet package assembly in the probing paths (for package references)
+ ///
+ private static bool IsLoadableAtRuntime(IAssemblySymbol assembly, Compilation compilation)
{
+ // Find the MetadataReference that corresponds to this assembly symbol
var correspondingReference = compilation.References.FirstOrDefault(r =>
SymbolEqualityComparer.Default.Equals(compilation.GetAssemblyOrModuleSymbol(r), assembly));
- return correspondingReference is PortableExecutableReference { FilePath: not null and not "" };
+ // If there's a corresponding reference, the assembly will be available at runtime.
+ // This includes:
+ // - PortableExecutableReference: compiled DLLs (NuGet packages, project outputs)
+ // - CompilationReference: project-to-project references (will be compiled to DLLs)
+ return correspondingReference != null;
}
private static string GetAssemblyFullName(IAssemblySymbol assemblySymbol)
diff --git a/TUnit.TestProject.Library/Hooks.cs b/TUnit.TestProject.Library/Hooks.cs
index 217d5b6d0c..1f1ace727c 100644
--- a/TUnit.TestProject.Library/Hooks.cs
+++ b/TUnit.TestProject.Library/Hooks.cs
@@ -14,3 +14,28 @@ public void AfterTests(TestContext testContext)
testContext.StateBag.Items["AfterHit"] = true;
}
}
+
+///
+/// Test session hook in a library project.
+/// This tests the fix for https://github.com/thomhurst/TUnit/issues/4583
+/// where hooks in referenced library projects don't execute.
+///
+public static class LibraryTestSessionHooks
+{
+ public static bool BeforeTestSessionWasExecuted { get; private set; }
+ public static bool AfterTestSessionWasExecuted { get; private set; }
+
+ [Before(TestSession)]
+ public static Task BeforeTestSession()
+ {
+ BeforeTestSessionWasExecuted = true;
+ return Task.CompletedTask;
+ }
+
+ [After(TestSession)]
+ public static Task AfterTestSession()
+ {
+ AfterTestSessionWasExecuted = true;
+ return Task.CompletedTask;
+ }
+}
diff --git a/TUnit.TestProject/Bugs/Issue4583/LibraryTestSessionHookTests.cs b/TUnit.TestProject/Bugs/Issue4583/LibraryTestSessionHookTests.cs
new file mode 100644
index 0000000000..5a038f838e
--- /dev/null
+++ b/TUnit.TestProject/Bugs/Issue4583/LibraryTestSessionHookTests.cs
@@ -0,0 +1,20 @@
+using TUnit.TestProject.Attributes;
+using TUnit.TestProject.Library;
+
+namespace TUnit.TestProject.Bugs.Issue4583;
+
+///
+/// Reproduction test for https://github.com/thomhurst/TUnit/issues/4583
+/// Tests that [Before(TestSession)] hooks in REFERENCED LIBRARY projects are executed.
+/// This is different from issue #4541 which tested hooks in the same project.
+///
+[EngineTest(ExpectedResult.Pass)]
+public class LibraryTestSessionHookTests
+{
+ [Test]
+ public async Task Verify_TestSession_Hook_In_Referenced_Library_Executed()
+ {
+ await Assert.That(LibraryTestSessionHooks.BeforeTestSessionWasExecuted).IsTrue()
+ .Because("[Before(TestSession)] hook in referenced library project should have executed");
+ }
+}