WPF控件的UI自动化测试似乎忽略了绑定

时间:2015-07-09 19:44:09

标签: c# wpf unit-testing xaml

我目前正在尝试弄清楚如何为我的WPF应用程序自动化UI测试,但我无法让它运行起来。

UserControl(扩展CheckBox)的XAML包含以下<CheckBox Name="IsFooCheckBox" IsChecked="{Binding Path=IsFoo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

INotifyPropertyChanged

绑定指向实现private bool _isFoo; public bool IsFoo { get { return _isFoo; } set { _isFoo = value; OnPropertyChanged("IsFoo"); } } 并包含以下属性的自定义数据上下文:

_isFoo

绑定正在生产中(在调试器中可以看到每当我切换复选框时都会更新var myContext = ... var sut = new MyControl { DataContext = myContext }; var peer = new CheckBoxAutomationPeer(sut.IsFooCheckBox); var pattern = peer.GetPattern(PatternInterface.Toggle) as IToggleProvider; pattern.Toggle(); Assert.That(sut.IsProvidingProfileCheckBox.IsChecked.Value); // works Assert.That(myContext.IsFoo); // fails 。)

我现在想要进行测试,切换复选框并检查数据上下文是否已更新(或检查代码隐藏中实现的逻辑)。 WPF UI自动化框架似乎正是我正在寻找的,所以我编写了以下NUnit测试:

Assert

第一个public class Car { public int Id { get; set; } public Car() { } public Car(int id) { Id = id; } } public class CarCollection { public List<Car> Cars { get; set; } public void AddCar(Car car) { Cars.Add(car); } public Car GetById(int id) { return Cars.Single(x => x.Id == id); } public CarCollection(List<Car> cars) { Cars = cars; } public CarCollection(Car car) { Cars = new List<Car>() { car }; } } 通过时,第二个失败。我不明白为什么会发生这种情况......似乎忽略了XAML文件中的绑定或者没有触发更新。有没有人建议如何修复我的测试?这甚至可能吗?

3 个答案:

答案 0 :(得分:0)

问题来自这里

public bool IsFoo
{
   get { return _IsFoo; }
   set
   {
      _isFoo = value;
      OnPropertyChanged("IsFoo");
   }
}

调用后

pattern.Toggle();

你隐式调用IsFoo的setter引发了PropertyChanged事件并反过来强制刷新与IsFoo相关联的UI元素 - 缩短长篇故事,调用getter而不是 _isFoo 它返回 _IsFoo 。你错误的变量。
尽量避免使用显式属性名称调用OnPropertyChanged方法。而不是使用 CallerMemberName 属性来检索属性名称。

     public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

然后你只需要下面的调用。

OnPropertyChanged();

答案 1 :(得分:0)

我有类似的问题。我用以下代码填充文本框:

        ValuePattern valuePattern = promptBox.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
        valuePattern.SetValue(value);

根据文本框中的值,另一个按钮状态应该从Disabled更改为Enabled。

我注意到在执行上述自动化代码后,手动点击窗口会触发绑定进行评估。

所以我刚刚添加了

    System.Windows.Forms.SendKeys.SendWait("{TAB}");
在SetValue之后

它开始工作得很好。

答案 2 :(得分:0)

我花了一些时间才弄明白这一点,但最后,这种情况在互联网的许多地方都很明显。一旦你知道要寻找什么,我想一切都很容易......

编码UI测试的问题是绑定不会自动解决。必须通过致电Window.ShowWindow来启动解决方案。

我扩展了测试并添加了以下代码段:

Window window = new Window
{
    Content = sut // the control to test
};
window.Show();

立即添加此调用修复了我在帖子中描述的奇怪测试行为。

直接后续问题是此调用需要一个活动的UI线程。因此,在持续集成环境中使测试在构建服务器上运行可能会很棘手。但是,这取决于环境(尤其是构建服务器),这是一个不同的问题。