Pull to refresh
18

Веб разработчик

-0,1
Rating
4
Subscribers
Send message
// Начинаем разработку как и полагается с написания модульного теста.
// Здесь набрасываем предположения о том, как будем тестировать
// конкретный Formatter<Person> с конкретными проверочными данными.
[TestClass]
public class DefaultFormatterTest
{        
    // Я предполагаю что в простейшем случае, набор тестовых
    // вызовов можно обернуть в команду.
    private Command formatterTestSuit;

    [TestInitialize]
    public void setUp()
    {
        // Это эталонная строка, из которой реализация 
        // Formatter<Person> должна будет извлечь 
        // экземпляр модели Person. И наоборот, из эталонного
        // экземпляра модели Person должна будет получаться 
        // такая строка при выполнении обратной операции.
        string text = "{\"FirstName\":\"Jack\",\"LastName\":\"Sparrow\",\"BirthDate\":\"1635/25/11\"}";

        // Это эталонная модель, из которой реализация
        // Formatter<Person> должна будет сгенерировать
        // строку, идентичную эталонной. И наоборот, из эталонной
        // строки должна будет получиться такая модель при 
        // выполнении обратного преобразования.
        Person model = 
            new Person{ 
                FirstName = "Jack", 
                LastName = "Sparrow", 
                BirthDate = new DateTime(1635, 11, 25)
            };

        // Для удобства, эталонные данные упаковываем в отдельный контейнер.
        FormatterSampleData<Person> sampleData = 
            new FormatterSampleData<Person>{
                Text = text,
                Model = model
            };

        // Инстанциируем экземпляр нашей, несуществующей еще фабрики
        // для производства строк из моделей, и моделей из строк.
        Formatter<Person> formatter = new DefaultFormatter<Person>();

        // И инициализируем наш несуществующий еще тестовый набор,
        // передавая ему в конструктор собственно экземпляр 
        // тестируемого Formatter<Person> и эталонные данные.
        this.formatterTestSuit = 
            new FormatterTestSuit<Person>(formatter, sampleData);
    }

    [TestMethod]
    public void Execute()
    {
        // Тестовый метод будет всего один. Он нужен лишь
        // для того, чтобы запустить комплект проверок,
        // упакованных внутрь команды.
        this.formatterTestSuit.Execute();
    }
}

// Переходим к реализации комплекта собственно модульных тестов,
// которые я решил упаковать в команду.
public class FormatterTestSuit<T>:Command
{
    private Formatter<T> formatter;
    private FormatterSampleData<T> data;

    public FormatterTestSuit(Formatter<T> formatter, FormatterSampleData<T> data)
    {
        if (formatter == null)
            throw new ArgumentNullException("formatter");

        if (data == null)
            throw new ArgumentNullException("data");

        this.formatter = formatter;
        this.data = data;
    }

    // Первый тестовый вызов проверяет корректность работы 
    // метода toString любой реализации Formatter<T>
    public void should_make_model()
    {
        T model = this.formatter.fromString(this.data.Text);

        Assert.IsNotNull(model);
        Assert.AreEqual(this.data.Model, model);
    }

    // Второй тестовый вызов проверяет правильность
    // строки, генерируемой методом toString.
    public void should_compose_string()
    {
        string text = this.formatter.toString(this.data.Model);

        Assert.AreEqual(this.data.Text, text);
    }

    // Оба тестовых метода, для удобства оборачиваем методом Execute.
    public void Execute()
    {
        this.should_make_model();
        this.should_compose_string();
    }
}

Ну а теперь можно собственно реализовывать остальное, чтобы можно было код откомпилировать и выполнить первый неудачный запуск тестов. Для сокращения объема сообщения я не стал проверять в FormatterTestSuit все граничные варианты, предположив тестирование только основного функционала, в идеальных условиях.

Вы бы пример кода привели что-ли? Какие сигнатуры методов у интерфейса подразумеваются? Такой пойдет?


public interface JsonSerializer<T>
{
    string ToJsonString(T item);
    T ToObject(string json);
}

Не пойму в чем проблема написать тест, с помощью которого можно будет тестировать разные реализации, которые должны обеспечивать одинаковые результаты при одинаковых данных на входе?

