2014年10月26日日曜日

UI オートメーションで自動テスト その4

UI オートメーションの続きです。

前回は、起動したアプリケーションを終了する処理を実装しました。
これで連続する自動テストを実行できるようになりました。
今回は、ボタンを押す処理を実装したいと思います。
この処理はメニューアイテムを選択するときにも使えます。

2014年10月9日木曜日

UI オートメーションで自動テスト その3

UI オートメーションの続きです。

前回は、テキストボックスに文字列を自動入力するところまで実装しました。
実行するとアプリケーションが起動したままでした。
今回は、起動したアプリケーションを終了する処理を実装したいと思います。

2014年10月2日木曜日

UI オートメーションで自動テスト その2

UI オートメーションの続きです。

前回は、テスト対象のアプリケーションを起動して UI オートメーション要素を取得するところまでを実装しました。
今回は、テキストボックスに文字列を自動入力する処理を実装したいと思います。

自動入力って響きがいいですね。
入力するテストパターンがたくさんあるときは、かなり有効です。

まずは、テスト対象の実装から始めます。

2014年9月18日木曜日

UI オートメーションで自動テスト その1

UI オートメーションを使うと、UI の自動テストができるらしい。

それってスゴイ便利じゃん!
ってことで調べてみました。

UI オートメーションには、4つのコンポーネントがあるみたいです。

  • UIAutomationClient
  • UIAutomationClientsideProviders
  • UIAutomationProvider
  • UIAutomationTypes

今回は、UIAutomationClient と UIAutomationTypes を参照設定に追加して始めます。

2014年9月11日木曜日

StyleCop の警告をエラーに変更

C# で開発をするときは StyleCop を使っています。
コードの標準化ができて可読性が上がってます。

でも、警告なので無視も可能。
エラーにする方法はないかな。。。

2014年8月28日木曜日

Form アプリで、二重起動を禁止する

前回は、WPF アプリの二重起動を禁止する方法を調べました。

前回の記事:
WPF アプリで、二重起動を禁止する

今回は、フォームアプリを調べてみました。

2014年8月21日木曜日

WPF アプリで、二重起動を禁止する

WPF アプリケーションで二重起動を禁止するにはどうすればいいのだろう?
よく使いそうな機能なので覚えておくと使えそう。 

調べたら、Mutex クラスを使えばいいことがわかりました。

2014年7月10日木曜日

ボタン用 ViewModel の作成

今回も Livet を使った MVVM ネタです。

ViewModel を書いていると同じことをたくさん書くので疲れます。
で、今回は ViewModelCommand でボタン用の ViewModel を作成してみました。

using System;
using Livet;
using Livet.Commands;

/// <summary>
/// <see cref="System.Windows.Controls.Button"/> の ViewModel の機能を提供します。
/// </summary>
public class ButtonViewModel : ViewModel
{
    #region Private fields

    /// <summary>
    /// コンテンツ。
    /// </summary>
    private object content;

    /// <summary>
    /// コマンド。
    /// </summary>
    private ViewModelCommand command;

    /// <summary>
    /// コマンドが実行可能かどうかの値。
    /// </summary>
    private bool canExecute;

    /// <summary>
    /// コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値。
    /// </summary>
    private bool autoRaiseCanExecuteChanged;

    /// <summary>
    /// コマンドが実行するメソッド。
    /// </summary>
    private Action execute;

    #endregion // Private fields

    #region Constructors

    /// <summary>
    /// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
    /// </summary>
    /// <param name="execute">コマンドが実行するメソッド。</param>
    /// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
    public ButtonViewModel(Action execute)
        : this(execute, true, true)
    {
    }

    /// <summary>
    /// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
    /// </summary>
    /// <param name="execute">コマンドが実行するメソッド。</param>
    /// <param name="canExecute">コマンドが実行可能かどうかの値。</param>
    /// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
    public ButtonViewModel(Action execute, bool canExecute)
        : this(execute, canExecute, true)
    {
    }

