WPFのアプリをテストするときは躓きやすいのでちょっとコツを書きます。
こんな感じの構成のときどうやって操作していいのか最初はちょっと難しいですよね。
<NavigationWindow x:Class="WpfAppSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfAppSample" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> </NavigationWindow>
<Page x:Class="WpfAppSample.SamplePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfAppSample" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Title="SamplePage"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <local:SampleUserControl Grid.Column="0"> </local:SampleUserControl> <Canvas Grid.Column="1"> <TextBox Height="119" Canvas.Left="82" TextWrapping="Wrap" Text="{Binding Data}" Canvas.Top="182" Width="224"/> </Canvas> </Grid> </Page>
<UserControl x:Class="WpfAppSample.SampleUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfAppSample" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Canvas Background="#FFC9D6F6"> <ListView Height="368" Width="340" Canvas.Left="25" Canvas.Top="56" ItemsSource="{Binding Users}"> <ListView.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}"/> <CheckBox Content="Engineer" IsChecked="{Binding IsEngineer}"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button Content="Add" Canvas.Left="227" Canvas.Top="28" Width="75" Click="Button_Click"/> <TextBox Height="23" Canvas.Left="25" TextWrapping="Wrap" Text="{Binding Name}" Canvas.Top="28" Width="120"/> <CheckBox Content="Engineer" Canvas.Left="150" Canvas.Top="30" Width="77" IsChecked="{Binding IsEngineer}"/> </Canvas> </UserControl>
ドライバを作る
まずはドライバを作ります。このサンプルだと以下に作ります。一つ一つ作っていくところがポイントですね。
- Window
- Page
- UserControl
- ItemsControlのItem
要素の特定
特定方法ですが、Windowを捕まえるのはWindowControlのメソッドを使います。これはWinFormsと同じですね。以下WindowsAppFriendに対する拡張メソッドにしていますが中身はWindowControlのstaticメソッドです。
var win = app.WaitForIdentifyFromTypeFullName("WpfAppSample.MainWindow");
それで、Window以下に関しては、x:nameでアクセスできるならWinFormsの時と同じくフィールドを使ってもらえばいいのですが、ついていない場合はVisualTreeをだどって見つけます。前に書いてたのでそのリンクを貼っておきます。
ishikawa-tatsuya.hatenablog.com
ishikawa-tatsuya.hatenablog.com
ドライバのサンプル
using Codeer.Friendly.Windows; using Codeer.Friendly.Windows.Grasp; namespace Driver.Windows { //ドライバ public class MainWindowDriver { public WindowControl Core { get; } public MainWindowDriver(WindowControl core) { Core = core; } } //捕まえるための拡張 public static class MainWindowDriverExtensions { public static MainWindowDriver AttachMainWindow(this WindowsAppFriend app) => new MainWindowDriver(app.WaitForIdentifyFromTypeFullName("WpfAppSample.MainWindow")); } }
using Codeer.Friendly; using Codeer.Friendly.Dynamic; using RM.Friendly.WPFStandardControls; namespace Driver.Windows { public class SamplePageDriver { public WPFUserControl Core { get; } public WPFTextBox TextBox => Core.LogicalTree().ByBinding("Data").Single().Dynamic(); public SamplePageDriver(AppVar core) { Core = new WPFUserControl(core); } } //MainWindowからSamplePageを取得するための拡張 public static class SamplePageDriverExtensions { public static SamplePageDriver AttachSamplePage(this MainWindowDriver window) => window.Core.VisualTree().ByType("WpfAppSample.SamplePage").Single().Dynamic(); } }
using Codeer.Friendly; using Codeer.Friendly.Dynamic; using RM.Friendly.WPFStandardControls; using System.Windows.Controls; namespace Driver.Windows { public class SampleUserControl_Driver { public WPFUserControl Core { get; } public WPFListView ListView => Core.LogicalTree().ByBinding("Users").Single().Dynamic(); public WPFButtonBase Add => Core.LogicalTree().ByType<Button>().ByContentText("Add").Single().Dynamic(); public WPFTextBox TextBox => Core.LogicalTree().ByBinding("Name").Single().Dynamic(); public WPFToggleButton Engineer => Core.LogicalTree().ByBinding("IsEngineer").Single().Dynamic(); public SampleUserControl_Driver(AppVar core) { Core = new WPFUserControl(core); } } //SamplePageからSampleUserControlを取得するための拡張 public static class SampleUserControlDriverExtensions { public static SampleUserControl_Driver Attach_SampleUserControl(this SamplePageDriver page) => page.Core.VisualTree().ByType("WpfAppSample.SampleUserControl").Single().Dynamic(); } }
using Codeer.Friendly; using Codeer.Friendly.Dynamic; using RM.Friendly.WPFStandardControls; namespace Driver.Windows { public class UserListViewItemDriver { public WPFUserControl Core { get; } public WPFTextBlock TextBlock => Core.VisualTree().ByBinding("Name").Single().Dynamic(); public WPFToggleButton Engineer => Core.VisualTree().ByBinding("IsEngineer").Single().Dynamic(); public UserListViewItemDriver(AppVar core) { Core = new WPFUserControl(core); } } //ListViewItemにUserListViewItemDriverを適用するための拡張メソッド public static class UserListViewItemDriverExtensions { public static UserListViewItemDriver AsUser(this WPFListViewItem item) => new UserListViewItemDriver(item.AppVar); } }
シナリオのサンプル
using System.Diagnostics; using Codeer.Friendly.Windows; using Driver; using NUnit.Framework; using Driver.Windows; namespace Scenario { [TestFixture] public class Test { WindowsAppFriend _app; [SetUp] public void TestInitialize() => _app = ProcessController.Start(); [TearDown] public void TestCleanup() => Process.GetProcessById(_app.ProcessId).Kill(); [Test] public void TestMethod() { //Windowを見つける var mainWindow = _app.AttachMainWindow(); //ページを見つける var samplePage = mainWindow.AttachSamplePage(); //UserControlを見つける var sampleUserControl = samplePage.AttachSampleUserControl(); //アイテムを取得 var item = sampleUserControl.ListView.GetItem(1); //アイテム一つに対するドライバにする var userItem = item.AsUser(); //操作 userItem.Engineer.EmulateCheck(true); } } }