Blog
0

Unit Testing C# Code with MSTest

  • Pradyumn Sharma
  • June 27, 2017

Tags: , ,

About two months ago, I had written a blog titled “Test-Driven Development: An Introduction with a JUnit Example“. In that post, I had explained the basic concepts of Test-Driven Development (TDD), taking the binary search algorithm as an example, and using Java, Eclipse, and JUnit as the platforms. In this post, I am going to discuss TDD using C#, Visual Studio 2015 (Community Edition), and MSTest.

We’ll dive right into the hands-on here, if you need an introduction to TDD, please refer to my earlier post.

Creating a Test Class

Begin by creating a new Unit Test Project. Steps:

File > New > Project > Test (under Templates, Visual C#), Unit Test Project

Name the solution “BinarySearchSolution”, and the project “BinarySearchTestProject”.

Visual Studio creates a class called UnitTest1, with the following default code:

1
2
3
4
5
6
7
8
9
10
11
namespace BinarySearchTestProject
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
}

Rename the class ‘UnitTest1’ to a more meaningful ‘BinarySearchTest”.

A method with the [TestMethod] attribute is an MSTest method. Conventionally, test methods are named using the scheme Test[thisbehavior].

Creating the Test Methods

I am going to have separate test methods for arrays with:

  • odd number of elements,
  • even number of elements, and
  • just one element.

So I replace the test method created by Visual Studio with the following methods, all empty initially:

1
2
3
4
5
6
7
8
9
10
11
12
13
[TestMethod]
public void TestArrayWithOddNumberOfElements()
{
}
[TestMethod]
public void TestArrayWithEvenNumberOfElements()
{
}
[TestMethod]
public void TestArrayWithOnlyOneElement()
{
}      

I implement only one test case in the TestArrayWithOddNumberOfElements() method, as follows:

1
2
3
4
5
6
[TestMethod]
public void TestArrayWithOddNumberOfElements()
{
    int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77 };
    Assert.AreEqual(0, BinarySearch.Search(collection, 11));
}

Assert.AreEqual is one of the methods provided by MSTest, to compare the expected and the obtained results. Its syntax is:

Assert.AreEqual (<expectedValue>, <actualValue>)

where <actualValue> is replaced by a call to the method that we want to test.

Creating the BinarySearch Class

Visual Studio complains about the missing class BinarySearch. I need to have this class before proceeding further. I decide to keep the deliverable code and the test code in two separate projects under the same solution. So I create another project BinarySearchProject (Visual C#, Class Library) in the same solution.

I rename the automatically created class Class1.cs to BinarySearch.cs.

1
2
3
4
5
6
namespace BinarySearchProject
{
    public class BinarySearch
    {
    }
}

In the BinarySearchTestProject, I add a reference to the BinarySearchProject.

I go back to the BinarySearchTest class, and find that Visual Studio still complains about the missing BinarySearch class.

But that’s easy to fix. I just have to specify “using BinarySearchProject”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using BinarySearchProject;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace BinarySearchTestProject
{
    [TestClass]
    public class BinarySearchTest
    {
        [TestMethod]
        public void TestArrayWithOddNumberOfElements()
        {
        int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77 };
                Assert.AreEqual(0, BinarySearch.Search(collection, 11));
        }
        [TestMethod]
        public void TestArrayWithEvenNumberOfElements()
        {
        }
        [TestMethod]
        public void TestArrayWithOnlyOneElement()
        {
        }
    }
}

Visual Studio still complains about the missing “Search” method in the BinarySearch class. I ask Visual Studio to create one for me. I tweak the method generated by Visual studio, changing the name of the second parameter from “v” to “value”:

1
2
3
4
5
6
7
public class BinarySearch
{
    public static int Search(int[] collection, int v)
    {
        throw new NotImplementedException();
    }
}

Starting with a Failing Implementation

I must have some implementation in the Search method that returns an int. I’ll worry about the actual implementation later, but for the time being, I write a failing implementation (an implementation that should always fail) as follows:

1
2
3
4
5
6
7
public class BinarySearch
{
    public static int Search(int[] collection, int v)
    {
        return -2;
    }
}

With this failing implementation and a single test case, it is time to run the test. For this purpose, right-click the BinarySearchTest class and click “Run Tests”.

Test fails, as I can see in the Test Explorer. That was expected, of course.

Visual Studio also lets me know which test method failed, and due to which assertion. It informs me that the expected value was 0, but the actual value that it got was -2.

No problem. I have taken the first baby steps for building my test infrastructure. Time for some serious work now.

Implementing the Test Methods

