# exampleTest

1. ComTest C# -examples

ComTest is a small helper language to make writing NUnit tests easier. The tests are written to program comment using ComTest macro language and then those comments are translated to NUnit tests.

On examples below one can run tests and look what kind of NUnit tests are generated.

ComTest comment block should include:

    /// <example>
    /// <pre name="test">
    ///    ... mix of ComTest language and normal C#
    /// </pre>
    /// </example>

1.1 Testing functions with Input/Output

Functions that uses for example ReadLine or WriteLine are not easy to test. It is possible with help of some helper objects that capture input and/or ouput, but they are out of the scope of this course. So those functions we do not test in this course.

1.2 ComTest test operators

Open plugin

1.3 Function that returns an int

# Matrix
public class Matrix
{
    public static void Main(string[] args)
    {
        int[,] m = {{2,4,1}, {9,2,0}, {5,6,1}, {0,12,3}};
        int r = Matrix.WhatRowContains(m, 12);
        System.Console.WriteLine("Rivi {0} sisältää luvun {1}", r, 12);
    }

    /// <summary>
    /// Find what line of matrix contains the search value
    /// </summary>
    /// <param name="mat">Matrix where we search</param>
    /// <param name="value">value we search</param>
    /// <returns>row index where we found the value.
    /// If many lines contains the value, we return the first index.
    /// If the matrix does not contain value, return -1</returns>
    /// <example>
    /// <pre name="test">
    /// int[,] m = {{2,4,1}, {9,2,0}, {5,6,1}, {0,12,3}};
    /// WhatRowContains(m, 1) === 0;
    /// WhatRowContains(m, 0) === 1;
    /// WhatRowContains(m, 12) === 3;
    /// WhatRowContains(m, 11) === -1;
    /// </pre>
    /// </example>
    public static int WhatRowContains(int[,] mat, int value)
    {
        for (int iy = 0; iy < mat.GetLength(0); iy++)
            for (int ix = 0; ix < mat.GetLength(1); ix++)
            {
                int item = mat[iy, ix];
                if (item == value) return iy;
            }
        return -1;
    }
}

 

# shellint

Run previous test and then run this command to see generated NUnit test file

cat MatrixTest.cs

 

1.4 Testing string-value

# HalfOfString
    /// <summary>
    /// Returns half of the string
    /// </summary>
    /// <param name="s">String to get the first half</param>
    /// <returns>First half of s</returns>
    /// <example>
    /// <pre name="test">
    ///  Half("") === "";
    ///  Half("Abba") === "Ab";
    ///  Half("Mouse") === "Mo";
    ///  Half("A") === "";
    /// </pre>
    /// </example>
    public static string Half(string s)
    {
        int len = s.Length;
        return s.Substring(0,len/2);
    }

 

1.5 Testing StringBuilder-value

Because StringBuilder is not a string, it must be converted to a string before testing.

When utilizing a void subroutine that modifies its parameters passed by reference, it is necessary to call the subroutine first and after that inspect the altered state of the parameters.

# HalfOfStringBuilder0
    /// <summary>
    /// Removes the right half of StringBuilder
    /// </summary>
    /// <param name="s">StringBuilder where half is left</param>
    /// <example>
    /// <pre name="test">
    ///  StringBuilder sb = new StringBuilder("Abba");
    ///  Half(sb);
    ///  sb.ToString() === "Ab";
    ///
    ///  sb = new StringBuilder("Mouse");
    ///  Half(sb);
    ///  sb.ToString() === "Mo";
    ///
    ///  sb = new StringBuilder("Eagles");
    ///  Half(sb);
    ///  sb.ToString() === "Eag";
    ///
    ///  sb = new StringBuilder("");
    ///  Half(sb);
    ///  sb.ToString() === "";
    ///
    ///  sb = new StringBuilder("E");
    ///  Half(sb);
    ///  sb.ToString() === "";
    /// </pre>
    /// </example>
    public static void Half(StringBuilder sb)
    {
        int len = sb.Length;
        sb.Remove(len/2,len-len/2);
    }

 

