使用 LeetCode 771 練習測試
題目大致上就是有個變數 J 跟 S,輸出在S 與 J 匹配的字元數量。(且 J 不會重覆字元)
所以
- J = “aA” , S = “aAAbbbb” 輸出為 3
- J = “z” , S = “ZZ” 輸出為 0
建立一個 Unit Test 專案 命名為 : LeetCode771JewelsAndStonesTests

Unit Test 的 3A 原則
- Arrange – 初始化
- Act – 執行
- Actual – 驗證結果
建立第一個測試 :

[TestMethod]
public void NumJewelsInStonesTest_When_J_Is_aA_And_S_Is_aAAbbbb_Should_Be_3()
{
//Arrange
var solution = new Solution();
var J = "aA";
var S = "aAAbbbb";
//Act
var actual = solution.NumJewelsInStones(J, S);
//Assert
var expected = 3;
Assert.AreEqual(expected, actual);
}
產生空的 Solution.cs :

public class Solution
{
public int NumJewelsInStones(string J, string S)
{
throw new System.NotImplementedException();
}
}
撰寫程式碼,通過測試 :

public class Solution
{
public int NumJewelsInStones(string J, string S)
{
int count = 0;
var js = J.ToArray();
var ss = S.ToArray();
foreach (var j in js)
{
foreach (var s in ss)
{
if (j == s)
{
count++;
}
}
}
return count;
}
}
建立第二個測試 :

[TestMethod]
public void NumJewelsInStonesTest_When_J_Is_z_And_S_Is_ZZ_Should_Be_0()
{
//Arrange
var solution = new Solution();
var J = "z";
var S = "ZZ";
//Act
var actual = solution.NumJewelsInStones(J, S);
//Assert
var expected = 0;
Assert.AreEqual(expected, actual);
}
由於可以直接通過測試 可以執行 Ctrl + RT (當前測試) 或 Ctrl + RA (所有測試)

安裝 Specflow
需先安裝 Visual Studio Extension (需重新啟動 Visual Studio)

Nuget 安裝 Specflow
建立 SpecflowFeature
專案,按右鍵,新增檔案


修改 Scenario :

Feature: Jewels and Stones @mytag Scenario: NumJewelsInStones Given I have entered J aA into the solution And I have entered S aAAbbbb into the solution When I press NumJewelsInStones Then the result should be 3 on the screen
右鍵產生 Steps

會新增一個 JewelsAndStonesSteps.cs
但你會發現變數並沒有帶入,所以要手動把它修改成 (.*) 跟傳入參數


回到 feature 會看到變數已有運作 :

直接建置的話會出現找不到 NUnit

因預設使用 NUnit 但這邊使用 MSTest 所以修正 App.config 使用 MsTest
<unitTestProvider name="MsTest" />

測試會顯示出來,此時已可以建置或執行測試 :

Specflow 的 JewelsAndStonesSteps.cs 程式部分 :
步驟跟 Unit Test 一樣,只是需要先用 ScenarioContext.Current.Add(key,value) 把值存起來

跟 ScenarioContext.Current.Get<type>(key) 取值 :

public class JewelsAndStonesSteps
{
[Given(@"I have entered J (.*) into the solution")]
public void GivenIHaveEnteredJIntoTheSolution(string J)
{
ScenarioContext.Current.Add("J",J);
}
[Given(@"I have entered S (.*) into the solution")]
public void GivenIHaveEnteredSIntoTheSolution(string S)
{
ScenarioContext.Current.Add("S", S);
}
[When(@"I press NumJewelsInStones")]
public void WhenIPressNumJewelsInStones()
{
var solution = new Solution();
var J = ScenarioContext.Current.Get<string>("J");
var S = ScenarioContext.Current.Get<string>("S");
var actual = solution.NumJewelsInStones(J, S);
ScenarioContext.Current.Add("actual", actual);
}
[Then(@"the result should be (.*) on the screen")]
public void ThenTheResultShouldBeOnTheScreen(int expected)
{
var actual = ScenarioContext.Current.Get<int>("actual");
Assert.AreEqual(expected, actual);
}
}
完成測試後,需要建立第二個測試,由於步驟都跟第一個步驟完全相同,所以可以將 Scenario 轉成 Scenario Outline ,並建立 Examples

Scenario Outline: NumJewelsInStones Given I have entered J <J> into the solution And I have entered S <S> into the solution When I press NumJewelsInStones Then the result should be <result> on the screen Examples: | J | S | result | | aA | aAAbbbb | 3 | | z | ZZ | 0 |
最後,執行測試 :