I now implement all the test methods in the BinarySearchTest class, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using BinarySearchProject;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace BinarySearchTestProject
{
    [TestClass]
    public class BinarySearchTest
    {
        [TestMethod]
        public void TestArrayWithOddNumberOfElements()
        {
            int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77 };
            Assert.AreEqual(0, BinarySearch.Search(collection, 11));
            Assert.AreEqual(3, BinarySearch.Search(collection, 44));
            Assert.AreEqual(6, BinarySearch.Search(collection, 77));
            Assert.AreEqual(2, BinarySearch.Search(collection, 33));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 100));
        }
        [TestMethod]
        public void TestArrayWithEvenNumberOfElements()
        {
            int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77, 88 };
            Assert.AreEqual(0, BinarySearch.Search(collection, 11));
            Assert.AreEqual(3, BinarySearch.Search(collection, 44));
            Assert.AreEqual(4, BinarySearch.Search(collection, 55));
            Assert.AreEqual(6, BinarySearch.Search(collection, 77));
            Assert.AreEqual(7, BinarySearch.Search(collection, 88));
            Assert.AreEqual(2, BinarySearch.Search(collection, 33));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 100));
        }
        [TestMethod]
        public void TestArrayWithOnlyOneElement()
        {
            int[] collection = new int[] { 11 };
            Assert.AreEqual(0, BinarySearch.Search(collection, 11));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
            Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
        }
    }
}

Without properly implementing the BinarySearch class, I run the tests again.

The tests fail again. All of them. As expected.

Implementing the BinarySearch Class

Time to implement the BinarySearch class, finally. With some logical thinking, and some trial and error, I end up with the following code that passes all the tests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BinarySearch
    {
        public static int Search(int[] collection, int value)
        {
            int size = collection.Length;
            int lower = 0;
            int upper = size - 1;
            int middle;
            while (lower <= upper)
            {
                middle = (lower + upper) / 2;
                if (collection[middle] > value)
                {
                    upper = middle - 1;
                }
                else if (collection[middle] < value)
                {
                    lower = middle + 1;
                }
                else // we found the data
                    return middle;
            }
            return -1;
        }

This is how Visual Studio lets me know that all the tests have passed:

Trying Out Some Alternative Implementation

I decide to make a few changes to the BinarySearch class. I replace the statement

upper = middle – 1;

with

upper = middle;

And similarly, I replace the statement

lower = middle + 1;

with

lower = middle;

Here is the modified code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BinarySearch
    {
        public static int Search(int[] collection, int value)
        {
            int size = collection.Length;
            int lower = 0;
            int upper = size - 1;
            int middle;
            while (lower <= upper)
            {
                middle = (lower + upper) / 2;
                if (collection[middle] > value)
                {
                    upper = middle;
                }
                else if (collection[middle] < value)
                {
                    lower = middle;
                }
                else // we found the data
                    return middle;
            }
            return -1;
        }

I run the code, hoping to see a green bar. Or fearing a red bar. But nothing appears. The program seems to have gone into an infinite loop. I manually cancel the tests (In the Test Explorer, there is a Cancel option).

Timeout as Test Failure

I can ask MSTest to report a test as having failed if it takes longer a specified amount of time. For example, given the amount of data in my test methods, five seconds can be a very generous upper limit of time for these to complete. I can specify this time limit with a Timeout parameter (in milliseconds) as shown in the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[TestClass]
public class BinarySearchTest
{
    [TestMethod, Timeout(5000)]
    public void TestArrayWithOddNumberOfElements()
    {
        int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77 };
        Assert.AreEqual(0, BinarySearch.Search(collection, 11));
        Assert.AreEqual(3, BinarySearch.Search(collection, 44));
        Assert.AreEqual(6, BinarySearch.Search(collection, 77));
        Assert.AreEqual(2, BinarySearch.Search(collection, 33));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 100));
    }
    [TestMethod, Timeout(5000)]
    public void TestArrayWithEvenNumberOfElements()
    {
        int[] collection = new int[] { 11, 22, 33, 44, 55, 66, 77, 88 };
        Assert.AreEqual(0, BinarySearch.Search(collection, 11));
        Assert.AreEqual(3, BinarySearch.Search(collection, 44));
        Assert.AreEqual(4, BinarySearch.Search(collection, 55));
        Assert.AreEqual(6, BinarySearch.Search(collection, 77));
        Assert.AreEqual(7, BinarySearch.Search(collection, 88));
        Assert.AreEqual(2, BinarySearch.Search(collection, 33));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 100));
    }
    [TestMethod, Timeout(5000)]
    public void TestArrayWithOnlyOneElement()
    {
        int[] collection = new int[] { 11 };
        Assert.AreEqual(0, BinarySearch.Search(collection, 11));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 9));
        Assert.AreEqual(-1, BinarySearch.Search(collection, 45));
    }
}

I run my tests again. This time Visual Studio reports all the test methods as having failed because of timeout.

Back to Safety