    /// <summary>
    /// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
    /// </summary>
    /// <param name="execute">コマンドが実行するメソッド。</param>
    /// <param name="canExecute">コマンドが実行可能かどうかの値。</param>
    /// <param name="autoRaiseCanExecuteChanged">コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値。</param>
    /// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
    public ButtonViewModel(Action execute, bool canExecute, bool autoRaiseCanExecuteChanged)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        this.execute = execute;
        this.canExecute = canExecute;
        this.autoRaiseCanExecuteChanged = autoRaiseCanExecuteChanged;
    }

    #endregion // Constructors

    #region Properties

    /// <summary>
    /// コンテンツを取得または設定します。
    /// </summary>
    public object Content
    {
        get { return this.content; }
        set
        {
            if (value != this.content)
            {
                this.content = value;
                this.RaisePropertyChanged(() => this.Content);
            }
        }
    }

    /// <summary>
    /// コマンドを取得します。
    /// </summary>
    public ViewModelCommand Command
    {
        get
        {
            return this.command = this.command ??
                new ViewModelCommand(this.execute, () => this.CanExecute);
        }
    }

    /// <summary>
    /// コマンドが実行可能かどうかの値を取得または設定します。
    /// </summary>
    public bool CanExecute
    {
        get { return this.canExecute; }
        set
        {
            if (value != this.canExecute)
            {
                this.canExecute = value;
                this.RaisePropertyChanged(() => this.CanExecute);

                if (this.AutoRaiseCanExecuteChanged)
                {
                    this.RaiseCanExecuteChanged();
                }
            }
        }
    }

    /// <summary>
    /// コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値を取得または設定します。
    /// </summary>
    public bool AutoRaiseCanExecuteChanged
    {
        get { return this.autoRaiseCanExecuteChanged; }
        set
        {
            if (value != this.autoRaiseCanExecuteChanged)
            {
                this.autoRaiseCanExecuteChanged= value;
                this.RaisePropertyChanged(() => this.AutoRaiseCanExecuteChanged);
            }
        }
    }

    #endregion // Properties

    #region Public methods

    /// <summary>
    /// コマンドを実行します。
    /// </summary>
    public void Execute()
    {
        if (this.command != null)
        {
            this.Command.Execute();
        }
    }

    /// <summary>
    /// コマンドが実行可能かどうかが変化したことを通知します。
    /// </summary>
    public void RaiseCanExecuteChanged()
    {
        if (this.command != null)
        {
            this.command.RaiseCanExecuteChanged();
        }
    }

    #endregion // Public methods
}

最低限必要なプロパティを実装しました。
おまけで、RaiseCanExecuteChanged メソッドの実行を制御するプロパティを用意。

使う側の MainWindowViewModel.cs はこんな感じで実装します。

public MainWindowViewModel()
{
    this.CopyButton = new ButtonViewModel(this.CopyAction)
    {
        Content = "コピー",
    };
}

public ButtonViewModel CopyButton { get; private set; }

private void CopyAction()
{
}

最後は、xaml です。

<Button Command="{Binding Path=CopyButton.Command}"
        Width="75"
        Height="24"
        Margin="3"
        HorizontalAlignment="Right"
        Content="{Binding Path=CopyButton.Content" />

バインドする名前が長くなってしまうのが難点だけど、ViewModel がスッキリできました。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年7月3日木曜日

Levet で MVVM の基本

お久しぶりです。
1ヶ月以上の開いてしまいました。

今回は、前回の Livet を使った簡単な MVVM のサンプルを作りたいと思います。

機能は TextBox に入力した文字列を別の TextBox にコピーするだけ。
とても、シンプルです。

画面はこんな感じ。(UI のセンスがありません)



では、はじめます。

Visual Studio Express 2013 を立ち上げたら、「Livet WPF4.5 MVVM アプリケーション」を選んでプロジェクトを作成します。

MainWindowVIewModel.cs を開いてたら、TextBox 用のプロパティを2つ追加します。


private string inputText;

public string InputText
{
    get { return this.inputText; }
    set
    {
        if (value != this.inputText)
        {
            this.inputText = value;
            this.RaisePropertyChanged(() => this.InputText);
        }
    }
}

private string outputText;

public string OutputText
{
    get { return this.outputText; }
    private set
    {
        if (value != this.outputText)
        {
            this.outputText = value;
            this.RaisePropertyChanged(() => this.outputText);
        }
    }
}

次にコピーの処理を追加します。

private void CopyAction()
{
    this.OutputText = this.InputText;
}

最後にボタン用のコマンドを追加します。

private ViewModelCommand copyCommand;

public ViewModelCommand CopyCommand
{
    get
    {
        return this.copyCommand = this.copyCommand ??
            new ViewModelCommand(this.CopyAction);
    }
}

MainWindow.xaml を開いてコントロールを追加します。

<Window x:Class="Kaznagamine.LivetSample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:Kaznagamine.LivetSample.Views"
        xmlns:vm="clr-namespace:Kaznagamine.LivetSample.ViewModels"
        Title="MainWindow" Height="300" Width="400">
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding Path=InputText}"
                     Width="120"
                     Height="23"
                     Margin="3"
                     TextAlignment="Right" />
            <Button Command="{Binding Path=CopyCommand}"
                    Width="75"
                    Height="24"
                    Margin="3"
                    HorizontalAlignment="Right"
                    Content="コピー" />
            <TextBox Text="{Binding Path=OutputText}"
                     Width="120"
                     Height="23"
                     Margin="3"
                     TextAlignment="Right"
                     IsReadOnly="True"/>
        </StackPanel>
    </Grid>
</Window>

ビルドして実行したら、左の TextBox に文字列を入力してボタンを押します。
右の TextBox に同じ文字列が表示されたら完成です。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年5月8日木曜日

