Closed richardhauer closed 2 years ago
A PS for anyone stumbling over this with the same issue. It's possible to disable execution of a test in the context of LUT while still executing it as part of a Build pipeline or in Test Explorer.
Just apply the attribute [TestCategory("SkipWhenLiveUnitTesting")]
to your test.
As you're developing an application, Live Unit Testing automatically runs any impacted unit tests in the background and presents the results and code coverage in real time.
I'm not really surprised it doesn't work, since VS needs to do coverage analysis...
We could try to hook Fody on $(TargetsTriggeredByCompilation)
to see if it works better that way (currently it is being hooked with AfterTargets="AfterCompile"
).
Fody & PropertyChanged.Fody packages need to be applied to both the library project AND the MSTest project in order for it to work through Test Explorer
That's strange... these packages shouldn't be needed in the test project. I just tested the Test Explorer on a project of mine that uses Fody and it works (I usually use Rider instead of the Test Explorer).
I can create a small github repo if it helps.
After a bit more experimentation I can remove the Fody
library from the Test project but I have to have the PropertyChanged.Fody
there. I suppose this is because even though the base class (which is in the library project) has all the references, there is a test class that's in the Test library and the transient dependency isn't sufficient. Maybe?
In terms of the hook, I could use Directory.Build.targets
to add Fody into the other target. Do you know what actions are being used? Can I locate this in the Fody repo maybe?
EDIT https://docs.microsoft.com/en-us/visualstudio/test/live-unit-testing-faq?view=vs-2019#customize-builds
The sample appears to suggest that targets that are executed on AfterBuild
should be ok. Looking at Fody.targets
it seems like there are some conditions that might disable Fody but it's a bit hard to get logging from this part of the system to see if these conditions are causing the issue.
Condition="'$(NCrunch)' != '1' And $(FodyExecutedWeavers) != '' And $(DisableFody) != true"
UPDATE
Thanks @ltrzesniewski - with your direction I have been able to get this working. Two changes were needed:
1) Create a directory.build.targets
file in the root of the solution.
2) Copy the FodyTarget
from the Fody/Fody.targets
file and make the following adjustments:
a) remove the And $(DesignTimeBuild) != true
clause from the Conditions
attribute of the <Target />
element
b) remove the DelaySign
attribute from the <Fody.WeavingTask />
element
It seems the LUT is building under the "DesignTimeBuild" flag which was preventing the execution. I am not using DelaySign
so this doesn't affect me at all.
I do not know whether there was a specific reason to exclude Fody execution during a DesignTimeBuild
condition, or if it was simply to cater to the DelaySign; if so, I imagine we can hard-wire false
on DelaySign
during DesignTimeBuild
which would enable LUT scenarios for everyone.
For now I'm satisfied with this outcome for my project.
@richardhauer
- Test library has a class that inherits from the base and implements a basic string property (auto-implemented)
I think this could be the root cause, the class you are testing is in the test library! At least that is the reason why you need PropertyChanged.Fody
in the test project!
@tom-englert yes that's the conclusion that I came to - the transient reference to the PropertyChanged.Fody
library is not sufficient.
Coupled with the msbuild minor adjustment and I have the LUT setup working a treat now.
I have just removed all my [TestCategory("SkipWhenLiveUnitTesting")]
flags and all the tests are running properly with coverage showing.
@richardhauer would be interesting to know if that modifications is still needed if the class you are testing is NOT in the test project but in the library project.
Most of my tests were against classes that were not defined in the Test library. It happens that the first test was setup that way as I was testing the base class' ability to record changed properties so I can have a IsChanged( a => a.Prop )
method that would inherit into all the models I need.
I had subsequently created a number of tests against the real models, all of which are in the Library project as you'd expect, and these had tests that passed when debugged or run in Test Explorer, but failed under LUT. With my changes to the target all the tests now pass under all conditions.
Cross-reference: https://github.com/Fody/Fody/issues/1034
Fixed in Fody 6.5.5
Bit new to Fody so pls go easy. There are a few moving parts to this that I've tried as a result of reading various posts/articles. I'm unsure if this is an issue with
PropertyChanged.Fody
or ifFody
in its entirety is not being executed under LUT scenarios. Happy to post to another location if that's appropriate but thought I'd start at the highest level of specificity.Environment
I have a basic soln structure as follows:
Microsoft.Net.Sdk
) targetingnet6.0
INotifyPropertyChanged
andprotected virtual void OnPropertyChanged( string propertyName )
FodyWeavers.xml
in the root with the<PropertyChanged />
element addedProblem
Nothing I can do will make
OnPropertyChanged()
fire in the context of Live Unit Testing. I can get it to work when running through Test Explorer and viadotnet test
so this isn't an issue with the normal operation of the library per se.I have been unable to identify a discrepancy between the build process used in LUT/roslyn and the normal
dotnet build
/msbuild
so I can't imagine why it wouldn't work, hoping someone with experience in this area can direct me to whatever changes might be necessary to get LUT going.Observation:
Fody
&PropertyChanged.Fody
packages need to be applied to both the library project AND the MSTest project in order for it to work through Test Explorer - I would not have expected this to be the case, but may be a clue. Presumably these references are only required on the project that actually uses the weaving?Anyone have any suggestions or thoughts?