Nunit и веб-приложения

Я начинаю изучение Unit testing с "(NUnit)". Я знаю, что этот тип тестирования используется для проверки «классов», «функций» и «взаимодействия между этими функциями».

В моем случае я разрабатываю «веб-приложения asp.net».

  • Как я могу использовать это тестирование для проверки своих страниц (поскольку оно считается классом и используемыми методами) и в какой последовательности? У меня есть три слоя:

    1. Слой интерфейса (CS каждой страницы).

    2. Уровень доступа к данным (класс для каждого объекта) (DAL).

    3. Уровень базы данных (содержит соединение с базой данных, открытое соединение, закрытое соединение и т. д.).

    4. Бизнес-уровень (иногда для расчета или отдельной логики).

  • Как протестировать методы, которые подключаются к базе данных?

  • Как сделать так, чтобы мое тестирование не было пустой тратой времени?

person Anyname Donotcare    schedule 30.05.2011    source источник


Ответы (1)


Есть модульные и интеграционные тесты. Модульное тестирование — это тестирование отдельных компонентов/классов/методов/функций и взаимодействия между ними, но только с одним реальным объектом (тестируемая система-SUT) и тестовыми двойниками. Тестовые двойники можно разделить на заглушки и макеты. Заглушки предоставляют подготовленные тестовые данные для SUT. Таким образом вы изолируете SUT от окружающей среды. Таким образом, вам не нужно обращаться к базам данных, веб-службам или службам wcf и т. Д., И у вас каждый раз есть одни и те же входные данные. Макеты используются для проверки того, что SUT работает должным образом. SUT вызывает методы для фиктивного объекта, даже не зная, что это не настоящий объект. Затем вы проверяете, что SUT работает, утверждая фиктивный объект. Вы можете написать заглушки и макеты вручную или использовать один из многих фреймворков. Одним из них является http://code.google.com/p/moq/.

Если вы хотите протестировать взаимодействие с базой данных, это интеграционное тестирование, и, как правило, это намного сложнее. Для интеграционного тестирования необходимо настроить внешние ресурсы в хорошо известном состоянии.

Возьмем ваши слои:

  1. Вы не сможете провести модульное тестирование. Страница тесно связана со средой выполнения ASP.NET. Вы должны стараться, чтобы в коде не было много кода. Просто вызовите некоторые объекты из своего кода и протестируйте эти объекты. Вы можете посмотреть шаблоны дизайна MVC. Если вам нужно протестировать свою страницу, вам следует посмотреть http://watin.org/. Он автоматизирует ваш интернет-браузер, нажимает кнопки на странице и проверяет, что страница отображает ожидаемый результат.

  2. Это интеграционное тестирование. Вы помещаете данные в базу данных, затем читаете их и сравниваете результаты. После теста или перед тестом Вы должны привести тестовую базу данных в хорошо известное состояние, чтобы тесты можно было повторять. Мой совет - настраивать базу данных до тестовых прогонов, а не после тестовых прогонов. Таким образом, вы сможете проверить, что находится в базе данных после сбоя теста.

  3. Я действительно не знаю, чем это отличается от того, что в пункте нет. 2.

  4. И это модульное тестирование. Создайте объект в тесте, вызовите его методы и проверьте результаты.

Как тестировать методы, которые подключаются к БД, рассмотрено в пункте 2. Как не терять время? Это придет с опытом. У меня нет общего совета, кроме как не тестировать свойства, в которых нет никакой логики.

Для получения отличной информации о модульном тестировании смотрите здесь:

http://artofunittesting.com/

https://rads.stackoverflow.com/amzn/click/com/0321146530

http://www.amazon.com/Growing-Object- Oriented-Software-Guided-Tests/dp/0321503627/ref=sr


public class NotTestableParty
{
    public bool ShouldStartPreparing()
    {
        if (DateTime.Now.Date == new DateTime(2011, 12, 31))
        {
            Console.WriteLine("Prepare for party!");
            return true;
        }
        Console.WriteLine("Party is not today");
        return false;
    }
}
2?ie=UTF8&s=books&qid=1306787051&sr=1-2

http://www.amazon.com/xUnit-Test- Patterns-Refactoring-Code/dp/0131495054/ref=sr