Visual Studio Express で Livet

今日は Livet です。

Livet は WPF 用 MVVM パターンのインフラストラクチャです。
Prism や MVVM Light Toolkit などのライブラリの中の1つです。

Express から利用する場合は Livet - WPF4/4.5 MVVM インフラストラクチャ からインストーラをダウンロードしてインストールするだけ。
プロジェクトを作成しようとすると、Livet 用テンプレートがあります。



これから Livet で WPF の勉強を始めていこうと思います。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年5月1日木曜日

Visual Studio Express で StyleCop

今回は StyleCop です。

StyleCop は Visual Studio 上から実行できて便利!
と言うのは、Professional の話。
Express だと IDE 上から操作ができないので、ビルド時に実行します。

実行するには、プロジェクトファイル (*.csproj) をテキストエディタで開いて4行追加するだけ。

<PropertyGroup>
  <StyleCopTargetsFile>$(ProgramFiles)\MSBuild\StyleCop\v4.7\StyleCop.Targets</StyleCopTargetsFile>
</PropertyGroup>
<Import Project="$(StyleCopTargetsFile)" Condition="Exists('$(StyleCopTargetsFile)')"/>

Condition でファイルの有無を確認しているので、StyleCop をインストールしていないパソコンでは実行しません。

StyleCop をインストールしていないパソコンでも実行するためには、NuGet でプロジェクトに StyleCop をインストールするのが便利です。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年4月24日木曜日

Blogger SyntaxHighlighter を設定する

今回も Blogger ネタです。

前回の記事を書くために、SyntaxHighlighter の設定をしました。
SyntaxHighlighter はソースコードをカッコよく表示してくれます。

設定は前回のタイトル変更と同じく、管理画面の [テンプレート] から行います。

今回は、XML の表示だったため、以下の設定を追加しました。

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
</script>

4 行目が XML の設定です。
ほかの言語もいろいろ対応しています。
言語一覧は Bundled Brushes に載っています。

設定が完了したら、投稿画面の [HTML] モードで <pre> タグを入力して、その中にソースコードを書きます。

<pre class="brush: html">
</pre>

XML はエンティティ文字の変換がちょっと面倒です。
[作成] モードで表示したい XML を書いたあとに、[HTML] モードにして <pre> タグで囲むと編集が楽になります。
プレビュー画面で表示されないので出来上がりは公開してからチェックするしかないみたいです。

これからはプログラムもどんどん載せていこうと思います。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年4月17日木曜日

Blogger 投稿ページのタイトルを変更する

今回は Blogger ネタです。

google で検索をしていたら、投稿ページのタイトルを変更する方法を見つけました。
早速、やってみました。

タイトルを編集するには、管理画面の [テンプレート] を選択して [HTML の編集] をクリックします。

編集画面でタイトルを定義している行を見つけます。

<title><data:blog.pageTitle/></title>

見つけたら、以下の様に修正します。

<b:if cond='data:blog.pageType == &quot;index&quot;'>
  <title><data:blog.title/></title>
<b:else/>
  <title><data:blog.pageName/> | <data:blog.title/></title>
</b:if>

修正したら、[テンプレートを保存] をクリックして終了します。

この変更で、ページの種類によってタイトルが変化します。
トップページの場合は、「ブログのタイトル」
それ以外は「投稿のタイトル | ブログのタイトル」

意外と簡単でした。

参考:
[Blogger] タイトルタグを「投稿タイトル|ブログタイトル」に変更する方法 | Bloggerをカスタマイズするときに見るブログ
レイアウト データ タグ - Blogger ヘルプ


今回の記事を書くために SyntaxHighlighter の設定を行いました。
それはまた次回に。


頑張りすぎず脱力系でいこうと思います。
以上。

2014年4月10日木曜日

ブログ始めました

タイトルのままです。

4月1日から始めようと思っていましたが、気づいたら10日になっていました。
プログラミングの tips などを防備録として書いていこうと思います。
Blogger も段々と充実していきたいので、その作業ログも記録していきます。

まずは月に1回。
もとい、週に1回は何かを書く!
実際には月に2回のペースかな。

書きながら文章力も付けばいいな〜と淡い期待。


今回はネタを用意していないのでパソコンの構成を公開。

ベアボーンキット:
 Intel NUC D54250WYK
RAM:
 CFD W3N1600Q-L4G
SSD:
 Crucial CT240M500SSD3
ネットワーク:
 Intel Centrino Advanced-N 6235
DVD:
 BUFFALO DVSM-PTS58U3-BK
キーボード:
 FILCO Majestouch NINJA FKBN104ML/EFB2
マウス:
 Logicool M570
OS:
 LinuxMint 15
 Windows 7 Pro 64bit


頑張りすぎず脱力系でいこうと思います。
以上。