RenderTargetBitmap in Windows Phone Unit Test App

别来无恙 提交于 2019-12-13 02:08:05

问题


I'm trying to write a unit test that will test a visual appearance of my custom control. Therefore I want to capture the control visual appearance using RenderTargetBitmap and then use assertions on result pixels. Here is my test:

[TestClass]
public class UnitTest2
{
    [TestMethod]
    public void TestMethod2()
    {
        //pixels to test
        byte[] pixels = null;

        // Since I create a UI elements, I need to use Dispatcher here.            
        var task = CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
        {
            // Here I create a visual element that I want to test
            var brush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            var element = new Border()
            {
                MinWidth = 20,
                MinHeight = 20,
                Background = brush,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                BorderThickness = new Thickness(0)
            };

            // create an instance of RenderTargetBitmap to render a bitmap 
            var rtb = new RenderTargetBitmap();
            var rtbTask = rtb.RenderAsync(element).AsTask();

            // the following operation lasts for ages
            // May be the reason is that the element is not a part of the VisualTree
            rtbTask.Wait(); 

            var rtbGetPixelsTask = rtb.GetPixelsAsync().AsTask<IBuffer>();
            rtbGetPixelsTask.Wait();
            pixels = rtbGetPixelsTask.Result.ToArray();
        });
        task.AsTask().Wait();

        Assert.AreEqual<byte>(255, pixels[0]);
        Assert.AreEqual<byte>(255, pixels[1]);
        Assert.AreEqual<byte>(255, pixels[2]);
        Assert.AreEqual<byte>(255, pixels[3]);
    }
}

The problem is that when I run this test the RendreAsync() operation lasts forever.
(The cause of that could be that the element is not a part of the VisualTree, but I cannot find any way to get existing visual tree or to create a new one.)
My question is - how can I make this test work?


回答1:


I've solved the issue.
Using async await helps to avoid hanging.

[TestMethod]
public async Task TestMethod2()
{
    //pixels to test
    byte[] pixels = null;

    // Since I create a UI elements, I need to use Dispatcher here.
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () =>
    {
        // Here I create a visual element that I want to test
        var brush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
        var element = new Border()
        {
            MinWidth = 20,
            MinHeight = 20,
            Background = brush,
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Top,
            BorderThickness = new Thickness(0)
        };

        // create an instance of RenderTargetBitmap to render a bitmap 
        var rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(element); // exception!

        var pixBuffer = await rtb.GetPixelsAsync();
        pixels = pixBuffer.ToArray();
    });

    Assert.AreEqual<byte>(255, pixels[0]);
    Assert.AreEqual<byte>(255, pixels[1]);
    Assert.AreEqual<byte>(255, pixels[2]);
    Assert.AreEqual<byte>(255, pixels[3]);
}

Ok. Now the test doesn't hang but I get the following exception:

Result Message: Test method UnitTestApp.MyUnitTest.TestMethod2 threw exception: System.NullReferenceException: Object reference not set to an instance of an object.

The reason is that the element is not a part of the VisualTree. I've found the way to fix that:

var grid = Window.Current.Content as Grid;
grid.Children.Add(element);

Do not forget to remove the element in the end. And the final version of the test:

[TestMethod]
public async Task TestMethod4()
{
    //pixels to test
    byte[] pixels = null;

    // Since I create a UI elements, I need to use Dispatcher here.
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () =>
    {
        var grid = Window.Current.Content as Grid;

        // Here I create a visual element that I want to test
        var brush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
        var element = new Border()
        {
            MinWidth = 20,
            MinHeight = 20,
            Background = brush,
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Top,
            BorderThickness = new Thickness(0)
        };

        grid.Children.Add(element);

        try
        {

            // create an instance of RenderTargetBitmap to render a bitmap 
            var rtb = new RenderTargetBitmap();
            await rtb.RenderAsync(element);

            var pixBuffer = await rtb.GetPixelsAsync();
            pixels = pixBuffer.ToArray();
        }
        finally
        {
            grid.Children.Remove(element);
        }
    });

    Assert.AreEqual<byte>(255, pixels[0]);
    Assert.AreEqual<byte>(255, pixels[1]);
    Assert.AreEqual<byte>(255, pixels[2]);
    Assert.AreEqual<byte>(255, pixels[3]);
}


来源:https://stackoverflow.com/questions/32889152/rendertargetbitmap-in-windows-phone-unit-test-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!