In the manner described above, each test will consist of at least 3 lines. Even those 3 lines could be writen to one line, when writing code in a TDD mindset, consideration is given to making the code as easy to test and read as possible. In this case, it is advisable to change the void subroutine to the function returning the most significant thing for testing purposes. In the previous example, it was the reference to StringBuilder. Consequently, each test can ultimately be condensed to one line.

# HalfOfStringBuilder1
    /// <summary>
    /// Removes the right half of StringBuilder
    /// </summary>
    /// <param name="s">StringBuilder where half is left</param>
    /// <returns>Reference to changes StringBuilder</returns>
    /// <example>
    /// <pre name="test">
    ///  StringBuilder sb = new StringBuilder("Abba");
    ///  Half(sb).ToString() === "Ab";
    ///  sb = new StringBuilder("Mouse");
    ///  Half(sb).ToString() === "Mo";  // Actually sb variable can now be avoided
    ///  Half(new StringBuilder("Eagles")).ToString() === "Eag";
    ///  Half(new StringBuilder("")).ToString() === "";
    ///  Half(new StringBuilder("E")).ToString() === "";
    /// </pre>
    /// </example>
    public static StringBuilder Half(StringBuilder sb)
    {
        int len = sb.Length;
        sb.Remove(len/2,len-len/2);
        return sb;
    }

 

To make things even shorter there is an ComTest operator =S= that converts both side ToString() before comparison.

# HalfOfStringBuilder2
    /// <summary>
    /// Removes the right half of StringBuilder
    /// </summary>
    /// <param name="s">StringBuilder where half is left</param>
    /// <returns>Reference to changes StringBuilder</returns>
    /// <example>
    /// <pre name="test">
    ///  Half(new StringBuilder("Abba")) =S= "Ab";
    ///  Half(new StringBuilder("Mouse")) =S= "Mo";
    ///  Half(new StringBuilder("Eagles")) =S= "Eag";
    ///  Half(new StringBuilder("")) =S= "";
    ///  Half(new StringBuilder("E")) =S= "";
    /// </pre>
    /// </example>
    public static StringBuilder Half(StringBuilder sb)
    {
        int len = sb.Length;
        sb.Remove(len/2,len-len/2);
        return sb;
    }

 

# shellsb2

Run previous test and then run this command to see generated NUnit test file

cat HalfOfStringBuilder2Test.cs

 

1.6 Testing 1-dim array

When testing the whole contents of 1-dim array, the old way is to change it to a string using Join-function.

# Numbers1
    /// <summary>
    /// Returns an arrays with numbers [0 - n-1]
    /// </summary>
    /// <param name="n">How many numbers needed</param>
    /// <returns>Arrys with numbers 0,1,...,n-1</returns>
    /// <example>
    /// <pre name="test">
    ///  String.Join(",",GiveNumbers(0)) === "";
    ///  String.Join(",",GiveNumbers(1)) === "0";
    ///  String.Join(",",GiveNumbers(3)) === "0,1,2";
    /// </pre>
    /// </example>
    public static int[] GiveNumbers(int n)
    {
        int[] result = new int[n];
        for (int i = 0; i < n; i++) result[i] = i;
        return result;
    }

 

Again to make things shorter, there is operator =J= that uses String.Join(", ", leftside) to the left side of comparison.

# Numbers2
    /// <summary>
    /// Returns an arrays with numbers [0 - n-1]
    /// </summary>
    /// <param name="n">How many numbers needed</param>
    /// <returns>Arrys with numbers 0,1,...,n-1</returns>
    /// <example>
    /// <pre name="test">
    ///  GiveNumbers(0) =J= "";
    ///  GiveNumbers(1) =J= "0";
    ///  GiveNumbers(3) =J= "0, 1, 2";
    /// </pre>
    /// </example>
    public static int[] GiveNumbers(int n)
    {
        int[] result = new int[n];
        for (int i = 0; i < n; i++) result[i] = i;
        return result;
    }

 

