Показаны сообщения с ярлыком Microsoft. Показать все сообщения
Показаны сообщения с ярлыком Microsoft. Показать все сообщения

четверг, 10 октября 2013 г.

Бесконечная рекурсия сводит Microsoft unit testing framework с ума

Совершенно случайно наткнулся на странное поведение юнит-тестов Microsoft. Нажимаю запуск всех тестов, проходит несколько секунд... И возвращаюсь в исходное состояние. Тестов как будто и не запускалось...Никаких ошибок, исключений, предупреждений, ничего... Некоторые тесты по отдельности запускались и успешно отрабатывали, а некоторые нет...
При отладке одного из тестов, вводящих Visual Studio в ступор, я увидел-таки заветную ошибку "An unhandled exception of type 'System.StackOverflowException' occurred". Получается, что при ошибке переполнения стека (например, из-за бесконечной рекурсии) простой запуск юнит-тестов не возвращает ошибку, а исключение "проглатывается" системой запуска тестов...
Например, такой код приведет к подобному поведению:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace RecursionUnitTest
{
    public class Recurse
    {
        public int Run()
        {
            return Run();
        }
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestRecursion()
        {
            Recurse rec = new Recurse();

            Assert.AreEqual(0, rec.Run());
        }
    }
}

пятница, 20 сентября 2013 г.

Сравнение коллекций/массивов в юнит-тестах Microsoft

Если вы используете фреймворк для юнит тестов, встроенный в Visual Studio, сравнение полученного результата с ожидаемым обычно производите используя класс Assert.
Но, если попробовать сравнить значения в коллекции или массиве (например, int[]) Assert.AreEqual() будет возвращать false для разных экземпляров массивов, даже если содержимое массивов одинаково.

Например:
[TestMethod]
public void TestArraysEquality()
{
  int[] array1 = new int[] { 1, 2, 3 };

  Assert.AreEqual(new int[] { 1, 2, 3 }, array1);
}

В результате тест завершается с ошибкой Assert.AreEqual failed.
Причина в том, что с массивом Assert.AreEqual проверяет равенство ссылок. Для простого примера, наподобие приведенного, можно просто написать три ассерта, по одному на каждый элемент... Но это решение на любителя. Или можно воспользоваться классом CollectionAssert, который пройдет через весь массив и проверит каждый элемент на равенство.
[TestMethod]
public void TestArraysEquality()
{
  int[] array1 = new int[] { 1, 2, 3 };

  CollectionAssert.AreEqual(new int[] { 1, 2, 3 }, array1);
}

Теперь тест завершится успешно.
К сожалению. CollectionAssert не обходит внутренние коллекции, и, если сравнить коллекцию коллекций, например, List<<int>>, то CollectionAssert.AreEqual все равно завершится ошибкой.