Windows Phone Unit Test App中的RenderTargetBitmap

时间:2015-10-01 13:41:42

标签: c# unit-testing windows-phone-8.1

我正在尝试编写一个单元测试来测试我的自定义控件的视觉外观。因此,我想使用RenderTargetBitmap捕获控件视觉外观,然后对结果像素使用断言。这是我的测试:

[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]);
    }
}

问题在于,当我运行此测试时,RendreAsync()操作将永久持续 (原因可能是element不是VisualTree的一部分,但我找不到任何方法来获取现有的可视化树或创建新的可视树。)
  我的问题是 - 我怎样才能使这项测试工作?

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题 使用async await有助于避免挂起。

[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]);
}

确定。现在测试没有挂起,但我得到以下异常:

  

结果消息:测试方法UnitTestApp.MyUnitTest.TestMethod2抛出   exception:System.NullReferenceException:未设置对象引用   一个对象的实例。

原因是element不是VisualTree的一部分。我找到了解决问题的方法:

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

不要忘记最后删除element。测试的最终版本:

[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]);
}