As my experiment with the modification failed, I revert the code to the earlier version, and run the tests again. This time, as expected, all the tests pass again.

Final Words

This is an introductory tutorial on the basics of MSTest. MSTest has many more features to help in specifying the expectations from our code and verifying that these expectations continue to be met. For more details on MSTest, you may visit:
https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest


24 responses to “Unit Testing C# Code with MSTest”

  1. Muchos Gracias for your post.Really looking forward to read more. Great.

  2. Useful information. Fortunate me I discovered your site accidentally, and I am shocked why this coincidence didn’t took place in advance! I bookmarked it.

  3. Can I just say what a relief to search out somebody who actually knows what theyre talking about on the internet. You definitely know learn how to convey a problem to mild and make it important. More people need to learn this and understand this aspect of the story. I cant believe youre no more widespread since you positively have the gift.

  4. Chinen says:

    Appreciation for any educational website. Where different might just I get that sort of knowledge written in this sort of suitable process? I’ve a venture that i am just now jogging about, we have been getting the style out there intended for similarly info.. beli volumetric filler indonesia

  5. campuzhit ng says:

    It’s really a great and useful piece of info. I am glad that you simply shared this helpful info with us. Please stay us up to date like this. Thank you for sharing.

  6. Thanks for all your hard work on this web site. Kate loves managing investigations and it’s really easy to see why. Almost all hear all regarding the compelling form you provide important ideas on the website and even welcome contribution from visitors about this area of interest while our favorite girl is truly discovering a whole lot. Enjoy the remaining portion of the new year. Your carrying out a great job.

  7. go source says:

    Hello, You’ve got completed an unbelievable career. I will absolutely bing the idea as well as privately recommend to be able to my local freinds.. endorsement advertising I’m sure they will be benefited from this blog.

  8. info saham says:

    This is a interesting along with valuable part of information and facts. I am fulfilled you discussed this beneficial data around. Make sure you keep us informed similar to this. Many thanks expressing.. info saham

  9. I truly enjoy studying on this website , it contains superb content . “Dream no small dreams. They have no power to stir the souls of men.” by Victor Hugo.

  10. Ndola Jobs says:

    Hello There. I found your blog using msn. This is a really well written article. I’ll be sure to bookmark it and return to read more of your useful info. Thanks for the post. I’ll definitely comeback.

  11. You are my inhalation, I have few web logs and often run out from post :). “Fiat justitia et pereat mundus.Let justice be done, though the world perish.” by Ferdinand I.

  12. aplikasi berita saham Many thanks for your auspicious writeup. That in fact used to be some sort of leisure account this. Seem difficult for you to additional delivered pleasant within you! Nonetheless, the best way could possibly most people communicate?

  13. L’OCCITANE 歐舒丹 【巴西香氛系列】睡蓮香霧的商品介紹 L’OCCITANE 歐舒丹,巴西香氛系列,睡蓮香霧

  14. Amazing points the following. We are pretty delighted to appear this page. Thanks a lot and I am looking forward to get in touch with anyone.. aplikasi android berita saham terbaru Will you make sure you drop us a mailbox?

  15. Your post on Unit Testing C# Code with MSTest – Pragati Software is very good. We hope you can continue delivering many more article . Long live 24x7weboffers.in

  16. That may be genuinely attention-grabbing, You’re a quite qualified digg.. kumpulan youtube terbaik I’ve got registered your feed and show off onward for you to interested in more of a person’s wonderful publish. On top of that, I’ve truly provided your web site during my internet sites

  17. ~100 預防高危致癌的 HPV 16、18 型號 (可減低 70 患子宮頸癌的風險) ~100 減低引致生殖器官濕疣 (俗稱「椰菜花」) 的 HPV 6、11 型的感染 (可減低超過 90 患生殖器官濕疣的風險) HPV4合1子宮頸癌疫苗 Gardasil HPV病毒會感染人類的皮膚及黏膜,一般會透過性接觸及親密的皮膚接觸而受到感染,是一種男性與女性都可能感染的常見病毒。可感染身體各個部位的HPV超過100種,當中有部份的HPV類型可影響生殖器部位,導致生殖器疣(genital warts) 、子宮頸細胞異常(abnormal cervical cells) ,甚至子宮頸癌 (cervical cancer)。 4合1 HPV 子宮頸癌疫苗,覆蓋4種高危HPV病毒:6、 11、16及18型(約70的子宮頸癌由HPV16和HPV18病毒引致),有助預防子宮頸癌、外陰癌、陰道癌及生殖器官濕疣

  18. SMAZ換能器傳送更穩定,更安全,更有效,和疼痛更少的HIFU能量。 SMAZ不需要應用較高的能量便可到達浅肌肉腱膜層。主要治療:-抬頭紋 -眉間紋 -鼻樑紋 -魚尾紋 -法令紋 -淚溝 -木偶紋 -垂直唇紋 -嘴角紋 -頸紋

  19. 股四頭肌 says:

    關于Ion Magnum技術: 它的作用是加快脂肪代謝而轉化成肌肉。專業設計的微電流模擬大腦到肌肉的正常神經傳導。乙醯膽鹼及ATP(産生能量的物質)都是由神經末梢釋放的。神經元共振導致神經末梢持續不斷的釋放ATP,甚至能達到正常釋放量的500。 Ion Magnum應用的是世界定級的神經生理學技術,它加快脂肪燃燒的速度,增强肌肉收縮,提高基礎代謝率(指的是你靜息狀態下消耗卡路里的速率)。複雜的微電流包含2000次與正常生理過程的相互作用,由此達到人體自然狀態下所不能達到的效果。它可以加快能量的轉化,增强體力和運動能力。 Ion Magnum目前由位於英國的創新科學研究中心開發、製造,該中心是由歐盟提供資金支持的。該設備及其組件均是由英國頂級的科學家手工製作的。該産品有CE標志,CE標志是歐洲共同市場的安全標志。 Ion Magnum基於最新的起搏器技術。

  20. 豐唇蜜 says:

    FineScan 會在肌膚上製造數以千計的細小深入傷口,即所謂的顯微加熱區(microthermal zone),但要確保每次治療時皆有部份組織不受能量影響,於是,每一個顯微加熱區的作用雖然強烈而明顯,但周圍都包覆著正常且結構完整的皮膚組織,使傷口能在短時間內癒合,並替換之前有缺陷的受損組織。Finescan不僅可讓表皮新生,更可促進深層膠原再生,從內而外徹底喚醒細胞,瞬時找回年輕時的肌膚狀態。憑藉最新的雙軸技術,FINESCAN 6可治療 – 面部 – 頸部 – 暗瘡凹凸洞 – 增生性疤痕

  21. ~100 預防高危致癌的 HPV 16、18 型號 (可減低 70 患子宮頸癌的風險) ~100 減低引致生殖器官濕疣 (俗稱「椰菜花」) 的 HPV 6、11 型的感染 (可減低超過 90 患生殖器官濕疣的風險) HPV4合1子宮頸癌疫苗 Gardasil HPV病毒會感染人類的皮膚及黏膜,一般會透過性接觸及親密的皮膚接觸而受到感染,是一種男性與女性都可能感染的常見病毒。可感染身體各個部位的HPV超過100種,當中有部份的HPV類型可影響生殖器部位,導致生殖器疣(genital warts) 、子宮頸細胞異常(abnormal cervical cells) ,甚至子宮頸癌 (cervical cancer)。 4合1 HPV 子宮頸癌疫苗,覆蓋4種高危HPV病毒:6、 11、16及18型(約70的子宮頸癌由HPV16和HPV18病毒引致),有助預防子宮頸癌、外陰癌、陰道癌及生殖器官濕疣

  22. 電波溶脂 says:

    CO2激光(CO2 laser / 二氧化碳激光)的波長是10600nm,照射到皮膚上會被皮膚的水份吸收,瞬間將皮膚有問題的組織氣化。CO2激光可以用來消除各種皮膚問題包括疣、癦、痣、脂溢性角化、粉刺和汗管瘤等。當治療後,您的皮膚需要5至10天時間復原。期間保持傷口清潔便可。優點:CO2激光所切割的深度比刮除術較深,亦較精準。可以處理較深層的皮膚問題,例如去除癦、油脂粒、肉粒、疣、珍珠疣、角質增生等。其復原亦較快,減少留下疤痕的機會。它最大的優點在於,能夠進一步減少激光治療過程當中的熱損傷反應,提升了激光治療的安全性,治療過程中幾乎沒有疼痛感

  23. 由全球生長因子與胜肽韓國廠商CAREGEN研發,利用美國專利「KP7-4胜肽技術」,獨特滲透配方提供高穩定、高滲透、高效能的胜髮環境,模擬人體生髮機制,目的使頭皮、毛囊恢復健康及作用活性,重啟生髮系統。DR CYJ髮胜肽療程的治療原理為 利用複合活性成分配方恢復毛髮平衡, 根據生態生物工程原理研發, 關鍵胜肽名為KP7-4,結合了七種專利胜肽, 實驗證明能有效模擬「人體胜髮因子」,掌握育髮四關鍵:毛囊強健、減緩異常落髮、強化髮根、供給毛囊血管營養,模擬毛髮循環機制,同時減緩異常落髮及強化髮根。DR.CYJ髮胜肽不含藥性且無副作用,能有效促進增髮

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2017 Pragati Software Pvt. Ltd. All Rights Reserved.

Enquiry