Nunit и уеб приложения

Започвам да изучавам Unit testing с "(NUnit)". Знам, че този тип тестване се използва за тестване на "класове", "функции" и "взаимодействието между тези функции".

В моя случай разработвам "asp.net уеб приложения".

  • Как мога да използвам това тестване, за да тествам моите страници (тъй като се счита за клас и използваните методи) и в каква последователност?, имам три слоя:

    1. Интерфейсен слой(.cs на всяка страница).

    2. Слой за достъп до данни (клас за всеки обект) (DAL).

    3. Слой на база данни (който съдържа връзка към базата данни, отворена връзка, затворена връзка,....и т.н.).

    4. Бизнес слой(понякога за извършване на изчисления или някаква отделна логика).

  • Как да тествам методите, които правят връзка с базата данни?

  • Как да се уверя, че тестването ми не е загуба на време?.

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


Отговори (1)


Има единични и интеграционни тестове. Единичното тестване е тестване на единични компоненти/класове/методи/функции и взаимодействие между тях, но само с един реален обект (тествана система-SUT) и тестови дубли. Тестовите дубли могат да бъдат разделени на мъничета и фалшиви. Stubs предоставят подготвени тестови данни на SUT. По този начин изолирате SUT от околната среда. Така че не е нужно да натискате база данни, уеб или wcf услуги и така нататък и имате едни и същи входни данни всеки път. Mocks се използват, за да се провери дали 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 - Тествана система или клас. Това е, което тествате. Test doubles - идва от stunt doubles. Те правят опасни сцени във филмите, за да не се налага на истинските актьори. И тук е така. Тестовите дубли заместват реални обекти в тестовете, така че да можете да изолирате 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;
    }
}

Как ще проверите дали този клас прави това, което трябва в навечерието на Нова година? Трябва да го направите на Нова година :)

Сега вижте модифициран парти клас Пример за мъниче:

    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;
        }
    }

Сега в тест Можете да предадете фалшивия часовник на парти класа

        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