public class NotTestableParty
{
    public bool ShouldStartPreparing()
    {
        if (DateTime.Now.Date == new DateTime(2011, 12, 31))
        {
            Console.WriteLine("Prepare for party!");
            return true;
        }
        Console.WriteLine("Party is not today");
        return false;
    }
}
1?ie=UTF8&s=books&qid=1306787051&sr=1-1

Редактировать:

SUT, CUT — тестируемая система или класс. Это то, что Вы тестируете. Пробные двойники - происходит от дублеров. Они делают опасные сцены в фильмах, чтобы настоящим актерам не приходилось. То же самое. Тестовые двойники заменяют реальные объекты в тестах, чтобы вы могли изолировать SUT/CUT в тестах от окружающей среды.

Давайте посмотрим на этот класс


public class NotTestableParty
{
    public bool ShouldStartPreparing()
    {
        if (DateTime.Now.Date == new DateTime(2011, 12, 31))
        {
            Console.WriteLine("Prepare for party!");
            return true;
        }
        Console.WriteLine("Party is not today");
        return false;
    }
}

Как вы будете проверять, что этот класс делает то, что должен в канун Нового года? Это надо сделать в новогоднюю ночь :)

Теперь посмотрим на модифицированный класс Party. Пример заглушки:

    public class Party
    {
        private IClock clock;

        public Party(IClock clock)
        {
            this.clock = clock;
        }

        public bool ShouldStartPreparing()
        {
            if (clock.IsNewYearsEve())
            {
                Console.WriteLine("Prepare for party!");
                return true;
            }
            Console.WriteLine("Party is not today");
            return false;
        }
    }

    public interface IClock
    {
        bool IsNewYearsEve();
    }

    public class AlwaysNewYearsEveClock : IClock
    {
        public bool IsNewYearsEve()
        {
            return true;
        }
    }

Сейчас в тесте. Вы можете передать фальшивые часы классу Party.

        var party = new Party(new AlwaysNewYearsEveClock());
        Assert.That(party.ShouldStartPreparing(), Is.True);

И теперь Вы знаете, работает ли Ваш вечерний класс в канун Нового года. AlwaysNewYearsEveClock — это заглушка.

Теперь посмотрите на этот класс:

    public class UntestableCalculator
    {
        private Logger log = new Logger();

        public decimal Divide(decimal x, decimal y)
        {
            if (y == 0m)
            {
                log.Log("Don't divide by 0");
            }

            return x / y;
        }
    }

    public class Logger
    {
        public void Log(string message)
        {
            // .. do some logging
        }
    }

Как вы будете проверять, что ваш класс регистрирует сообщение. В зависимости от того, где вы его регистрируете, вам нужно проверить файл, базу данных или какое-то другое место. Это будет не юнит-тест, а интеграционный тест. Для модульного тестирования вы делаете это.

    public class TestableCalculator
    {
        private ILogger log;
        public TestableCalculator(ILogger logger)
        {
            log = logger;
        }
        public decimal Divide(decimal x, decimal y)
        {
            if (y == 0m)
            {
                log.Log("Don't divide by 0");
            }
            return x / y;
        }
    }

    public interface ILogger
    {
        void Log(string message);
    }
    public class FakeLogger : ILogger
    {
        public string LastLoggedMessage;
        public void Log(string message)
        {
            LastLoggedMessage = message;
        }
    }

И в тесте Вы можете

var logger = new FakeLogger();
        var calculator = new TestableCalculator(logger);
        try
        {
            calculator.Divide(10, 0);
        }
        catch (DivideByZeroException ex)
        {
            Assert.That(logger.LastLoggedMessage, Is.EqualTo("Don't divide by 0"));
        }

Здесь Вы утверждаете о поддельном регистраторе. Поддельный регистратор — это фиктивный объект.

person Piotr Perak    schedule 30.05.2011
comment
Большое спасибо, Пери, некоторые понятия не ясны, можете ли вы объяснить, что вы подразумеваете под Test doubles,stubs ,mocks,SUT... Я действительно не знаю, чем это отличается от пункта №. 2. уровень базы данных использует базу данных напрямую, уровень доступа к данным состоит из класса для каждого объекта (отображение) и использует уровень базы данных для доступа к данным и выполнения операций CRUD. - person Anyname Donotcare; 31.05.2011