# shellnumbers2

Run previous test and then run this command to see generated NUnit test file

cat Numbers2Test.cs

 

In newer .net version it is also possible to compare arrays directly. That is best way if values are double-values.

# onedimarray1n
    /// <summary>
    /// Returns an arrays with numbers [0 - n-1]
    /// </summary>
    /// <param name="n">How many numbers needed</param>
    /// <returns>Arrys with numbers 0,1,...,n-1</returns>
    /// <example>
    /// <pre name="test">
    ///  GiveNumbers(0) === new int[0];
    ///  GiveNumbers(1) === new int[]{0};
    ///  GiveNumbers(3) === new int[]{0,1,2};
    /// </pre>
    /// </example>
    public static int[] GiveNumbers(int n)
    {
        int[] result = new int[n];
        for (int i = 0; i < n; i++) result[i] = i;
        return result;
    }

 

If function changes values in array, one must first call function and then test the changed array. Many times this can be done by joining the array to string.

# ChangeWordsArray1
    /// <summary>
    /// Changes mid word if possible.
    /// </summary>
    /// <param name="words">Where to change word</param>
    /// <param name="newQWord">new value for mid word</param>
    /// <example>
    /// <pre name="test">
    ///  string[] words = {"cat", "dog", "eagle", "elephant"};
    ///  ChangeMid(words, "mouse");
    ///  words =J= "cat, mouse, eagle, elephant";
    ///
    ///  words = new string[]{"cat"};
    ///  ChangeMid(words, "fox");
    ///  words =J= "fox";
    ///
    ///  words = new string[]{};
    ///  ChangeMid(words, "fox");
    ///  words.Length === 0;
    /// </pre>
    /// </example>
    public static void ChangeMid(string[] words, string newWord)
    {
        if (words.Length == 0) return;
        int mid = (words.Length-1) / 2;
        words[mid] = newWord;
    }

 

Previous is quite long way to test and in TDD spirit it might be good idea to do function that returns a reference to changed array. And then creating the array to test in function call, every test case can be implemented in one row.

# ChangeWordsArray2
    /// <summary>
    /// Changes mid word if possible.
    /// </summary>
    /// <param name="words">Where to change word</param>
    /// <param name="newQWord">new value for mid word</param>
    /// <example>
    /// <pre name="test">
    ///  string[] words = {"cat", "dog", "eagle", "elephant"};
    ///  ChangeMid(words, "mouse") =J= "cat, mouse, eagle, elephant";
    ///  ChangeMid(new string[]{"cat"}, "fox") =J= "fox";
    ///  ChangeMid(new string[]{}, "fox") =J= "";
    /// </pre>
    /// </example>
    public static string[] ChangeMid(string[] words, string newWord)
    {
        if (words.Length == 0) return words;
        int mid = (words.Length-1) / 2;
        words[mid] = newWord;
        return words;
    }

 

# shellChangeWordsArray2

Run previous test and then run this command to see generated NUnit test file

cat ChangeWordsArray2Test.cs

 

If the array is not needed after test, it is possible to create array on the function call.

# ArraySum
    public static void Main()
    {
        int[] lengthOfMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int days = Sum(lengthOfMonths);
        System.Console.WriteLine("Days in a year: " + days);

    }


    /// <summary>
    /// Calculates sum of an int array
    /// </summary>
    /// <param name="array">int array to sum</param>
    /// <returns>sum of array</returns>
    /// <example>
    /// <pre name="test">
    ///    int[] numbers = {1,2,3};
    ///    Sum(numbers) === 6;
    ///    numbers = new int[0];
    ///    Sum(numbers) === 0;
    ///    Sum(new int[]{3,4}) === 7; // without extra variable
    /// </pre>
    /// </example>
    public static int Sum(int[] array)
    {
        int sum = 0;
        foreach (int item in array)
            sum += item;
        return sum;
    }

 

# testinglists

1.7 Testing lists

