TDD: Как бы вы работали над этим классом, в стиле первого теста?
Я пишу небольшое приложение для обучения ASP.NET MVC, и одной из его функций является возможность поиска книг на Amazon (или других сайтах) и добавления их на "книжную полку".
Поэтому я создал интерфейс под названием IBookSearch (с методом DoSearch) и реализацию AmazonSearch, которая выглядит следующим образом
public class AmazonSearch : IBookSearch
{
public IEnumerable<Book> DoSearch(string searchTerms)
{
var amazonResults = GetAmazonResults(searchTerms);
XNamespace ns = "http://webservices.amazon.com/AWSECommerceService/2005-10-05";
var books= from item in amazonResults.Elements(ns + "Items").Elements(ns + "Item")
select new Book
{
ASIN = GetValue(ns, item, "ASIN"),
Title = GetValue(ns, item, "Title"),
Author = GetValue(ns, item, "Author"),
DetailURL = GetValue(ns, item, "DetailPageURL")
};
return books.ToList();
}
private static XElement GetAmazonResults(string searchTerms)
{
const string AWSKey = "MY AWS KEY";
string encodedTerms = HttpUtility.UrlPathEncode(searchTerms);
string url = string.Format("<AMAZONSEARCHURL>{0}{1}",AWSKey, encodedTerms);
return XElement.Load(url);
}
private static string GetValue(XNamespace ns, XElement item, string elementName)
{
//Get values inside an XElement
}
}
В идеале я хотел бы сделать это в стиле TDD, сначала написать тест и все такое. Но я должен признаться, у меня возникли проблемы с обдумыванием этого.
Я мог бы создать FakeSearch, который реализует DoSearch() и вернуть некоторые специальные книги, но я не думаю, что это приносит какую-то ценность в данный момент, не так ли? Может быть, позже, когда у меня есть код, который использует список книг.
Что еще я мог проверить первым? Единственный тест, о котором я могу подумать, - это тот, который проверяет вызов в облаке (в GetAmazonResults) и затем проверяет, что DoSearch может правильно выполнить выбор Linq2XML и вернуть правильный список. Но мне кажется, что этот тип теста может быть написан только после того, как у меня есть некоторый код на месте, так что я знаю, что подделать.
Какой-нибудь совет о том, как вы, парни и девушки, пошли бы, выполняя этот тестовый стиль?
3 ответа
Кажется, что ваша главная проблема здесь - это знать, когда писать фиктивный код. Я понимаю вашу точку зрения: если вы еще не написали код, как вы можете высмеивать его?
Я думаю, что ответ заключается в том, что вы хотите запустить свой TDD с очень, очень простых тестов, как это делает Кент Бек в Test Driven Development. Начните с написания теста, который вызывает DoSearch и утверждает, что то, что вы получаете, не равно нулю, и напишите некоторый код, чтобы выполнить этот шаг. Затем напишите тест, который утверждает, что вы извлекаете нужное количество книг для известного поискового запроса, и напишите код для его прохождения. В конце концов вы дойдете до того момента, когда вам понадобится получить действительные, действительные данные Книги, чтобы пройти тест, и в этот момент вам будет написана часть DoSearch, и вы сможете подумать над ее издевательством (или его частью).).
Вы захотите написать макет, когда тестируете код, который использует поиск, а не для тестирования самого поиска.
Для класса выше, я мог бы проверить по:
- поиск общей книги и проверка того, что оно найдено и действительно.
- поиск случайной фиксированной строки "kjfdskajfkldsajklfjafa" и проверка того, что книги не найдены
- так далее
Но... и вот большой, я никогда не издевался над классом, который я тестировал, я издевался над классами, которые он использовал.
Короче говоря: FakeSearch будет использоваться при проверке правильности работы интерфейса при нажатии кнопки "Поиск". Я мог убедиться, что он вызывается и что пользовательский интерфейс правильно обрабатывает возвращенные книги.
Надеюсь, это поможет.
В этом классе основное внимание уделяется тому, чтобы он правильно интегрировался с веб-сервисами Amazon. Поскольку этот веб-сервис не принадлежит вам, вы не должны насмехаться над ним, потому что у вас нет глубоких знаний о том, как он работает. "Только издевайтесь над вашими типами", "Не издевайтесь над сторонними библиотеками" и т. Д.
Вот несколько способов решения проблемы:
Напишите тест, который подключается к реальному веб-сервису по сети, возможно, в поисках какой-нибудь очень популярной книги, которой вы можете доверять, будут издаваться годами. Это дает хорошую уверенность в том, что вы используете службу правильно, но она также подвержена множеству ложных срабатываний - например, иногда сеть может быть недоступна или данные в удаленной системе изменяются. Таким образом, вам также понадобятся тесты, которые...
Напишите тесты для файлов статических данных, которые основаны на данных из реального веб-сервиса. Чтобы получить тестовые данные, вы можете вручную делать запросы к веб-сервису и записывать ответы в файл *. Вам нужно будет смоделировать сетевое соединение (либо используя заглушку, которая не работает в сети, либо запустив встроенный веб-сервер в тестах и подключившись к нему вместо реального URL). Таким образом, вы можете легко протестировать все виды угловых случаев и состояний ошибок, и данные всегда будут доступны и остаются неизменными, независимо от того, что происходит с реальным веб-сервисом. Одно предостережение в том, что если API реального веб-сервиса изменится, эти тесты его не заметят, поэтому вам также понадобятся некоторые тесты, написанные для реального веб-сервиса (как упомянуто выше).
* Например, однажды я использовал cron и небольшой скрипт оболочки для загрузки каждые несколько минут данных из веб-службы, которая содержала постоянно меняющуюся информацию о расписании. Сбор таких данных в течение нескольких недель был очень полезен в качестве тестовых данных. Из этих данных я создал статические ответы, которые содержали все виды особых случаев, которые я заметил в реальных данных. Это также было полезно для настройки поддельного веб-сервиса и "машины времени", которая воспроизводила ранее записанные данные, чтобы наша система могла использоваться без доступа к реальному веб-сервису.