Вы меня честно признаться заинтриговали. Расскажите пожалуйста, если вас не затруднит, что хотя бы в первом приближении вы подразумевали, говоря о желающих расти, двигаться вперед и выходить за рамки программистах? В идеале бы пример какой-нибудь что-ли.


Дело в том, что большинство моих потенциальных нанимателей впадали в легкую задумчивость, когда я сообщал им что у меня есть в том числе более, чем десятилетний опыт предпринимательской деятельности, когда мне кроме программирования приходилось еще заниматься организацией труда, бухгалтерского и налогового учета, учета персонала, сбытовой деятельностью.

Не могу понять о чем спор? TDD — это не плитка шоколада, которую попробовал и вкусно-сладко. TDD — это даже не просто знания, TDD — это комплект навыков. TDD невозможно начать успешно практиковать, лишь прочитав о нем в книжке и попробовав пару раз, ибо на выработку даже одного навыка требуется достаточно значительное время, а на выработку комплекта навыков требуется еще более значительное время.


Это как при обучении игре на гитаре сказать — "я уже сто(пусть даже тысячу) раз сыграл гамму, а все еще не могу сыграть Hotel California как Joe Walsh, не буду больше играть гаммы, это пустая трата времени".

Как один из вариантов:


public interface Command
{
    void Execute();
}

public class DataContextImplementationTestBase:Command

    private DataContext context;

    public DataContextImplementationTestBase(DataContext context)
    {
        if(context == null)
            throw new ArgumentNullException("context");
        this.context = context;
    }

    public void DataContext_should_return_value()
    {
        IEnumerable<User> users = context.Get<IEnumerable<User>>();

        Assert.IsNotNull(users);
        Assert.AreEqual(0, users.Count());
    }

    public void DataContext_should_return_null()
    {
        Assert.IsNull(context.Get<IEnumerable<Agreements>>());
    }

    public void Execute()
    {
        this.DataContext_should_return_value();
        this.DataContext_should_return_null();
    }
}

[TestClass]
public class DefaultDataContextTest:DataContextImplementationTestBase
{
    public DefaultDataContextTest()
        :(new DefaultDataContext()){}

    [TestMethod]
    public void Run_tests()
    {
        this.Execute();
    }
}

Я дочитал до конца и могу сказать что я совершенно согласен с Андреем Солнцевым. Мой собственный опыт свидетельствует что TDD first — в долгосрочной перспективе, единственная правильная практика. Я всегда сначала пишу модульные тесты, потом пишу интеграционные тесты, потом пишу тесты для UI. Еще ни разу об этом не пожалел и ни разу у меня не было повода предположить что я потратил время зря.


От себя могу добавить что исчерпывающий комплект хорошо написанных модульных тестов представляет собой:


  1. Актуальную документацию по коду. Эта документация никогда не врет (в отличие например от комментариев), потому что она исполняемая.
  2. Объективный и что немаловажно автоматический инструмент контроля качества кода.
  3. Облегчает и поощряет повторное использование кода (потому что пункты 1 и 2)

На мой взгляд в статье описан несколько идеализированный образ компании-нанимателя. Мой личный опыт свидетельствует о наличии существенных отклонение от этого образа в окружающей меня реальности.


За полтора года я принял участие примерно в полусотне интервью. Поскольку у меня несколько специфичные ожидания по отношению к работодателю, то я всегда готовлюсь к интервью. Изучаю не только сайт потенциального нанимателя, но и "пробиваю" через основные поисковики запросы, ответы на которые не принято писать на официальных сайтах. Готовлю к собеседованию вопросы и делаю пометки относительно моментов, которые кажутся мне недостаточно внятными.


В какой-то момент у меня было предположение что представители служб персонала действительно изучают записи соискателей в социальных сетях, но мой опыт показал что это очень и очень редкий случай. Как показала практика, девяносто процентов представителей служб персонала, с которыми мне довелось общаться, даже мое интервью прочитали в лучшем случае "по диагонали". И чаще всего, при очной встрече (или в скайпе) их общение со мной начиналось с "чистого листа".


