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

  • 質問

  • 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 という行を入れてエラーを検出したり、処理を分岐すれば良いだけの話ではないですか。

    私など底辺の趣味プログラマーですが、皆さんの意見をお聞かせください。
    2020年5月16日 1:41

回答

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

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

    • 回答としてマーク huahi11112 2020年5月18日 12:54
    2020年5月18日 9:00
    モデレータ

すべての返信

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

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

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

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

    • 回答としてマーク huahi11112 2020年5月16日 8:00
    • 回答としてマークされていない huahi11112 2020年5月17日 22:45
    2020年5月16日 4:23
    モデレータ
  • 御回答まことにありがとうございました。
    次のようなテストメソッドを作成しました。

    <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暗号() というメソッドが同じソリューションに搭載されており、これをテストメソッドから使用可能にします。
    暗号作成メソッドの中身は複雑で、内容を改変すると決まった答えを出さなくなる可能性があります。
    メインプログラムの中でメソッドの動作テストをしても良いですが、テストを外に出して実行できるならば便利ですね。
    この様な使い方をするのが単体テストというものなのでしょうか。もっと学習を進めてみたいと思います。
    2020年5月16日 8:00
  • そうですね。
    その「get暗号」に与えた入力(引数)と出力(戻り値)が変わらないことをテストすることで、互換性の担保、デグレの検出が単体テストを実行するだけで確認できるようになるので、開発者・テスター自身の手作業によるテストの削減、デグレの早期発見というプラスの効果はあります。

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

    • 回答としてマーク huahi11112 2020年5月18日 12:54
    2020年5月18日 9:00
    モデレータ
  • その点は大丈夫です。暗号化処理の核心部分をDLL化してWindow クラスから分離しています。そのDLLも、さらに別のアプリケーション内に暗号化してリソースとして保存してあり、難読化を突き詰めています。

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

    2020年5月18日 12:58