Lists can be tested almost same way than 1-dim arrays. So lists can be tested be converting them to string by String.Join. Nowadays better method is test lists directly. In number lista, especially double lists, that prevents problems with decimal symbols.

# ListOfNumbers
    /// <summary>
    /// Return list with values from start by step count n
    /// </summary>
    /// <param name="first">first list element</param>
    /// <param name="step">step between list values</param>
    /// <param name="n">number of list values</param>
    /// <returns>list with values</returns>
    /// <example>
    /// <pre name="test">
    ///    ListOf(0.0, 1.0, 3) === new List<double>{0.0, 1.0, 2.0};
    ///    ListOf(1.0, 0.5, 4) === new List<double>{1.0, 1.5, 2.0, 2.5};
    ///    ListOf(1.0, 0.5, 0) === new List<double>{};
    /// </pre>
    /// </example>
    public static List<double> ListOf(double first, double step, int n)
    {
        List<double> list = new List<double>();
        double val = first;
        for (int i = 1; i <= n; i++, val+=step)
            list.Add(val);
        return list;
    }

 

If function changes values in list, one must first call function and then test the changed list. Many times this can be done by joining the array to string.

# ChangeWordsList1
    /// <summary>
    /// Changes mid word if possible.
    /// </summary>
    /// <param name="words">Where to change word</param>
    /// <param name="newQWord">new value for mid word</param>
    /// <example>
    /// <pre name="test">
    ///  List<string> words = new List<string>{"cat", "dog", "eagle", "elephant"};
    ///  ChangeMid(words, "mouse");
    ///  words =J= "cat, mouse, eagle, elephant";
    ///
    ///  words = new List<string>{"cat"};
    ///  ChangeMid(words, "fox");
    ///  words =J= "fox";
    ///
    ///  words = new List<string>();
    ///  ChangeMid(words, "fox");
    ///  words.Count === 0;
    /// </pre>
    /// </example>
    public static void ChangeMid(List<string> words, string newWord)
    {
        if (words.Count == 0) return;
        int mid = (words.Count-1) / 2;
        words[mid] = newWord;
    }

 

Previous is quite long way to test and in TDD spirit it might be good idea to do function that returns a reference to changed list. And then creating the list to test in function call, every test case can be implemented in one row.

# ChangeWordsList2
    /// <summary>
    /// Changes mid word if possible.
    /// </summary>
    /// <param name="words">Where to change word</param>
    /// <param name="newQWord">new value for mid word</param>
    /// <example>
    /// <pre name="test">
    ///  List<string> words = new List<string>{"cat", "dog", "eagle", "elephant"};
    ///  ChangeMid(words, "mouse") =J= "cat, mouse, eagle, elephant";
    ///  ChangeMid(new List<string>{"cat"}, "fox") =J= "fox";
    ///  ChangeMid(new List<string>(), "fox") =J= "";
    /// </pre>
    /// </example>
    public static List<string> ChangeMid(List<string> words, string newWord)
    {
        if (words.Count == 0) return words;
        int mid = (words.Count-1) / 2;
        words[mid] = newWord;
        return words;
    }

 

# shellChangeWordsList2

Run previous test and then run this command to see generated NUnit test file

cat ChangeWordsList2Test.cs

 

1.8 Be careful with double values converted to string

In different cultures the decimal symbol is different. For example in Finland it is comma (,) and in USA it is period (.).

To prevent problems with converting double values to strings, it might be best to change the culture to some fixed culture before test code by inserting code like:

/// System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo("en-US");

Note that this requires at least 4.6 version of .Net framework.

With older .Net version the safest is:

/// var ci = new System.Globalization.CultureInfo("fi-FI");
/// ci.NumberFormat.NumberDecimalSeparator = ".";
/// System.Threading.Thread.CurrentThread.CurrentCulture = ci;
# matrix

1.9 Testing 2-dim array

One way to test 2-dim arrays (matrix) is to test few important values like:

mat[0,0] ~~~ 0.1;
mat[1,1] ~~~ 0.7;

Another old way to test is to convert the matrix to a string using:

