Menu

Writing a .Net Core Bubble Sort using TDD in Visual Studio Code

16th December 2019 - c#, dotnetcore, vscode

A lot of areas packed into that title!

Today we’ll be looking at quite a different pipeline to your standard .net development. Using the new (ish) kid on the block, and all round text-ide darling, Visual Studio Code.

This article was originally just a small stroll down bubble-sort lane, as a kind of cheat sheet for development, but it become apparent it was also an opportunity to thrash around in TDD and Visual Studio Code.

Lets start by installing the .net core SDK, currently at version 3.1 (Dec 2019). This will give you the command line dotnet command, that we’ll use in Visual Studio Code to run tests and compile the script.

After that, install Visual Studio Code and the following extensions from https://marketplace.visualstudio.com;

Now all that is installed, lets discuss bubble sorting (also known as a comparison sort).

Just like a bubble of Carbon Dioxide travelling from the base of a glass of 7-up to the surface, bubble sort is all about moving.

Starting with a list of numbers, a bubble sort will compare pairs, and swap them until the list is sorted in the desired order.

The number of swaps required is calculated as O(n2), meaning that the maximum number of swaps required is n2, or the length of the list squared. As such, bubble-sort is the least optimal way of sorting, but by far the easiest to detect sorting issues, because of it’s simplicity.

With that information, we can now go on an create a project, and a test that will determine whether our code will be able to sort a list of numbers into ascending numerical order.

Start up Visual Studio Code into an empty folder and start the terminal using Ctrl+’ or via the menu.

Create a new .net core nunit project.

PS C:\repo\coding-blog> dotnet new nunit

This command will create a project, named after the containing folder and containing two files, a .proj file containing all the dependencies and the code file, containing the code.

We write our test, with a single simple Test Cases

[TestCase(new []{2,1,3,4,5},new[]{1,2,3,4,5})]
public void Test_BubbleSort(int[] startingArray, int[] expectedArray){
 CollectionAssert.AreEqual(expectedArray,BubbleSort(startingArray));
}

Add the BubbleSort method in the same class as the test.

public int[] BubbleSort(int[] arr){
    return arr;
}

Compile and run the tests in the terminal by running

dotnet test

As every good TDD person knows, we now have failing test, but compiling code.

Test run for M:\p\coding-blog\bin\Debug\netcoreapp3.1\coding-blog.dll(.NETCoreApp,Version=v3.1)
Microsoft (R) Test Execution Command Line Tool Version 16.3.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...

A total of 1 test files matched the specified pattern.

  X Test_BubbleSort([2, 1, 3, 4, 5],[1, 2, 3, 4, 5]) [38ms]
  Error Message:
     Expected and actual are both <System.Int32[5]>
  Values differ at index [0]
  Expected: 1
  But was:  2

  Stack Trace:
     at coding_blog.Tests.Test_BubbleSort(Int32[] startingArray, Int32[] expectedArray) in M:\p\coding-blog\UnitTest1.cs:line 13



Test Run Failed.
Total tests: 1
     Failed: 1
 Total time: 0.6986 Seconds

Lets alter the bubble sort method so that it passes the test.

public int[] BubbleSort(int[] arr){
   for(var i=0; i < arr.Length-1;i++){
      if(arr[i]>arr[i+1]){
           var tmp=arr[i];
           arr[i]=arr[i+1];
           arr[i+1]=tmp;
      }
   }
   return arr;
 }

And running the tests reveals that we’re good

Test run for M:\p\coding-blog\bin\Debug\netcoreapp3.1\coding-blog.dll(.NETCoreApp,Version=v3.1)
Microsoft (R) Test Execution Command Line Tool Version 16.3.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...

A total of 1 test files matched the specified pattern.


Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 0.6682 Seconds

The next step in any TDD toolbook is to optimise the code, and using the testcase as a safety net. Obviously, at this point “BubbleSort” seems a very silly name for this method, as the desired outcome should dictate it’s naming, not the algorithm of the method. So we’d generally look at what we want the method to do (SortNumerically) and name accordingly

Then we would be able to test alternative means of sorting arrays in your application, adding StopWatches to determine speed and creating huge test cases, using TestCaseSource. All the time, your tests will prevent you adding code which will cease to return the desired effect.

public int[] SortNumerically(int[] arr){
    // use third party sort
    return MySortingLibraryDependency.Sort(arr,SortMe.Ascending);
}

I hope this was helpful in first steps for TDD and .net core using Visual Studio Code.

Take care.