Лишь двое из всех представителей потенциальных нанимателей почитали код в моих репозиториях на гитхабе, и лишь один из них согласился попрограммировать в паре, чтобы попытаться не в теории (задавая вопросы), а на практике, определить мой профессиональный уровень и нашу потенциальную совместимость.


У всех потенциальных нанимателей я всегда прошу показать мне тестовое задание. Потому что это наилучший способ выстроить предположения о подходах к разработке, принятых внутри компании. Потому что некоторые тестовые задания обескураживают своей необычностью и можно сходу предположить что я сильно непохож на сотрудников потенциального нанимателя. В таком случае как свидетельствует мой опыт, лучше вежливо отказаться от собеседований, чтобы не тратить свое и чужое время в попытках совместить заведомо несовместимое. Тестовое задание кстати сходу мне смогли предложить всего семь-восемь компаний, остальные под разными предлогами предпочли этого не делать.

Похоже я чего-то недопонял, так что если не возражаете, тоже задам вопрос на тему места размещения экземпляров деревьев выражений.


А если завтра появится требование применять отдельные бизнес-правила к категориям, с рейтингом ниже 20, назовем их к примеру PoorRating? Что будем делать?

Если я правильно помню, сигнатура Expression.Parameterподразумевает следующий набор аргументов (Type type, string name). Соответственно приведенный вами код, компилироваться не должен, из-за невозможности преобразования TIn в string в строке 9. Или я чего-то неправильно прочитал?

От офисных «ангаров» меня как-то бог миловал…
А я совершенно точно знаю в какой офис я был бы готов ездить даже по пробкам. В офис, где программирование воспринимается и культивируется не как тяжелый труд, а как увлекательное творчество. Где все члены команды заражены здоровым перфекционизмом и потребностью коллективного и персонального развития. Где руководители программистов умеют программировать (и программируют) и для них это тоже не только работа, но в первую очередь развлечение (fun). В общем словно бы компания приятелей собралась попрограммировать для удовольствия. Ну то есть чтобы ощущения от работы и коммуникаций не были изматывающими как после гребли на галере, а обычная здоровая усталость и моральное удовлетворение.

Честно скажу что я таких офисов (команд) в реальности не видел, в книжках только читал.
Читая заголовок мне и в голову не пришло что это фактически тизер конференции HolyJS…
А-ля «Дао де Цзин» софтверной разработки?

«Виселицу» я постоянно практикую во взаимодействии с руководителями и заказчиками, эффект не всегда ожидаемый, но обычно впечатляющий.
Я считаю такое культивируется «сверху». Собственник-генеральный директор уехал на регату в Италию ибо его интересует только выручка-прибыль.

Исполнительный слинял «на переговоры, на выставку, на конференцию» ибо полагает что выручка-прибыль в ближайшее время не упадет, а большего ему и не надо.

Руководители подразделений уверены что собственнику-генеральному-исполнительному собственно бизнес и конечный продукт по-большому счету фиолетовы ибо их интересуют только выручка-прибыль-регаты.

Ну а сотрудникам на местах в этой ситуации тоже непонятно зачем перенапрягаться.

Статистики по эффективности работы сотрудников-руководителей у меня к сожалению нет, боюсь что мало кто ее в принципе сейчас собирает. Ну и для некоторых видов сотрудников наверное в принципе сложно реализовать адекватную оценку производительности-эффективности. Не все же продажами или производством занимаются.
А много ли присутствующие здесь видели офисов, в которые бы в принципе хотелось поехать? Не говоря уже о том чтобы «в переполненном метро, в холодном трамвае, по утренним пробкам...»?

98 процентов офисных помещений, в которых мне доводилось бывать выглядят одинаково уныло, с одинаково убогой мебелью и планировкой. Примерно как советские многоэтажки в фильме «С легким паром»…
А встречались кому-нибудь внятные книги (пусть не бесплатные) на тему управляемости кода в сложных проектах? На тему сохранения внятности (простоты) внутренней компоновки системы по мере возрастания ее сложности? В идеале чтобы было поменьше текста, побольше примеров кода.
12 ...
21

Information

Rating
Does not participate
Location
Тюмень, Тюменская обл. и Ханты-Мансийский АО, Россия
Date of birth
Registered
Activity