搜尋此網誌

2024年7月18日 星期四

dotnet cli 建立 classlib 與 mstest 專案

緣起:


    不久前在看敏捷開發的書,他裡面有個範例是在講保齡球的計分,除了主程式之外,還有用到 unit test。我不想單純讀程式碼,想要跟著動手操作,這樣印像才會比較深。

    趁這個機會學習怎麼在 dotnet 建立 library 與 test 的專案,還有 unit test 的基本程式。


建立解決方案與 library 專案:


    官方教學文件。我在我 Desktop 下指令,建立 UnitTest 的解決方案

dotnet new sln -o UnitTest

    就會産生一個 UnitTest 的資料㚒,裡面有個 UnitTest.sln 檔,檔案内容長這樣

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal

    接著下指令來建立 library 專案

dotnet new classlib -o MyLibrary

    然後把專案加入解決方案

dotnet sln add ./MyLibrary/MyLibrary.csproj

    在 MyLibrary 新增 Game.cs

namespace MyLibrary
{
    public class Game
    {
        private int _score;

        public bool IsPass
        {
            get
            {
                return _score >= 60;
            }
        }

        public int Score
        {
            get { return _score; }
        }
        public Game()
        {
            _score = 0;
        }

        public void Add(int score)
        {
            _score += score;
        }
    }
}


建立 mstest 專案並引用 MyLibrary:


    下指令

dotnet new mstest -o MyTest

    然後一樣把 MyTest 加入解決方案

dotnet sln add ./MyTest/MyTest.csproj

    最後讓 MyTest 專案參考 MyLibrary 專案

dotnet add ./MyTest/MyTest.csproj reference ./MyLibrary/MyLibrary.csproj

    看一下 MyTest 專案,它預設有個 GlobalUsing.cs 跟 UnitTest1.cs,GlobalUsing 引用 Microsoft.VisualStudio.TestTools.UnitTesting。修改 UnitTest1.cs

namespace MyTest;
using MyLibrary;


[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Game game = new Game();
        game.Add(10);
        game.Add(12);
        Assert.AreEqual(game.Score, 22);
    }
}

    只要方法有加上 TestMethod 的 Attribute,在跑 dotnet test 時,這些方法都會自動執行,然後用 Assert 類別的方法來確認結果是否符合預期。


    再加上一個測試的方法,故意說 IsPass 是 false

namespace MyTest;
using MyLibrary;


[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Game game = new Game();
        game.Add(10);
        game.Add(12);
        Assert.AreEqual(game.Score, 22);
    }

    [TestMethod]
    public void TestMethod2(){
        Game game = new Game();
        game.Add(60);
        Assert.IsFalse(game.IsPass);
    }
}

    dotnet test 的結果


    如果覺得每次新增一個測試的方法都要 new 一個 Game 物件很麻煩的話,可以把 game 改成 member,然後新增一個方法,給它 TestInitialize 的 Attribute,把 new Game 寫在裡面

namespace MyTest;
using MyLibrary;


[TestClass]
public class UnitTest1
{
    private Game game;

    [TestInitialize]
    public void Init(){
        game = new Game();
    }

    [TestMethod]
    public void TestMethod1()
    {
        game.Add(10);
        game.Add(12);
        Assert.AreEqual(game.Score, 22);
    }

    [TestMethod]
    public void TestMethod2(){
        game.Add(60);
        Assert.IsFalse(game.IsPass);
    }
}

    這樣在每個測試的方法執行前,game 都會是一個新的 Game 物件。


沒有留言:

張貼留言