Функциональные тесты - это расширенный набор юнит-тестов, не так ли?
Я уже давно читаю о модульных и функциональных тестах.
Если я напишу исчерпывающие функциональные тесты, не будут ли они, в свою очередь, охватывать и нижележащие модули, что, в свою очередь, сделает излишние тесты модулей?
Мы придерживаемся гибкого подхода и пишем функциональные тесты с использованием WebDriver, как только мы закончим с "кусочком" функциональности, который обычно составляет 2-4 недели времени на спринт.
1 ответ
Возможно, но не обязательно.
Функциональные тесты можно рассматривать как тесты "черного ящика", при которых вы смотрите на определенную функцию (независимо от того, является ли это единственным методом, модулем, системой и т. Д.) И проверяете, что для заданного ввода вы получаете заданный вывод.
Однако, если функциональный тест не пройден, все, что вы можете сказать, это то, что система неисправна; это не обязательно дает вам представление о том, какая часть системы виновата. Конечно, вы уйдете и диагностируете проблему, но заранее не знаете, в чем проблема.
например
//assuming you have a UserService that amongst other things passes through to a UserRepository
var repo = new UserRepository();
var sut = new UserService(repo);
var user = sut.GetUserByID(1);
Assert.IsNotNull(user); //Suppose this fails.
В приведенном выше случае, вы не знаете, если это потому, что GetUserByID()
функция неисправна - возможно, она не называется repo.GetUserByID
и просто вернул ноль, возможно, он получил User
от repo
но случайно вернул неинициализированную временную переменную и т. д. - или, возможно, это потому, что зависимость (repo
) сам по себе неисправен. В любом случае вам придется отладить проблему.
Модульные тесты, с другой стороны, больше похожи на тесты "белого ящика", когда вы эффективно сняли укрытие с системы и тестируете, как система ведет себя, чтобы делать то, что вы хотите, чтобы она делала.
например (код ниже может не скомпилироваться и только для демонстрационных целей)
//setup a fake repo and fake the GetUserByID method to return a known instance:
var repo = new Mock<UserRepository>();
var user = new User{ID=1;}
repo.Setup(r=>r.GetUserByID(1).Returns(user);
var sut = new UserService(repo.Object);
var actual= sut.GetUserByID(1);
//now make sure we got back what we expected. If we didn't then UserService has a problem.
Assert.IsNotNull(user);
Assert.AreEqual(user,actual);
В этом случае вы явно проверяете, что sut.GetUserByID()
ведет себя ожидаемым образом - что он вызывает repo.GetUserByID()
и возвращает результирующий объект, не искажая и не изменяя его.
Если этот модульный тест пройден, но функциональный тест не пройден, вы можете с уверенностью сказать, что проблема не в UserService
, но с UserRepository
класс, даже не глядя на код. Это может или не может сэкономить ваше время, это действительно зависит от того, насколько сложны ваши функциональные блоки.