-
Notifications
You must be signed in to change notification settings - Fork 79
Description
Workaround for microsoft/testfx#740 (comment). Also seems like this method should work based on comment by Morten here (Note his solution is v1 source generator, we should build a v2 one.)
Follow-on from #137
Problem
We have to add an explicit dispatch call to all our UI tests in order to get them to work async and wait for UI to load before testing (don't think we can do that without async). And therefore we hit the issue where we can't use the existing [UITestMethod] attribute which should do that for us.
[TestMethod]
[TestPage(typeof(PropertySizerTestInitialBinding))]
public async Task PropertySizer_TestInitialBinding()
{
await App.DispatcherQueue.EnqueueAsync(() => {
// TestPage shouldn't be null here, but we'll do the safer ?. to be sure.
var propertySizer = TestPage?.FindDescendant<PropertySizer>();
Assert.IsNotNull(propertySizer, "Could not find PropertySizer control.");
// Set in XAML Page LINK: PropertySizerTestInitialBinding.xaml#L14
Assert.AreEqual(300, propertySizer.Binding, "Property Sizer not at expected initial value.");
});
}What we want
// We're already dispatched to the UI thread here and can write our test either sync or async
[UITestMethodWithXamlPage(typeof(PropertySizerTestInitialBinding))] // Rename of TestPage attribute
public void PropertySizer_TestInitialBinding() // or `async Task` should also be supportable if we need it
{
// TestPage shouldn't be null here, but we'll do the safer ?. to be sure.
var propertySizer = TestPage?.FindDescendant<PropertySizer>();
Assert.IsNotNull(propertySizer, "Could not find PropertySizer control.");
// Set in XAML Page LINK: PropertySizerTestInitialBinding.xaml#L14
Assert.AreEqual(300, propertySizer.Binding, "Property Sizer not at expected initial value.");
}Solution
Basically the UITestMethodWithXamlPage attribute would generate a regular TestMethod implementation (similar to the example above) with the async Task and DispatcherQueue code we already know works. However, it would also incorporate the GetPageForTest and TestInitialize code currently from VisualUITestBase (added in #137) to remove reflection and setup the test before calling the attributed method the source generator is writing for (UITextMethodWithXamlPage).
[TestMethod]
public async Task PropertySizer_TestInitialBinding_Test()
{
await App.DispatcherQueue.EnqueueAsync(async () => {
// Simplifies our reflection heavy initialization in GetPageForTest!
TestPage = new PropertySizerTestInitialBinding(); // should have diagnostics if this isn't a FrameworkElement/UserControl/Page thing
// Set content (currently done in TestInitialize, so that can be removed)
Task result = SetTestContentAsync(TestPage);
await result;
if (!result.IsCompletedSuccessfully)
{
throw new Exception($"Failed to load page for {TestContext.TestName} with Exception: {result.Exception?.Message}", result.Exception);
}
// Call developer code, Note: would need to generate different and await instead if it was an async method.
PropertySizer_TestInitialBinding();
TestPage = null; // can be removed from Cleanup method now
});
}Open Questions
- Do we also want our own fixed
UITestMethodwhich does the same without grabbing a page, but encapsulates the need for dispatching to the queue?