String.Join(" ",mat.Cast<double>()) === "0.1 0.3 0.5 0.7";

The problem with that is that if we have two matrices with the same values, but in different number of rows and columns, we may get wrong result.

# Matrices1
    /// <summary>
    /// Create a matrix starting from x1, step by dx
    /// and do totally nx x ny numbers
    /// </summary>
    /// <param name="ny">how many rows</param>
    /// <param name="nx">how many columns</param>
    /// <param name="x1">start value</param>
    /// <param name="dx">increment</param>
    /// <returns>matrix with nx x ny numbers</returns>
    /// <example>
    /// <pre name="test">
    ///    System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo("en-US");
    ///    double[,] mat = Matrix(2,2,0.1,0.2);
    ///    mat[0,0] ~~~ 0.1;
    ///    mat[1,1] ~~~ 0.7;
    ///    String.Join(" ", mat.Cast<double>()) === "0.1 0.3 0.5 0.7";
    ///    // and shorter:
    ///    String.Join(" ", Matrix(0,0,0.1,0.1).Cast<double>()) === "";
    ///    String.Join(" ", Matrix(1,1,0.2,0.1).Cast<double>()) === "0.2";
    ///    String.Join(" ", Matrix(2,2,0.1,0.2).Cast<double>()) === "0.1 0.3 0.5 0.7";
    /// </pre>
    /// </example>
    public static double[,] Matrix(int ny, int nx, double x1, double dx)
    {
        double[,] t = new double[ny,nx];
        double x = x1;
        for (int iy = 0; iy < ny; iy++)
            for (int ix = 0; ix < nx; ix++, x += dx)
                t[iy,ix] = x;
        return t;
    }

 

In current .net one can test also 2D matrices directly.
Also one benefit is that decimal symbol has no harmful effect.

# Matrices2
    /// <summary>
    /// Create a matrix starting from x1, step by dx
    /// and do totally nx x ny numbers
    /// </summary>
    /// <param name="ny">how many rows</param>
    /// <param name="nx">how many columns</param>
    /// <param name="x1">start value</param>
    /// <param name="dx">increment</param>
    /// <returns>matrix with nx x ny numbers</returns>
    /// <example>
    /// <pre name="test">
    ///    double[,] mat = Matrix(2,2,0.1,0.2);
    ///    mat[0,0] === 0.1;
    ///    mat[1,1] === 0.7;
    ///    mat === new double[,]{{0.1, 0.3}, {0.5, 0.7}};
    ///    Matrix(0,0,0.1,0.1) === new double[0,0];
    ///    Matrix(1,1,0.2,0.1) === new double[,]{{0.2}};
    ///    Matrix(2,2,0.1,0.2) === new double[,]{{0.1, 0.3}, {0.5, 0.7}};
    /// </pre>
    /// </example>
    public static double[,] Matrix(int ny, int nx, double x1, double dx)
    {
        double[,] t = new double[ny, nx];
        double x = x1;
        for (int iy = 0; iy < ny; iy++)
            for (int ix = 0; ix < nx; ix++, x += dx)
                t[iy, ix] = x;
        return t;
    }

 

Implementation of Jonoksi-function

1.10 Testing floating point numbers

Because of the internal representation of the floating point numbers, they can not be compared with an "equal" sign, but compare whether they fall within a certain "tolerance", a margin.

# DoubleAlmost
    /// <example>
    /// <pre name="test">
    /// double d = 0.1;
    /// d ~~~ 0.1;
    /// </pre>
    /// </example>

 

The default tolerance is 6 digits and it can be changed by #TOLERANCE:

# DoubleTolerance
    /// <example>
    /// <pre name="test">
    /// #TOLERANCE=0.01
    /// double d = 0.101;
    /// d ~~~ 0.1;
    /// </pre>
    /// </example>

 

In current .net it is also possible to test floating points directly. Default tolerance is 0.000001.

# DoubleEqTolerance
    /// <example>
    /// <pre name="test">
    /// #TOLERANCE=0.01
    /// double d = 0.101;
    /// d === 0.1;
    /// </pre>
    /// </example>

 

