Как да пишем модулни тестове правилно
Здравейте. Те пишат в Интернет, че тестваният метод винаги трябва да бъде изолиран от всякакви зависимости, в противен случай тестваният метод ще изтегли външни методи от същия или друг клас по време на изпълнението си, което противоречи на тестването на единици, тъй като в този случай няма да бъде тестван един обект, а взаимодействие между няколко обекта. Вярно ли е това твърдение?
Имах този въпрос, след като научих за модулни тестове в Yii framework. LoginFormTest::testLoginNoUser() извиква метода LoginForm::login(), който вътрешно извиква LoginForm::getUser() и процесът на изпълнение надхвърля класа LoginForm до класа User. В резултат на това се оказва, че са тествани LoginForm::login(), LoginForm::getUser() и User::findByUsername(). Но защо. В края на краищата, не трябва да искам да тествам работата на метода User::findByUsername() тук, искам да го направя в друг тест.
Може ли това да се нарече модулно тестване или все още е интеграционно тестване? Сега се оказва, че User::findByUsername() е имплицитно тестван в LoginFormTest и също ще бъде изрично тестван в UserTest, това нормално ли е? И ако е така, добре ли е да изхвърлите всичко в една директория и модулни тестове и интеграционни тестове? Къде е ръбът.
Не е ясно какво сте искали да получите в отговор, защото не сте задали ясен въпрос.
Първо, разбира се, вие "за щастие" сте избрали първата версия на Yii като пример. Тази рамка не е много подходяща за създаване на "тестваем" код, тъй като съдържа голямо количество "магия" на всички етапи на функциониране. не вярвате? Опитайте се да изградите нещо на базата на CActiveRecord и тестове за файлови единици. Ще получите всичко, но не и това, от което се нуждаете. Най-важният аспект на модулното тестване е, че един тест (методclass-test) трябва да решава строго една задача, а не да проверява цялата подсистема във фонов режим. В един от моите проекти реших този проблем, като написах цял куп мъничета. Второ, всичко зависи от задачите. Грубо казано, модулните тестове тестват кода такъв, какъвто е. Следващото ниво на тестове (няма да го назовавам, защото постоянно ги бъркам) проверява бизнес сценарии. И най-високото ниво проверява всичко във връзка с външни интерфейси. И трето, един тест не трябва да включва кода на други тестове, защото всеки тест трябва да бъде изолиран, като се предполага, че всички други кодове работят. Ето защо, когато пишете, например, тест за малък модел, не е необходимо да управлявате работа с базата данни: счита се, че цялата подсистема за взаимодействие с базата данни е _работеща_.
Да, и още. Те често бъркат подигравки и мъничета. Кодът е мъниче - код, който "заглушава" изпълнението на друг. Целта на мъничето е да тества какво _какво_ връща обектът при своята работа. Във вашия случай имате нужда от някакъв обект, който няма да позволи кодът да бъде изпълнен по-нататък LoginForm::login(). Как да го направим? Със статично писане на код - няма как. Имаме нужда от добавка, която динамично да използва тези обекти, така че да могат да бъдат заменени с мъничета. Мокът е добавка към тестван обект, чиято цел е да тества как работи обектът вътре, поради което макетите винаги се изграждат върху Reflection.
Моля, бъдете по-внимателни. Като пример избрах Yii версия 2. Даде пример. И зададе ясен въпрос. Ето го
> Може ли това да се нарече модулно тестване или все още е интеграционно тестване?
И тогава той попита. Критично ли е в процеса на тестване на един метод косвено да се тестват и някои други методи на системата. Исках да разбера дали винаги е необходимо да се подиграва всичко в модулните тестовепристрастяване или не. Ако е така, тогава защо разработчиците на Yii са мислили различно?
Зададох ясен въпрос, на който ти за съжаление даде отговор, от който нищо не става ясно.
xfg: не, IMHO, това вече не са модулни тестове, защото се тества твърде много последователност от действия. Това е, което описах на второто ниво, говорейки за тестове за бизнес сценарии.
Нека просто кажем, че ако единичен тест не успее недвусмислено да идентифицира метод с грешка (без четене на следи и отстраняване на грешки), тогава това не е единичен тест.
За това защо разработчиците на Yii имат такъв поглед върху тестовете. Всеки песяк си хвали блатото (в) Ето отговора. Всеки има свои граници и критерии.
И отговорих на въпроса ви: >> Най-важният аспект на модулното тестване е, че един тест (метод на тестовия клас) трябва да решава точно една задача, а не да проверява цялата подсистема във фонов режим.