VSの単体テストのメリットとは?

Category: visual studio general_ja

Question

huahi11112 on Sat, 16 May 2020 01:41:31


Microsoft Visual Studio Community 2019を使用しています。
単体テストに興味を持ち、下のサイトを見て同様のことを実現できたのですが、
https://docs.microsoft.com/ja-jp/visualstudio/test/getting-started-with-unit-testing?view=vs-2019

<テストプロジェクトのソースコード>
<TestClass()> Public Class UnitTest1

    <TestMethod()> Public Sub TestMethod1()
        Dim n1 = sample1(1, 1)

        Assert.AreEqual(True, n1)

    End Sub

    Private Function sample1(ByVal a As Integer, ByVal b As Integer) As Boolean
        If a + b = 0 Then Return True

        Return False
    End Function

End Class

ここで、sample1(a,b)のパラメーターを変えるとテストでエラーになることを確認しましたが、この様なテストをして何のメリットがあるのでしょうか。

a,bに変数を格納し、
if not sample1(a,b)=true then XXXX という行を入れてエラーを検出したり、処理を分岐すれば良いだけの話ではないですか。

私など底辺の趣味プログラマーですが、皆さんの意見をお聞かせください。

Replies

Azulean on Sat, 16 May 2020 04:23:51


テストコード内にテストターゲット(テスト対象)のコードがある場合、それに意味はないのは同意です。
あくまで、テストターゲットの実装がテストコードとは別のプロジェクト・別のクラスにあることが前提だと思います。

一例としては回帰テストの効率化です。
たとえば、「CsvFileReader」クラスを作ったとして、テスト用の「hogehoge.csv」を読み込ませたときに、「1,2,3」という数値配列が得られるというテストケースを書いたとします。
作った当初は問題なくテスト成功すると思いますが、CsvFileReader クラスを「複数行対応」「文字列の "" に対応」といったように改造・拡張していく中で、不具合が混入するかもしれません。
それを、いちいち細かくレビューしたり、手動で毎回テスト・デバッグしたりするよりは、単体テストを実行して OK/NG とする方が、回帰テストとしては楽ですよね。

ほかの例を挙げるとしたら、作ってから GUI からデバッグできるようになるまでに工程が多くかかるものを、部品単位でテストすることで、「完成したものを積み上げる」という開発者の精神的安定や、進捗が急に遅くなるといった問題の軽減にも寄与します。

とりあえず、テストコード書くだけのドキュメントを読んでも正直わからないと思うので、ユニットテストを扱った文献を読んでもらった方が良いかもしれません。

huahi11112 on Sat, 16 May 2020 08:00:19


御回答まことにありがとうございました。
次のようなテストメソッドを作成しました。

<TestClass()> Public Class UnitTest1

    <TestMethod()> Public Sub TestMethod1()
        Dim a = New WpfApplication1.MainWindow
        Dim s As String
        '単体テストに使うget暗号()メソッドを使用可能にする
        ’’’’ここに何かを記述 ’’’’

        s = a.get暗号(4031, "その1") 'パラメーター、IntegerとStringから、固有の9文字の半角文字列を作り出す
        Assert.AreEqual(s, "560681146") ’作成された暗号が"560681146"であると期待する

        s = a.get暗号(2974, "その2")
        Assert.AreEqual(s, "220947540")

        s = a.get暗号(10000, "その3")
        Assert.AreEqual(s, "000000000")

    End Sub


End Class

get暗号() というメソッドが同じソリューションに搭載されており、これをテストメソッドから使用可能にします。
暗号作成メソッドの中身は複雑で、内容を改変すると決まった答えを出さなくなる可能性があります。
メインプログラムの中でメソッドの動作テストをしても良いですが、テストを外に出して実行できるならば便利ですね。
この様な使い方をするのが単体テストというものなのでしょうか。もっと学習を進めてみたいと思います。

Azulean on Mon, 18 May 2020 09:00:57


そうですね。
その「get暗号」に与えた入力(引数)と出力(戻り値)が変わらないことをテストすることで、互換性の担保、デグレの検出が単体テストを実行するだけで確認できるようになるので、開発者・テスター自身の手作業によるテストの削減、デグレの早期発見というプラスの効果はあります。

ところで、暗号化処理自体は Window になくても成立するので、Window クラスから分けませんか?
単体テストコード内で Window のインスタンスを作ると、テストのプロセス内でハンドルリークする気もするので…。
(実際にはテストランナーのプロセスはそこまで長生きしないので、実害はないでしょうけども)

huahi11112 on Mon, 18 May 2020 12:58:14


その点は大丈夫です。暗号化処理の核心部分をDLL化してWindow クラスから分離しています。そのDLLも、さらに別のアプリケーション内に暗号化してリソースとして保存してあり、難読化を突き詰めています。

今回、暗号化クラスを単体テストすることができるようになり、手作業によるテストの削減という面では進歩がありました。