Unit Testing Search and Sort method(s)

I just decided to write a unit test, and see how to do it. This is my unit test:

[TestMethod]
public void TestSearchSort()
{
System.IO.File.WriteAllText(@"C:\Users\Hosch250\Documents\Visual Studio 2013\Projects\ConsoleApplication14\ConsoleApplication14\TestFile.cs", string.Empty);

var TestInstance = new Program();
var titles = new List<string>();
string[] query = { "main", "menu" };

Program.Search(ref titles, ref query);

var expectedTitles = new List<string>();
"The File Menu", "Draw", "Windows Phone Notebooks",
"Windows Phone Sections", "Windows Phone Pages" };

using (var file = new System.IO.StreamWriter(@"C:\Users\Hosch250\Documents\Visual Studio 2013\Projects\ConsoleApplication14\ConsoleApplication14\TestFile.cs", true))
{
file.WriteLine("Expected Count: " + expectedTitles.Count);
file.WriteLine("Actual Count: " + titles.Count);
}

Assert.AreEqual(expectedTitles.Count, titles.Count);
for (var i = 0; i < titles.Count; i++)
{
using (var file = new System.IO.StreamWriter(@"C:\Users\Hosch250\Documents\Visual Studio 2013\Projects\ConsoleApplication14\ConsoleApplication14\TestFile.cs", true))
{
file.WriteLine("Expected Title: " + expectedTitles[i]);
file.WriteLine("Actual Title: " + titles[i]);
}
Assert.AreEqual(expectedTitles[i], titles[i]);
}
}


This is the method it tests:

public static void Search(ref List<string> resultTitles, ref string[] query)
{
List<int> weight = new List<int>();

int position = -1;

foreach (string[] array in SearchKeys.Keys)
{
position++;
int length = array.Length;
int middle = length / 2;
char firstCharMidArray = array[middle][0];

foreach (string s in query)
{
int min = array[middle][0] < s[0] ? middle : 0;
int max = array[middle][0] <= s[0] ? array.Length : middle + 1;

for (int i = min; i < max; i++)
{

if (array[i] == s)
{
if (weight[position] == 0)
{
}
weight[position]++;

}
}
}
}

StableSort(ref resultTitles, ref weight);
}


I write to the file in the test method so I can see where/how it failed. How did I do? Should I be doing anything different? Should I have more tests? I most certainly cannot run every possible combination of search terms.

var expectedTitles = new List<string>();
"The File Menu", "Draw", "Windows Phone Notebooks",
"Windows Phone Sections", "Windows Phone Pages" };


This can just be written as

var expectedTitles = new List<string>
{
"The File Menu", "Draw", "Windows Phone Notebooks",
"Windows Phone Sections", "Windows Phone Pages"
};


var TestInstance = new Program();


This isn't used and can be removed.

There's a convenience method CollectionAssert.AreEqual that can be used.

Two collections are equal if they have the same elements in the same order and quantity. Elements are equal if their values are equal, not if they refer to the same object. The values of elements are compared using Equals by default.

It will give you error messages like this

CollectionAssert.AreEqual failed. (Different number of elements.)

CollectionAssert.AreEqual failed. (Element at index 0 do not match.)

One way of writing unit tests is called arrange-act-assert. Following that method and using the above recommendations, the code would look like this

var expectedTitles = new List<string>
{
"The File Menu", "Draw", "Windows Phone Notebooks",
"Windows Phone Sections", "Windows Phone Pages"
};

var titles = new List<string>();
string[] query = { "main", "menu" };
Program.Search(ref titles, ref query);

CollectionAssert.AreEqual(expectedTitles, titles);


I write to the file in the test method so I can see where/how it failed.

Don't do that. This:

using (var file = new System.IO.StreamWriter(@"C:\Users\Hosch250\Documents\Visual Studio 2013\Projects\ConsoleApplication14\ConsoleApplication14\TestFile.cs", true))
{
file.WriteLine("Expected Count: " + expectedTitles.Count);
file.WriteLine("Actual Count: " + titles.Count);
}


Has just become a possible reason for your test to fail that has nothing to do with your test. For example, if this was part of a test suite in a repo on GitHub, I couldn't run this test successfully. It's important that tests be portable and deal only with the code under test.

If you really want to know exactly which item caused your test to fail, use the overload that takes a message string.