# THROWS

1.11 Expecting an exception

If some test SHOULD throw an exception, it can be written like:

# ExpectException
    /// <example>
    /// <pre name="test">
    ///    string cat = "cat";
    ///    cat[0] === 'c'
    ///    cat[7] === 'a'  #THROWS IndexOutOfRangeException
    ///    cat[2] === 't'
    /// </pre>
    /// </example>

 

and then if it DOES NOT throw an excption, it is test error. The value (in this case a) does not matter, because the exception comes before the value is used. So in this kind of tests the value can be arbitrary. The exception name should be checked from API-documents, or it could be own exception class if user have done that and throws it in test case.

# shellExpectException

Run previous test and then run this command to see generated NUnit test file

cat ExpectExceptionTest.cs

 

# testprint

1.12 Testings subroutines that print something

It is not easy to test a subroutine that prints something. But those subroutines can be designed so that testing comes easier. Instead of:

# print1
    public static void PrintPartOfArray(int[] array, int start, int len)
    {
        for (int i=start; i<start+len; i++)
           Console.Write(array[i] + " ");
        Console.WriteLine();
    }
}

 

divide the subroutine to function that formats the string to print and then print that string. Test the function:

# print2
    public static void PrintPartOfArray(int[] array, int start, int len)
    {
        Console.WriteLine(FormatPartOfArray(array, start, len));
    }



    /// <example>
    /// <pre name="test">
    ///    FormatPartOfArray(new int[]{1,2,3,4,5,6},1,2) === "2 3 ";
    ///    FormatPartOfArray(new int[]{1,2,3,4,5,6},0,1) === "1 ";
    ///    FormatPartOfArray(new int[]{1,2},0,3) === "1 "; #THROWS IndexOutOfRangeException
    /// </pre>
    /// </example>
    public static string FormatPartOfArray(int[] array, int start, int len)
    {
        StringBuilder result = new StringBuilder();
        for (int i=start; i<start+len; i++)
           result.Append(array[i] + " ");
        return result.ToString();
    }
}

 

1.13 Test using table format

Sometimes complicated tests may be hard to write and even harder to read what should be result by what parameters. This can be simplified by ComTest Table format. The idea is to write one template test and mark test and result parameters by names starting by $-sign. Then one writes table where parameters are in columns. A textual replacement is made to change the template test to real test.

Below is examples from previous examples by using table format. Note that in table's header line column separator | must be separated by at least one space from column name. And at least one empty line should separate test template from test table.

# MatrixTbl
    /// <example>
    /// <pre name="test">
    /// int[,] m = {{2,4,1}, {9,2,0}, {5,6,1}, {0,12,3}};
    /// WhatRowContains(m, $value) === $row;
    ///
    ///    $value | $row
    ///  ------------------
    ///       1   |  0
    ///       0   |  1
    ///      12   |  3
    ///      11   | -1
    /// </pre>
    /// </example>
    public static int WhatRowContains(int[,] mat, int value)
    {
        for (int iy = 0; iy < mat.GetLength(0); iy++)
            for (int ix = 0; ix < mat.GetLength(1); ix++)
            {
                int item = mat[iy, ix];
                if (item == value) return iy;
            }
        return -1;
    }
}

 

# shellMatrixTbl

Run previous test and then run this command to see generated NUnit test file

cat MatrixTblTest.cs

 

# HalfOfStringTbl
    /// <example>
    /// <pre name="test">
    ///  Half($param) === $result;
    ///
    ///    $param  | $result
    ///   -------------------
    ///    ""      | ""
    ///    "Abba"  | "Ab"
    ///    "Mouse" | "Mo"
    ///    "A"     | ""
    /// </pre>
    /// </example>
    public static string Half(string s)
    {
        int len = s.Length;
        return s.Substring(0,len/2);
    }

 

# shellHalfOfStringTbl

Run previous test and then run this command to see generated NUnit test file

