Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
мы очень эффективно смогли решить проблему тестирования, написав бэкенд для SQLITE, который может работает только в оперативной памяти
bool SuperPuperClass::hasAnyStudents() {
return !this.studentsList.empty();
}
bool SuperPuperClass::hasAnyStudents() { return !this.studentsList.empty(); }
Что мы в этом примере должны проверять? Что метод std::list::empty() работает как надо?
Очень часто стоит только сказать коллеге: «Там упало пару тестов и надо...» он даже договорить не даст
Вот когда будет, тогда и надо задуматься о том что пора писать тест.
А если весь день писали код, завтра выходной — суббота или воскресение, или вообще отпуск? А вдруг не дай бог грипп? Будете откладывать комммит?
bool ElfParser::isCorrected( const char * data, int data_len );
лучше применять вопросы: «Насколько сложна функция? Код функции уже устоялся?». Если оба вопроса «да», значит пишем тест, иначе мы просто задолбаемся актуализировать тесты.
и тогда лучше ему не юнит-тесты читать, а с проектом знакомиться
Сначала пишу пользовательский код, как будто предстоящий код уже написан. Исходя из написанного понимаю что и как нужно делать.
Ну так ведь это другой вид, тестирования и в юнит тестировании их не должно быть
унит тесты должны тестировать только одну ответсвенность, в правильном коде в котором соблюдены правила SOLID, одной ответсвенности соответсвует один класс.
В итоге все другое не как не отностится к модульным тестам, в соответсвии с чем запускается намного реже.
Класс может использовать базу данных, а может не использоватьЕсли класс содержит бизнес-логику, то он не должен стучаться к базе напрямую ни при каких обстоятельствах. Есть паттерн «репозиторий». Такие классы скрывают собой базу данных, предоставляя над ней некую абстракцию. На них тоже нужны юнит-тесты, но они тоже по-хорошему не должны стучаться к настоящей БД, а использовать ту же SQLite с хранилищем в памяти, потому что это быстро и позволяет запускать тесты не настраивая никаких дополнительных сервисов типа сервера баз данных, достаточно только IDE и компилятора.
использовать ту же SQLite с хранилищем в памяти
Сам же ConsoleWriter не тестируется в силу его тривиальности.
DateTime.Now уже нужно. В этом случае мы создаём «обёртку» с методом Now() которая просто делегирует вызов стандартному DateTime. И эту «обёртку» мы не тестируем.Так же и с базой данных. Не нужно имитировать базу данных. Нужно ее изолировать. С O/RM это делается вполне себе красиво.
Извините не хотел не кого обидеть, не кого тролить.
Ну так это уже совсем другая история, которая зовется «НАГРУЗОНОЕ ТЕСТИРОВАНИЕ», при которых выявляется как раз тоги, слабые места приложения.
его разработчик — по идеи написал тесты и описал как правильно работать с ним в документации
public class ArticlesRepository : IArticlesRepository
{
// Здесь используется ORM. Неважно какая.
private ORM _orm = new ORM();
// Пример вымышленный. Вместо массива может быть всё, что угодно.
public Article[] GetPublishedArticles()
{
return _orm.Articles.Where(a => a.Published).ToArray();
}
}
public class ArticlesClient
{
private IArticlesRepository _articlesRepository;
public ArticlesClient(IArticlesRepository articlesRepository)
{
_articlesRepository = articlesRepository;
}
public int CalculatePublishedArticles()
{
return _articlesRepository.GetPublishedArticles().Length;
}
}
ArticlesClient тоже может реализовывать какой-нибудь интерфейс. И использоваться в любом необходимом месте. В контроллере или ещё где-нибудь. ArticlesClient не будут использовать базу данных. В качестве реализации IArticlesRepository будет использоваться mock. ArticlesRepository будут использовать базу данных, разворачиваемую в памяти. В статье описан способ с использованием MS SQL.ORM же — внешний код по отношению к нашему. Возможно, это просто библиотека или набор библиотек, которые пришли к нам из NuGet. Мы не тестируем код этой библиотеки. Мы тестируем то, что с помощью него делаем. Нашу логику. Как уже сказано, это не юнит тесты. Это можно назвать интеграционными или behavior тестами. И они пишутся, как правило после реализации. Юнит тесты в рамках TDD пишутся до реализации
Тест не должен звучать как «объект должен достать из базы, потом посчитать что-то», он должен звучать как «объект должен вызвать метод, получающий что-то и посчитать».
Я в последнее время склоняюсь к мысли, что тесты в рамках TDD нужны не для того, чтобы чего-то там защитить
public TestContext TestContext { get; set; }
[TestInitialize]
public void SetupTestConnectionString()
{
string dbFilename = Path.Combine(TestContext.DeploymentDirectory, GetType().Name + ".sdf");
Database.DefaultConnectionFactory = new System.Data.Entity.Infrastructure
.SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", Path.GetDirectoryName(dbFilename),
string.Format("Data Source={0}", dbFilename));
TestContext.AddResultFile(dbFilename);
}Ну, создание базы каждый раз с нуля можно больно ударить по производительности.
Тем более, что при более сложных организациях объектов (когда они друг на друга ссылаются), ваше требование держать тест коротким сводится на нет, потому что стадия arrange растягивается на 10-20 строчек, если не больше.
Но если начать проверку бизнес логики методом заполнения базы данных — берегитесь этой сложности.
Плюс в работе с реальной базой данных есть тот недостаток, что сложно, например, проверить пейджинг. Чтобы проверить, что при наличии 1000 записей вернутся только 10, эти 1000 записей приходится пихать в базу.
lookupUser фасадная User getOrCreateUser(String firstName, String lastName) вызывает createUser.И как называются такие тесты? Которые запускаются с юнит-тестами, на них похожи, полностью автономны от внешних зависимостей и т.п.
namespace TestNamespace
{
using System.EnterpriseServices;
using NUnit.Framework;
[Transaction(TransactionOption.Required)]
public class RepositoryTestsBase : ServicedComponent
{
[TearDown]
public virtual void Teardown()
{
System.Data.SqlClient.SqlConnection.ClearAllPools();
if (ContextUtil.IsInTransaction)
{
ContextUtil.SetAbort();
}
}
}
}
Unit тесты на практике