Модульный тест VS не видит ожидаемые и фактические результаты как равные - PullRequest
0 голосов
/ 28 мая 2018

В ближайшем будущем мы переходим к разработке в стиле TDD, поэтому я пробую VS Unit Test, который поставляется с VS 2013 (именно это мы и используем на работе).Я пытаюсь использовать TDD, чтобы написать класс, который найдет константу Капрекара.Я нахожусь в стадии разработки, у меня есть тест, который отправляет действительное число, и я ожидаю, что мне будет возвращен список, содержащий один элемент.Этот элемент будет состоять из массива из 3 ячеек.Три ячейки будут содержать исходное число, число с цифрами в порядке убывания и число с цифрами в порядке возрастания.Мой код отладки показывает, что я получил ожидаемые результаты обратно, но модульный тест говорит, что нет.Что мне нужно сделать, чтобы модульный тест видел равные ожидаемые и фактические результаты?Вот сокращенная версия моего кода.

Код модульного теста:

namespace KaprekarsConstantTest
{
[TestClass]
public class UnitTest1
{
    private Kaprekar k;

    [TestInitialize]
    public void Init()
    {
        k = new Kaprekar();
    }

    [TestMethod]
    public void FirstRow()
    {
        int[] row = new int[3];
        row[0] = 5324;
        row[1] = 5423;
        row[2] = 2345;
        List<int[]> expected = new List<int[]>();
        expected.Add(row);
        List<int[]> actual = k.Generate(5324);
        int[] rslt = actual[0];
        int[] expct = expected[0];
        CollectionAssert.AreEqual(expected, actual,
            "\nExpect: " + expct[0].ToString() + "; " + expct[1].ToString() + "; " + expct[2].ToString() +
            "\nActual: " + rslt[0].ToString() + "; " + rslt[1].ToString() + "; " + rslt[2].ToString() + "\n");
    }
  }
}

Код приложения

namespace KaprekarsConstant
{
public class Kaprekar
{
    public List<int[]> Generate(params int[] orgNum)
    {
        List<int[]> rtnVal = new List<int[]>();
        int num = orgNum[0];
        string digits = num.ToString();
        int[] row = new int[3];
        row[0] = num;
        List<int> lstDigits = new List<int>();
        string snglNum = String.Empty;
        for (int ndx = 0; ndx < 4; ndx++)
        {
            snglNum = digits[ndx].ToString();
            lstDigits.Add(int.Parse(snglNum));
        }
        lstDigits.Sort();
        string dNum = String.Empty;
        for (int ndx = 3; ndx > -1; ndx--)
            dNum = dNum + lstDigits[ndx].ToString();
        row[1] = int.Parse(dNum);
        string aNum = String.Empty;
        for (int ndx = 0; ndx < 4; ndx++)
            aNum = aNum + lstDigits[ndx].ToString();
        row[2] = int.Parse(aNum);
        rtnVal.Add(row);
        return rtnVal;
    }
  }
}

Результат теста

Имя теста: FirstRow

Полное имя теста: KaprekarsConstantTest.UnitTest1.FirstRow

Источник теста: *… \Проекты \ C_Sharp \ KaprekarsConstant \ KaprekarsConstantTest \ UnitTest1.cs: строка 51

Результат теста: Сбой

Продолжительность теста: 0: 00: 00.0033773

Сообщение о результате: CollectionAssert.AreEqual не удалось.

Ожидается: 5324;5423;2345

Фактически: 5324;5432;2345

(Элемент с индексом 0 не совпадает.)

Результат StackTrace: в KaprekarsConstantTest.UnitTest1.FirstRow () в… \ Projects \ C_Sharp \ KaprekarsConstant \ KaprekarsConstantTest\ UnitTest1.cs: строка 61

1 Ответ

0 голосов
/ 28 мая 2018

Существует две причины, по которым этот тест не пройден:

  • Первый элемент (элемент 0) каждого списка представляет собой массив из трех элементов.На самом деле они не совпадают - вторыми элементами первого элемента являются 54 23 и 54 32 .Даже если вы это исправите, произойдет сбой, потому что ...

  • Во-вторых, вам нужно указать .NET выполнить структурное сравнение элементов списка, этопо умолчанию выполняется сравнение ссылок на объекты, т. е. равенство ссылок для каждого массива int [].

Измените вашу коллекцию следующим образом:

CollectionAssert.AreEqual(
    expected, actual, 
    System.Collections.StructuralComparisons.StructuralComparer,
    "\nExpect: " + ... // omitted for brevity
);

и тест пройдёт.

Если вы просто сравните массивы, структура теста сделает частичное сравнение, поэтому этот тест, например, пройдет:

[TestMethod]
public void WillCompareByElement()
{
    var x = new[] { 3, 2 };
    var y = new[] { 3, 2 };

    CollectionAssert.AreEqual(x, y);
}

Вы можете получить более четкие сообщения об ошибках теста, повторяющиеся по каждому элементу списка и сравниваемые таким образом.

Кроме того, вы можете рассмотреть возможность использования приличной библиотеки утверждений, такой как mustly.Затем вы можете написать:

expected.ShouldBe(actual);

и получить вывод, например:

Message: Test method SOTestEquals.UnitTest1.SecondRow threw exception: 
Shouldly.ShouldAssertException: [[5324, 5423, 2345]]
    should be
[[5324, 5432, 2345]]
    but was not
    difference
[*[5324, 5423, 2345]*]

Сохраняя записываемый вами вывод.

...