Matlabで単体テストを書く for 入門者向け

先日、初めてMatlabでテストコード書いたので、つまづいたところを重点にまとめてみました。あくまで、とりあえず始めてみたい人向けです。細かなところは記述しません。

## 内容
Matlabでは単体テストがサポートされています。そのサンプルコード([単純なテストスイートの作成]( http://jp.mathworks.com/help/matlab/matlab_prog/create-simple-test-suites.html ))をMatlabの公式ページから見ることができます。また本稿はこのページ([クラスを使用するセットアップ コードと破棄コードの記述](https://jp.mathworks.com/help/matlab/matlab_prog/write-setup-and-teardown-code-using-classes.html))を参考にしています。

本稿は以下のような構成になっています。

- 単純なテストクラスのおさらい
- テストのセットアップ
- 一つのテストのみの実行

### 単純なテストクラスのおさらい
まずは単純なテストクラスの生成と実行の方法について見ていきます。(以下、[単純なテストスイートの作成]( http://jp.mathworks.com/help/matlab/matlab_prog/create-simple-test-suites.html ) を引用)

#### テストしたい関数
2次関数を解く関数 `quadraticSolver.m` です。中学生で習う公式ですね。

```matlab
%quadraticSolver.m

function roots = quadraticSolver(a, b, c)
% quadraticSolver returns solutions to the 
% quadratic equation a*x^2 + b*x + c = 0.

if ~isa(a,'numeric') || ~isa(b,'numeric') || ~isa(c,'numeric')
    error('quadraticSolver:InputMustBeNumeric', ...
        'Coefficients must be numeric.');
end

roots(1) = (-b + sqrt(b^2 - 4*a*c)) / (2*a);
roots(2) = (-b - sqrt(b^2 - 4*a*c)) / (2*a);

end
```
#### テストコード
x^2-3x+2=0とx^2-2+10=0の場合をテストするコードです。解はそれぞれ、実数の組と虚数の組を期待します。

```matlab
% SolverTest.m

classdef SolverTest < matlab.unittest.TestCase
    % SolverTest tests solutions to the quadratic equation
    % a*x^2 + b*x + c = 0
    
    methods (Test)
        function testRealSolution(testCase)
            actSolution = quadraticSolver(1,-3,2);
            expSolution = [2,1];
            testCase.verifyEqual(actSolution,expSolution);
        end
        function testImaginarySolution(testCase)
            actSolution = quadraticSolver(1,2,10);
            expSolution = [-1+3i, -1-3i];
            testCase.verifyEqual(actSolution,expSolution);
        end
    end
    
end
```

#### 実行

```matlab
> import matlab.unittest.TestSuite
> suiteClass = TestSuite.fromClass(?SolverTest);
> result = run(suiteClass);
```

### テストのセットアップ
これまで、簡単なテストの方法について確認しました。
ここではテストのセットアップについて扱います。
テストのセットアップとはなんでしょう。例えば、共通する大量のパラメータの代入、訓練データの生成など、テストごとに用意するのは面倒かつ、コストがかかります。そこで用意されている`TestMethodSetup`を使い、各テストに共通する前処理などを記述することでその問題を解決できます。

### テストコードにセットアップ関数を定義する
```matlab

%SolverTest.m

classdef SolverTest < matlab.unittest.TestCase
    % SolverTest tests solutions to the quadratic equation
    % a*x^2 + b*x + c = 0

    % プロパティの追加とセットアップ関数 ---------------   
    properties
        param
    end

    methods (TestMethodSetup)
        function setParams(testCase)
            testCase.param = 1
        end
    end
    %------------------------------------------------   
   
    % セットアップ関数でセットした値 param を使う
    methods (Test)
        function testRealSolution(testCase)
            actSolution = quadraticSolver(testCase.param,-3,2);
            expSolution = [2,1];
            testCase.verifyEqual(actSolution,expSolution);
        end
        function testImaginarySolution(testCase)
            actSolution = quadraticSolver(testCase.param,2,10);
            expSolution = [-1+3i, -1-3i];
            testCase.verifyEqual(actSolution,expSolution);
        end
    end
    
end
```

### 一つのテストのみの実行

テストクラスから作成したテストスイートにたくさんのテストがある場合、そのうちの一つのケースのみをテストしたい場合についてです。
例えば、上の例の`testImaginarySolution`のみをテストしたい場合、

プロンプトから

```matlab
> testCase = SolverTest;
> result = run(testCase, 'testImaginarySolution')
```
とすることで、実行可能です。