cat HalfOfStringTblTest.cs

 

# HalfOfStringBuilderTbl
    /// <example>
    /// <pre name="test">
    ///  StringBuilder sb;
    ///  sb = new StringBuilder($param);
    ///  Half(sb);
    ///  sb.ToString() === $result;
    ///
    ///    $param  | $result
    ///   -------------------
    ///    ""      | ""
    ///    "Abba"  | "Ab"
    ///    "Mouse" | "Mo"
    ///    "A"     | ""
    /// </pre>
    /// </example>
    public static StringBuilder Half(StringBuilder sb)
    {
        int len = sb.Length;
        sb.Remove(len/2,len-len/2);
        return sb;
    }

 

# shellHalfOfStringBuilderTbl

Run previous test and then run this command to see generated NUnit test file

cat HalfOfStringBuilderTblTest.cs

 

# ListOfNumbersTbl
    /// <summary>
    /// Return list with values from start by step count n
    /// </summary>
    /// <param name="first">first list element</param>
    /// <param name="step">step between list values</param>
    /// <param name="n">number of list values</param>
    /// <returns>list with values</returns>
    /// <example>
    /// <pre name="test">
    ///    ListOf($first, $step, $n) === new List<double>$result;
    ///
    ///      $first | $step | $n |  $result
    ///   ----------------------------------------------
    ///       0.0   | 1.0   | 3  | {0.0, 1.0, 2.0}
    ///       1.0   | 0.5   | 4  | {1.0, 1.5, 2.0, 2.5}
    ///       1.0   | 0.5   | 0  | {}
    /// </pre>
    /// </example>
    public static List<double> ListOf(double first, double step, int n)
    {
        List<double> list = new List<double>();
        double val = first;
        for (int i = 1; i <= n; i++, val+=step)
            list.Add(val);
        return list;
    }

 

# shellListOfNumbersTbl

Run previous test and then run this command to see generated NUnit test file

cat ListOfNumbersTblTest.cs

 

# Matrices2Tbl
    /// <summary>
    /// Create a matrix starting from x1, step by dx
    /// and do totally nx x ny numbers
    /// </summary>
    /// <param name="ny">how many rows</param>
    /// <param name="nx">how many columns</param>
    /// <param name="x1">start value</param>
    /// <param name="dx">increment</param>
    /// <returns>matrix with nx x ny numbers</returns>
    /// <example>
    /// <pre name="test">
    ///    Matrix($ny,$nx,$x1,$dx) === new double[,]$result;
    ///
    ///        $ny | $nx | $x1 | $dx | $result
    ///      ---------------------------------------------------
    ///         2  |  2  | 0.1 | 0.2 | {{0.1, 0.3}, {0.5, 0.7}}
    ///         0  |  0  | 0.1 | 0.1 | {}
    ///         1  |  1  | 0.2 | 0.1 | {{0.2}}
    ///         2  |  2  | 0.1 | 0.2 | {{0.1, 0.3}, {0.5, 0.7}}
    /// </pre>
    /// </example>
    public static double[,] Matrix(int ny, int nx, double x1, double dx)
    {
        double[,] t = new double[ny, nx];
        double x = x1;
        for (int iy = 0; iy < ny; iy++)
            for (int ix = 0; ix < nx; ix++, x += dx)
                t[iy, ix] = x;
        return t;
    }

 

# shellMatrices2Tbl

Run previous test and then run this command to see generated NUnit test file

cat Matrices2TblTest.cs

 

# Time
    /// <example>
    /// <pre name="test">
    /// Time t;
    //  t = new Time($h,$m);
    /// t.Add($amin);    t.ToString() === $result;
    ///
    ///    $h  | $m  | $amin | $result
    /// -------------------------------
    ///    13  | 16  | 27    | "13:43"
    ///    12  | 15  | 50    | "13:05"
    ///     0  |  1  | 2     | "00:03"
    /// </pre>
    /// </example>
    public void Add(int minutes) {
        int totalMin = h * 60 + m + minutes;
        h = totalMin / 60;
        m = totalMin % 60;
    }

 

# shellTimeTbl

Run previous test and then run this command to see generated NUnit test file

cat TimeTest.cs

 

2. Problems

2.1 VS solution verkkolevyllä

Jos solution sijaitsee verkkolevyllä, ei Comtest toimi, koska VS ei luota verkkolevyihin eikä siksi suostu lataamaan Comtestin solutioniin tekemiä tiedostoja.

Tilanteen voi korjata avaamalla

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE 

kansiossa (tai minne ikinä asensitkaan VS:n) olevan devenv.exe.config -tiedoston ja lisäämällä siihen yhden rivin. Mutta jotta kaikki olisi mahdollisimman vaikeaa, on ko. tiedostoon kirjoittaminen estetty (tai ainakin minulla oli), joten joudut avaamaan suosikki tekstieditorisi administratorina (hiiren kakkosnappi -> Run as Administrator) että voit muokata tuota tiedostoa. Tuohon tiedostoon pitää lisätä rivi

<loadFromRemoteSources enabled="true" /> 

heti rivin

<runtime>

perään. Tallenna tiedosto ja käynnistä VS varmuuden vuoksi uudelleen, ja ComTestin pitäisi nyt toimia.

2.2 Known problems

  • does not work with Visual Studio Express (contains no test framework)
  • may not work on mounted or substed drives (sometimes works???).
    The project must be in real local physical disk drive.
  • if you get an error saying something like No output from ComTest, there are two options:
    • your path to ComTest.jar is not correct in Tools/ComTest/Options. Please check it and correct.
    • you have a virus scanner that prevents the run, see later below.
  • if you get an error that says something like: ComTest: File not found, then your Java is not found. Either you have not installed the Java or it is not in the path. In first case install Java, in second case add the full path for Java:
    • go to command line and write:

       dir c:\java.exe /s

      you should get something like:

        Directory of c:\Program Files (x86)\Java\jre7\bin
      
        12.06.2013  21:43           175 016 java.exe
                   1 File(s)        175 016 bytes
    • in this example case (the path can be something else also), go to your Visual Studion and open Tools/ComTest/Options and write to Java-path: (note also the "):

       "c:\Program Files (x86)\Java\jre7\bin\java.exe"
  • if you use namespace and your namespace have same name than your class, then you may have problems when using classname. Like:

     public namespace Matrix
     {
       public class Matrix
       {
      ...
      /// Matrix.WhatRowContains(m, 12) === 3;

    Solution:

    1. Do not use classname at all.

    2. Change the name of namespace or the class.

    3. Write the the test line using both namespace and classname:

      /// Matrix.Matrix.WhatRowContains(m, 12) === 3;
  • classes, methods and possible namespaces must be public.
  • if you load new Plugin, load the new ComTest.jar at the same time.
  • sometimes when run tests in Solution that Contains Jypeli (XNA), says that "Specified cast is not valid" or "No such interface supported...". Then it helps to delete all generated Test-projects that include Jypeli (XNA).
  • some virus scanners may prevent the run for Java or ComTest. The result is a screen where its says: "No output from ComTest".
  • the snippet installer does not work if you have the Windows Phone SDK installed. This is not something we can fix, unfortunately. See: MSDN forum post
  • if you get error like:

      C:\Users\documents\visual (Unknown) || skipped: file not found
      studion (Unknown) || skipped: file not found
      ...

    then your project (or solution) is under path where is spaces in pathname. Please move to directory where is no spaces in the name.

  • if you get error like:

      Picked up _JAVA_OPTIONS: -Djava.vendor="Sun Microsystems Inc."
      Error occurred during initialization of VM
      java/lang/NoClassDefFoundError: java/lang/Object

    then at least one case the java was somehow damaged. Changed to use other java.exe in other directory helped. You may try to go to command line and look what its says ig you run exactly same Java like:

      "C:\Program Files (x86)\Java\jre7\bin\java.exe" -version

    if you still get the error, the Java is damaged.

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.