Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Юнит тесты для "системного" приложения

2301  1 2 3 4 5 6 7 8 9 все
AlexNek патриот15.04.21 10:49
AlexNek
15.04.21 10:49 

Для задачи

https://foren.germany.ru/showmessage.pl?Number=37847327&Bo...

...

Остальное в следующем посте

#1 
AlexNek патриот15.04.21 10:56
AlexNek
NEW 15.04.21 10:56 
в ответ AlexNek 15.04.21 10:49

Как то привык логику тестировать. А тут работа с файлами и системой.

Можно конечно всё тестовыми заглушками заменить, но не вижу большого смысла. Только для того чтобы тесты были...

Копируем допустим файл, на диске места больше нет.

Или скопировали десяток больших файлов. Или...

Это же целую модель системы надо делать.

#2 
koder патриот15.04.21 11:02
koder
NEW 15.04.21 11:02 
в ответ AlexNek 15.04.21 10:56
А как проверить что реагирует только на файлы, а не на каталоги.

Если я правильно понял и обертки это моки, то (на яве, по крайней мере) создаем моки для ввода и вывода и отлавливаем на выводе все, что выходит. Создаем сценарии тестов, отлавливаем на выходе одного и того же мока результрат и сравниваем с ожидаемым.То есть тестов много, сценариев много, а вот мок вывода один.

А вот времена и размеры будут роль играть.
Юниттесты нe проверяют перформанs


Нужно определиться что и для чего. Юниттесты только защищают целостность и функтиональность кода.

#3 
koder патриот15.04.21 11:07
koder
NEW 15.04.21 11:07 
в ответ AlexNek 15.04.21 10:56
Копируем допустим файл, на диске места больше нет.


Униттесты не проверяют состояния окружения, но они проверяют реакцию кода на определенные ответы опрошенного окружения. Сами запросы выполняют системные функции. Заменяем системную функциию на мок и симулируем ситуацию(вручную выбрасываем ошибкu). Проверяем реакцию собственного кода.

#4 
AlexNek патриот15.04.21 11:17
AlexNek
NEW 15.04.21 11:17 
в ответ koder 15.04.21 11:02
и обертки это моки

Не знаю что там в Яве и что имелось в виду. Я понимаю обвертку так.


    internal class DirectoryWatcher: IDirectoryWatcher
    {
        public event EventHandler<FileSystemEventArgs> NewFileAdded;
        private readonly FileSystemWatcher _watcher = new FileSystemWatcher();
        public void Start(string directoryName)
        {
            _watcher.Path = directoryName;
            // Watch files only.  
            _watcher.IncludeSubdirectories = false;
            // Watch all files.  
            _watcher.Filter = "*.*";
            _watcher.Created += Watcher_Created;
            //Start monitoring.  
            _watcher.EnableRaisingEvents = true;
        }
        public void Stop()
        {
            //Stop monitoring.  
            _watcher.EnableRaisingEvents = false;
        }
        private void Watcher_Created(object sender, FileSystemEventArgs e)
        {
            //e.FullPath
            NewFileAdded?.Invoke(sender, e);
        }
    }


Юниттесты нe проверяют перформанs

Так меня не скорость интересует, а функциональность. Просто в данном случае всё сильно зависит от количества и размеров файлов на входе.

Сейчас я всё делаю сразу после поступления события о приходе нового файла. А может нужно это всё в очередь записывать?


Ну и другое. Как проверить пароль перед стартом проги в юнит тестах. Дело в том что если ничего не делать, то прога просто не запуститься после запуска окна ввода пароля.


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


#5 
AlexNek патриот15.04.21 11:20
AlexNek
NEW 15.04.21 11:20 
в ответ koder 15.04.21 11:07
вручную выбрасываем ошибкu

Ну так это же все надо и делать вручную.


Но вот как проверить, что не будет сигнала от системы если я кинул в файл каталог?

#6 
Программист коренной житель15.04.21 11:22
NEW 15.04.21 11:22 
в ответ AlexNek 15.04.21 10:56
Как то привык логику тестировать. А тут работа с файлами и системой.
Можно конечно всё тестовыми заглушками заменить, но не вижу большого смысла. Только для того чтобы тесты были...

Перед тем, как написать тест надо ответить на один вопрос - что я хочу протестировать?

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

Значит у тебя есть некая логика, в которой есть некоторое количество вызовов системных функций. Ну а логику тестировать ты уже привык :) Осталось только абстрагироваться от системных вызовов. Сделать это можно одним простым способом - выделив эти функции на другой уровень и соеденив этот уровень со своим кодом через некий интерфейс (контракт).


Если не хочется городить все это ради тестов, то всегда можно сделать "системные тесты". Правда системные тесты а) медленнее и б) не могут протестировать все тонкости, например "на диске места больше нет" :)


Так что тут уж придется тебе делать выбор :)


Это же целую модель системы надо делать.

Да, ну или выделять какие-то важные для тебя части и моделировать только их. Я когда-то делал обертку для доступа в реестр.

#7 
koder патриот15.04.21 11:37
koder
NEW 15.04.21 11:37 
в ответ AlexNek 15.04.21 11:17
а функциональность. Просто в данном случае всё сильно зависит от количества и размеров файлов на входе.

Что изменится. если количество файлов увеличится в 10 раз? будет подключен другой обработчик? Изменится результат?


Как проверить пароль перед стартом проги в юнит тестах. Дело в том что если ничего не делать, то прога просто не запуститься после запуска окна ввода пароля.

Юниттесты не проверяют прогу. И для тестов прога не запускается. Юниттесты проверяют юниты - куски програмного кода, один или несколько вызовов функций. Изолировано.


То, что ты пытаешься запустить это интегратионтест в тестовом окружении. Если хрень запускается в броузере, работу юзера можно симулировать силениумоm

#8 
koder патриот15.04.21 11:38
koder
NEW 15.04.21 11:38 
в ответ Программист 15.04.21 11:22
то всегда можно сделать "системные тесты".

Что такое системный тест?

#9 
AlexNek патриот15.04.21 11:42
AlexNek
NEW 15.04.21 11:42 
в ответ Программист 15.04.21 11:22
надо ответить на один вопрос - что я хочу протестировать?

В данном случае написано надо смущ


Работу системных функций, которые работают с файлами тестировать не надо.

А я и не хочу именно их тестировать, я могу просто неправильно задать параметры для их вызова.


выделив эти функции на другой уровень

ну они как бы и выделены. Но для тестов

  1. нужно писать свою имплементацию
  2. передавать ее в конструктор


А так как этих уровней минимум три+экспорт+настиройки, то вся работа по тестированию будет сопоставима по затратам с написанием кода и даже больше.

#10 
AlexNek патриот15.04.21 11:45
AlexNek
NEW 15.04.21 11:45 
в ответ koder 15.04.21 11:37
Если хрень запускается в броузере

Эта хрень - обычное windows exe

#11 
koder патриот15.04.21 11:45
koder
NEW 15.04.21 11:45 
в ответ AlexNek 15.04.21 11:17
Для данного случая мне кажется что разработка юнит тестов займет гораздо больше времени чем они принесут пользы.

Юниттесты не приносят пользу. Они защищают. Допустим есть код, этот код протестован вручную или другим способом и никогда не будет менятся. ВСЕ. Юниттесты никакой пользы больше не принесут.

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


У нас деятели повадились отключать ССЛ-шифрование у рест-ендпойнтов. Приложение стартует. Пока к нему кто то не попробует подконнектится. Закрыли юниттестами.

#12 
Программист коренной житель15.04.21 11:53
NEW 15.04.21 11:53 
в ответ koder 15.04.21 11:38
Что такое системный тест?

Тест всей системы. Т.е. запустил прогу, вбил пароль, сделал какие-то действия, проверил результат.

#13 
koder патриот15.04.21 11:55
koder
NEW 15.04.21 11:55 
в ответ AlexNek 15.04.21 11:42
А так как этих уровней минимум три+экспорт+настиройки, то вся работа по тестированию будет сопоставима по затратам с написанием кода и даже больше.

Во первых да. Часто написание Юниттестов сопоставимо с написанием кода. Во вторых если мы хотим от затычки особой функтиональности, то это уже спай - шпион.

я могу просто неправильно задать параметры для их вызова.

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


Если есть возможность формализовать утверждение, что такое "неправильный" параметр, то такой опработчик и его тест надо делать до вызова системной функциi

#14 
AlexNek патриот15.04.21 11:57
AlexNek
NEW 15.04.21 11:57 
в ответ koder 15.04.21 11:37
Что изменится. если количество файлов увеличится в 10 раз?
  1. Копируем файл в каталог
  2. Получаем уведомление о добавлении файла
  • Сжимаем файл
  • Перемещаем файл

пункт 2 занимает определенное время. И вся цепочка будет работать совершенно по разному в зависимости от количества и размера одновременно копируемых файлов.


Вот сейчас, например. В юнит тесте Зип работает без проблем, а обработчике выдает ошибку.

#15 
AlexNek патриот15.04.21 12:04
AlexNek
NEW 15.04.21 12:04 
в ответ koder 15.04.21 11:45
Юниттесты не приносят пользу. Они защищают.

А мне и не нужно ничего защищать. Я только хочу проверить работу проги на граничных условиях. Да и вообще что бы не сломал.


Вод делаю я XAML парсер, так у меня этих тестов на каждый чих: <tag>, <tag\r\n>, <\r\ntag> и т.п.

Явная польза.


А тут изменил не заглушку, а реальную обвертку и всё тебе уже поступают каталоги а не файлы.


#16 
koder патриот15.04.21 12:20
koder
NEW 15.04.21 12:20 
в ответ AlexNek 15.04.21 11:57
пункт 2 занимает определенное время.

Это не функтиональность. Это производительность. Юниттесты не тестируют производительность.

И вся цепочка будет работать совершенно по разному

Если я правильно понял, то абсолютно также. Но дольше. Юниттесты это не тестируют. Они тестируют только принципиальные различия. Например допускается только 50 файлов. При наличии > 50 файлов должен сработать ДРУГОЙ кусок кода. Это принципиальное различие, это можно тестировать.

В юнит тесте Зип работает без проблем, а обработчике выдает ошибку.

Более того. У меня в реале зип выдаст ошибку, у соседа нет. Надо тестировать не зип. Нужно тестировать код, использующий зип. А зип выдавал и будет выдавать ошибки по независящим от кода причинам. Юниттесты тестируют только код.

#17 
Программист коренной житель15.04.21 12:21
NEW 15.04.21 12:21 
в ответ AlexNek 15.04.21 11:42

В данном случае написано надо

И как, ответ-то уже есть? :)


А я и не хочу именно их тестировать, я могу просто неправильно задать параметры для их вызова.

Не понимаю.


ну они как бы и выделены. Но для тестов 1. нужно писать свою имплементацию 2. передавать ее в конструктор

1) определить интерфейс

2) сделать класс, который имплеметрирует этот интерфейс

3) передавать в конструктор можно и это пожалуй наиболее простое решение. Можно использовать какой-нибудь контейнер. Например Ninject. Но есть и другие способы.

#18 
AlexNek патриот15.04.21 12:35
AlexNek
NEW 15.04.21 12:35 
в ответ koder 15.04.21 11:55
Тестировать надо , как собственный код ресгирует на любой вариант ответа системной функции.

Так в том то и дело что никаких отличий не будет

sourceFilePath = "E:\\Alex\\WinCatalog" - каталог

sourceFilePath = "E:\\Alex\\WinCatalog" - файл

#19 
AlexNek патриот15.04.21 12:43
AlexNek
NEW 15.04.21 12:43 
в ответ koder 15.04.21 12:20
Это не функциональность. Это производительность.

reentrancy - производительность?


Если я правильно понял, то абсолютно также

Могу логов нафигачить если не веришь, хоть и не проверял еще смущ


Нужно тестировать код, использующий зип.

и что тут тестировать FileCompressor.Compress(destFilePath); ?

#20 
AlexNek патриот15.04.21 12:56
AlexNek
NEW 15.04.21 12:56 
в ответ Программист 15.04.21 12:21
И как, ответ-то уже есть?

В смысле? На какой вопрос?


Не понимаю.

Ну вот кусок кода для настройки. Вроде всё верно. А гад реагирует на копирование каталога.


_watcher.Path = directoryName;

// Watch files only.

_watcher.IncludeSubdirectories = false;

// Watch all files.

_watcher.Filter = "*.*";

_watcher.Created += Watcher_Created;

//Start monitoring.

_watcher.EnableRaisingEvents = true;


Можно использовать какой-нибудь контейнер. Например Ninject.

никогда в моем коде не будет DI Container. И фиг поймешь как работает система, когда оно везде. И непонятно как отлаживать. Был уже такой проект.


Но есть и другие способы.

и какие интересно?

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

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

#21 
Программист коренной житель15.04.21 13:36
NEW 15.04.21 13:36 
в ответ AlexNek 15.04.21 12:56
На какой вопрос?

Что ты хочешь тестировать?


Ну вот кусок кода для настройки. Вроде всё верно. А гад реагирует на копирование каталога.
_watcher.Path = directoryName;
// Watch files only.
_watcher.IncludeSubdirectories = false;
// Watch all files.
_watcher.Filter = "*.*";
_watcher.Created += Watcher_Created;
//Start monitoring.
_watcher.EnableRaisingEvents = true;

Это мило, то тут ты конфигурируешь некий объект _watcher. Никакой логики тут нет. Цикломатическая сложность этого кода равна 1.


Но предположим, что ты хочешь получить ошибку (исключение) в момент, когда выполныешь строку _watcher.EnableRaisingEvents = true; если directoryName - директория. И не получать исключение, если directoryName - файл.

В таком случае у тебя есть такой код:

    public interface ISystemFile
    {
      System.IO.FileAttributes GetAttributes(string path);
    }
    public class SystemFile : ISystemFile
    {
      public FileAttributes GetAttributes(string path)
      {
        return System.IO.File.GetAttributes(path);
      }
    }
    public class FileSystemWatcher
    {
      ISystemFile _systemFiles = null;
      public FileSystemWatcher()
        : this (new SystemFile())
      {
      }
      public FileSystemWatcher(ISystemFile systemFiles)
      {
        _systemFiles = systemFiles;
      }
      public string Path { get; set; }
      public bool IncludeSubdirectories { get; set; }
      public string Filter { get; set; }
      public event EventHandler Created;
      private bool _enableRaisingEvents = false;
      public bool EnableRaisingEvents
      {
        get
        {
          return _enableRaisingEvents;
        }
        set
        {
          if (value == true)
          {
            System.IO.FileAttributes att = _systemFiles.GetAttributes(Path);
            if (att == System.IO.FileAttributes.Directory)
              throw new Exception("blah-blah-blah");
          }
          _enableRaisingEvents = value;
        }
      }
   }


Ну и тестируешь то, что надо:

    [TestMethod]
    public void EnableRaisingEvents_TrueForFile_OK()
    {
      // Arrenge
      ISystemFile systemFile = Substitute.For<ISystemFile>();
      systemFile.GetAttributes(Arg.Any<string>()).Returns(FileAttributes.Normal);
      FileSystemWatcher watcher = new FileSystemWatcher(systemFile);
      // Act
      watcher.EnableRaisingEvents = true;
      // Assert
      Assert.IsTrue (watcher.EnableRaisingEvents);
    }
    [TestMethod]
    [ExpectedException(typeof(Exception))]
    public void EnableRaisingEvents_TrueForDirectory_Exception()
    {
      // Arrenge
      ISystemFile systemFile = Substitute.For<ISystemFile>();
      systemFile.GetAttributes(Arg.Any<string>()).Returns(FileAttributes.Directory);
      FileSystemWatcher watcher = new FileSystemWatcher(systemFile);
      // Act
      watcher.EnableRaisingEvents = true;
      // Assert
    }



и какие интересно?

Ну например тоже сделать виртуальную функцию, которая будет возвращать реальную обертку. В тесте такую функцию можно перегрузить.


#22 
koder патриот15.04.21 13:45
koder
NEW 15.04.21 13:45 
в ответ AlexNek 15.04.21 12:04
Я только хочу проверить работу проги на граничных условиях.

Тогда берем прогу и проверяем. Именно прогу. Именно в определенном окружении. Это не юниттесты.

#23 
koder патриот15.04.21 13:47
koder
NEW 15.04.21 13:47 
в ответ AlexNek 15.04.21 12:35
"E:\\Alex\\WinCatalog" - каталог


Это не каталог. Это строка. В принципе путь к файлу, но вообще строка.

#24 
koder патриот15.04.21 13:55
koder
NEW 15.04.21 13:55 
в ответ AlexNek 15.04.21 12:43
reentrancy


Попробуй на примере сформулировать, что конкретно ты хочешь протестировать, увеличив количество файлов? То, что ты тестируешь - это ТВОЙ код или ты пытаешься посмотреть, как работает сторонняя библиотека? Именно твой код меняет поведение от количества файлов?


Могу логов нафигачить если не веришь, хоть и не проверял еще

Не надо. Опиши словами. Что должно произойти от увеличения количества файлов? Если ты используешь слова "быстрее", то это производительность.

и что тут тестировать

Только выzов самой функции. Вызывается и сколько раз вызывается. Это не твой код. Тут нечего тестировать.

#25 
AlexNek патриот15.04.21 13:58
AlexNek
NEW 15.04.21 13:58 
в ответ Программист 15.04.21 13:36
На какой вопрос? Что ты хочешь тестировать?

Вообще то не вижу ничего, что имеет смысл покрывать юнит тестами.

Можно только создать сферического коня в вакууме и его тестировать смущ


Это мило, то тут ты конфигурируешь некий объект _watcher. Никакой логики тут нет

Естественно, но именно так и не работает


Нужно было добавить еще одну строку

_watcher.NotifyFilter = NotifyFilters.FileName;


А что ты там тестируешь я так и не понял, для меня это какое то извращение, тем более что я пользую NUnit


#26 
AlexNek патриот15.04.21 14:03
AlexNek
NEW 15.04.21 14:03 
в ответ koder 15.04.21 13:47
Это не каталог. Это строка. В принципе путь к файлу, но вообще строка.

ну так в том то и дело. Не имеет значения, что я кидаю файл или каталог на выходе одна и таже строка.

И там еще буфер в 4К по умолчанию. Так что неизвестно будет ли работать для 1000 файлов и больше.

#27 
AlexNek патриот15.04.21 14:11
AlexNek
NEW 15.04.21 14:11 
в ответ koder 15.04.21 13:55
Если ты используешь слова "быстрее", то это производительность.

В данном случае от скорости меняется логика.

Я начинаю вызывать функцию по новому, когда она еще не закончила свою работу.


Кроме того как в "эмуляторе" отследить что эта функция создала новый файл к каталоге для мониторинга


Только выzов самой функции. Вызывается и сколько раз вызывается.

А на кой мне эвент тестировать? Сколько раз его вызвал столько и придет, вроде как системная функция.

#28 
AlexNek патриот15.04.21 14:13
AlexNek
NEW 15.04.21 14:13 
в ответ koder 15.04.21 13:45
Тогда берем прогу и проверяем

Ну так это я и сам могу сделать, только хорошо бы иметь это на автомате.

На одном компе запустить, потом на другом.

#29 
Программист коренной житель15.04.21 14:26
NEW 15.04.21 14:26 
в ответ AlexNek 15.04.21 13:58
Вообще то не вижу ничего, что имеет смысл покрывать юнит тестами.
Можно только создать сферического коня в вакууме и его тестировать
Можно. А можно задуматься о том, где могут быть проблемы в твоем коде и как смоделировать эти проблемы.

Короче говоря можно попробовать ответить на следующие вопросы:

1) что является твоим Unit under test?

2) какие требования предъявляются к твоему Unit under test?

3) с какими объектами взаимодействуешь твой Unit under test?


Ну и после того, как это все станет понятно, можно будет приступать к самим тестам.


Естественно, но именно так и не работает

ОК, что именно не работает в приведенном тобой коде?


А что ты там тестируешь я так и не понял

Тестируется setter проперти EnableRaisingEvents.


тем более что я пользую NUnit

Какая разница, в какой среде ты это тестируешь? NSubstitute - это библиотека для mock.


#30 
koder патриот15.04.21 14:59
koder
NEW 15.04.21 14:59 
в ответ AlexNek 15.04.21 14:03
Не имеет значения, что я кидаю файл или каталог

Во первых ты не можешь кинуть файл. Кинуть можно обьект класса или базисный тип как параметр. Мы же внутри программного кода. Файл - это понятие файловой системы. В коде файловой системы нет, есть обьекты определенных классов с определенными параметрами. Вот это и тестируем


И там еще буфер в 4К по умолчанию.

где там? как твой код взаимодействует прямо или косвенно с буфером, что может произойти, какой ответ ты можешь получить?

#31 
koder патриот15.04.21 15:03
koder
NEW 15.04.21 15:03 
в ответ AlexNek 15.04.21 14:13
На одном компе запустить, потом на другом.

Железное правило номер 0 - юниттесты дают одинаковые результаты вне зависимости от окружения. И даже в отсутствии этого самого окружения вообще. Иначе это интеграционные тесты.

#32 
koder патриот15.04.21 15:06
koder
NEW 15.04.21 15:06 
в ответ AlexNek 15.04.21 14:11
А на кой мне эвент тестировать? Сколько раз его вызвал столько и придет, вроде как системная функция.


Не в этом дело. При определенных обстоятельствах в твоем коде может не дойти до вызова этой функции. Юниттест проверяет эти условия. Шаловливый коллега мог закоментировать вызов или заменить функцию другой. Юниттест защищает от этого. Но Юниттест не может дать результат "на этом компе результаты неудовлетворительные, компьютер медленный". В смысле может конечно, написать можно что угодно, но это будет неправильно. Юниттесты не снимают метрики.

#33 
AlexNek патриот15.04.21 16:13
AlexNek
NEW 15.04.21 16:13 
в ответ Программист 15.04.21 14:26
Тестируется setter проперти EnableRaisingEvents.

А причем тогда файловая система?

System.IO.File.GetAttributes(path);


где могут быть проблемы в твоем коде и как смоделировать эти проблемы

А зачем их моделировать?

Сделаю я лучше пару временных тест каталогов и всё протестирую "наживую"


ОК, что именно не работает в приведенном тобой коде?

В приведенной версии, если я перемещаю каталог в директорию которая мониторится, возникает событие о создании объекта.

#34 
AlexNek патриот15.04.21 16:18
AlexNek
NEW 15.04.21 16:18 
в ответ koder 15.04.21 14:59
Мы же внутри программного кода

Не мы а Вы смущ

Я говорил о реальном тесте, который мне нужен.


где там?

В FileSystemWatcher

A 4 KB buffer can track changes on approximately 80 files in a directory. Each event takes up 16 bytes in the buffer, plus enough bytes to store the name of the file, in Unicode (2 bytes per character), that the event occurred on.


Если дофига файлов накидаю, могу ничего и не получить. Так что можно долго и нудно моделировать и усё будет в порядке.

#35 
koder патриот15.04.21 16:25
koder
NEW 15.04.21 16:25 
в ответ AlexNek 15.04.21 16:13
А зачем их моделировать?Сделаю я лучше пару временных тест каталогов и всё протестирую "наживую"

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


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


#36 
AlexNek патриот15.04.21 16:26
AlexNek
NEW 15.04.21 16:26 
в ответ koder 15.04.21 15:06
Но Юниттест не может дать результат "на этом компе результаты неудовлетворительные

На так о чем я и говорю, что не нужны в данном случае юнит тесты, потому как все ситуации смоделировать невозможно.

Меня сейчас будущее не интересует, что кто то, что то, когда то сломает.

#37 
Murr патриот15.04.21 16:27
Murr
NEW 15.04.21 16:27 
в ответ AlexNek 15.04.21 10:56

Это же целую модель системы надо делать.

------

Наконец-то ты это осознал!!!

Когда Я говорил, что таскаю данные из живой базы потому как не именю времени на написание всех тестов было таки непонятно почему... спок

#38 
AlexNek патриот15.04.21 16:30
AlexNek
NEW 15.04.21 16:30 
в ответ koder 15.04.21 16:25
а они упали, потому что каталога нет

Так в тестах он и будет создаваться, всё с нуля, на "чистой системе".

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

#39 
Murr патриот15.04.21 16:33
Murr
NEW 15.04.21 16:33 
в ответ AlexNek 15.04.21 11:17

А может нужно это всё в очередь записывать?

-----

Конечно нужно. Только не в очередь, а проверять дату/время созадния файла по событию.

Копирование, надеюсь, у тебя идет в отдельном потокe?

#40 
koder патриот15.04.21 16:38
koder
NEW 15.04.21 16:38 
в ответ AlexNek 15.04.21 16:18
Я говорил о реальном тесте, который мне нужен.


Мы. Потому что юниттест работает только и исключительно только внутри програмного кода. Если я неправ, то приведи пример обратного. Поэтому мы передаем в тест тестируемый обьект, вызываем тестируемую функцию и проверяем ресультаты. Тестируемая функция внутри кода работает исключительно с другими элементами кода, никогда не с файлами.


Так что можно долго и нудно моделировать и усё будет в порядке.

Именно. FileSystemWatcher управляет мониторингом файлов. Ты не можешь юниттестами проверять поведение этого класса, потому что ты ЗНАЕШь как он себя поведет. Зачем здесь юниттесты, которые будут запускаться автоматически при каждом коммите в репозиторий и при каждом построении приложения? FileSystemWatcher как работал максимум с 80 файлами так и будет это делать. Какая цель проверять это на каждом компе, куда попадет програмный код? Заметь, не приложение будет запущено, а именно попадет програмный код. Билдсервер, компы коллеg

#41 
koder патриот15.04.21 16:43
koder
NEW 15.04.21 16:43 
в ответ AlexNek 15.04.21 16:30, Последний раз изменено 15.04.21 16:52 (koder)
Так в тестах он и будет создаваться, всё с нуля, на "чистой системе".

А права у него есть "создавать"? А если в системе есть уже такой каталог? После окончания теста каталог будет снесен вместе с содержимым?

Приложение то показать и выбросить.

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

#42 
Программист коренной житель15.04.21 17:00
NEW 15.04.21 17:00 
в ответ AlexNek 15.04.21 16:13

А причем тогда файловая система?

System.IO.File.GetAttributes(path);

Ты привел кусок кода, написал:

Ну вот кусок кода для настройки. Вроде всё верно. А гад реагирует на копирование каталога.

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

//Start monitoring.
_watcher.EnableRaisingEvents = true;

а судя по твоему коду, мониторить ты начинаешь установив значение проперти EnableRaisingEvents в true, ты не различаешь файл и директорию. Очевидно, что если в _watcher был передан путь к директории, то должна быть сгенерирована ошибка. Именно это и проверяют тесты, которые я привел в качестве примера.


А зачем их моделировать?

Затем, что ты почему-то решил писать юнит-тесты.


Сделаю я лучше пару временных тест каталогов и всё протестирую "наживую"

Это сколько угодно. Почему ты тогда говоришь о юнит-тестах? Юнит-тесты - это совершенно определенная технология. Если хочешь тестировать все приложение, то можно использоваться BDD (например NBehave).


В приведенной версии, если я перемещаю каталог в директорию которая мониторится, возникает событие о создании объекта.

Код, где это происходит ты не приводил.

#43 
Murr патриот15.04.21 17:01
Murr
NEW 15.04.21 17:01 
в ответ AlexNek 15.04.21 16:18

Если дофига файлов накидаю, могу ничего и не получить.

------

Тебе не нужно тестировать FileSystemWatcher.

Тебе нужно тестировать реакцию твоего приложения на то как он сработает при переполнении его очереди.

При какой-либо отсутствии реакции или отсустствии события ты все одно ничего не можешь сделать....

#44 
Murr патриот15.04.21 17:07
Murr
NEW 15.04.21 17:07 
в ответ Программист 15.04.21 17:00

не указал, что именно там не работает

------

Вообще-то - указал - реагирует на копирование каталога



Код, где это происходит ты не приводил.

------

FileSystemWatcher.cs спок

#45 
Программист коренной житель15.04.21 17:14
NEW 15.04.21 17:14 
в ответ Murr 15.04.21 17:07, Последний раз изменено 15.04.21 17:14 (Программист)
Вообще-то - указал - реагирует на копирование каталога

Б@*ть! Ошибка-то в чем? В том что сгенерировался эвент на каталог или в том, что был скопирован каталог? И где код, в котором происходит эта ошибка?


FileSystemWatcher.cs

А теперь просмотри топик и найти код из этого файла.

#46 
Murr патриот15.04.21 17:34
Murr
NEW 15.04.21 17:34 
в ответ Программист 15.04.21 17:14

Ошибка-то в чем?

-----

Ошибка в том, что ватчер настроен на отслеживание создания файлов, а реагирует на них и на создание каталога.


В том что сгенерировался эвент на каталог или в том, что был скопирован каталог?

------

Тебе нужно поработать с FileSystemWatcher чтобы понимать возникающие проблемы.

Я, когда-то, считал что мне нужно мониторить некоторые изменения из студийного адд-она и потому его использовал - по-этому мне понятны проблемы Алекса. Самое смешное - тогда оказалось что мониторить ничего не надо...


А теперь просмотри топик и найти код из этого файла.

------

Зачем?

Ты спросил - Где именно возникает проблема? - Я дал тебе имя файла в котором находится этот код.

Файл - общедоступный. К нему, кстати, и тесты где-то были...


#47 
Программист коренной житель15.04.21 17:46
NEW 15.04.21 17:46 
в ответ Murr 15.04.21 17:34
Ошибка в том, что ватчер настроен на отслеживание создания файлов, а реагирует на них и на создание каталога.

Т.е. баг в FileSystemWatcher?


Тебе нужно поработать с FileSystemWatcher чтобы понимать возникающие проблемы.

Нафига мне с ним работать?


Зачем?

Затем, что юнит-тестами покрывают СВОЙ код, чтобы быть уверенными в том, он удовлетворяет требованиям.

#48 
Murr патриот15.04.21 18:24
Murr
NEW 15.04.21 18:24 
в ответ Программист 15.04.21 17:46

Т.е. баг в FileSystemWatcher?

-----

Скорее - фича. Надо в доках смотреть...


Нафига мне с ним работать?

-----

Чтобы не понимать об чем написано.


Затем, что юнит-тестами покрывают СВОЙ код, чтобы быть уверенными в том, он удовлетворяет требованиям.

-----

Угу...

Вот только для теста нужен мок, который должен отработать... как оригинальный код.

А чтобы его слепить - надо понимать/знать чего ожидать, включая ошибки и фичи...

#49 
Программист коренной житель15.04.21 20:10
NEW 15.04.21 20:10 
в ответ Murr 15.04.21 18:24
Скорее - фича. Надо в доках смотреть...

Ну т.е. тестировать это не надо ;)


Вот только для теста нужен мок, который должен отработать... как оригинальный код.

Не должен.


А чтобы его слепить - надо понимать/знать чего ожидать, включая ошибки и фичи...

Ну, как ты сам говоришь, это надо смотреть в доках.

#50 
AlexNek патриот15.04.21 20:58
AlexNek
NEW 15.04.21 20:58 
в ответ koder 15.04.21 16:38
Тестируемая функция внутри кода работает исключительно с другими элементами кода, никогда не с файлами

Вполне может быть, "клеан юнит тест" правил я еще не учил. Тогда мне требуется что то другое, потому как большинство действий делается на уровне файловой системы и моделировать их смысла нет.

При этом, почти уверен что простая модель будет работать без проблем.


потому что ты ЗНАЕШь как он себя поведет

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


которые будут запускаться автоматически при каждом коммите

А отчего все должны запускаться при каждом коммите? Даже и на работе у нас было разделение, на ежедневные и после коммитные.


FileSystemWatcher как работал максимум с 80 файлами так и будет это делать

А я этого кстати, еще и не знаю, не проверял. Да и неизвестно как он себя поведет если время "выхода из эвента" будет долгим.

Ну и у меня на каждое сообщение запускался новый треад, а что будет когда они закончатся? Сейчас уже на ConcurrentQueue переделал с одним треадом

#51 
AlexNek патриот15.04.21 21:06
AlexNek
NEW 15.04.21 21:06 
в ответ koder 15.04.21 16:43
А если в системе есть уже такой каталог?

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


После окончания теста каталог будет снесен вместе с содержимым?

Безусловно и свободное место будет проверяться. Корзина правда не будет чистится.


если делаешь учебное приложение, ты должен делать так, как надо.

Согласен, но в данном случае меня "поджимают сроки". Зачем мне инвестировать время в приложение которое идет на помойку.

Я свои юнит теста для парсера еще не окончил.


твой коллега будет сидеть и думать, что он сломал в системе

Ничего он думать не будет, у него будет сообщение с описанием проблемы. Типа "не могу создать тестовый каталог".

#52 
AlexNek патриот15.04.21 21:23
AlexNek
NEW 15.04.21 21:23 
в ответ Программист 15.04.21 17:00

а не указал, что именно там не работает.

Может быть не очень подробно описал, но мне казалось что вполне достаточно.


https://foren.germany.ru/showmessage.pl?Number=37855570&Bo...

А гад реагирует на копирование каталога.
_watcher.IncludeSubdirectories = false;


То бишь IncludeSubdirectories = false, из описания можно понять что этого достаточно для того чтобы извещение о добавлении нового каталога не приходило.

А оно приходит.


Очевидно, что если в _watcher был передан путь к директории

Так ему и нужен путь какую директорию мониторить.


Именно это и проверяют тесты, которые я привел в качестве примера.

Но так они это проверяют на основе знаний о файловой системе, а именно от этого хотелось вроде уйти. смущ


Затем, что ты почему-то решил писать юнит-тесты.

Это не я решил, для этой проги я бы их не делал. Но в задании было так.


NBehave

ну вот что то новое узнал


Код, где это происходит ты не приводил.

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

#53 
AlexNek патриот15.04.21 21:43
AlexNek
NEW 15.04.21 21:43 
в ответ Murr 15.04.21 17:01
Тебе нужно тестировать реакцию твоего приложения на то как он сработает при переполнении его очереди.

Для этого нужно хотя бы примерно знать, что происходит при этом.

#54 
Программист коренной житель15.04.21 21:48
NEW 15.04.21 21:48 
в ответ AlexNek 15.04.21 21:23
а не указал, что именно там не работает.
Может быть не очень подробно описал, но мне казалось что вполне достаточно.

Из твоего описания было не понятно, что именно ты хочешь протестировать юнит-тестами. Собственно говоря, ты так до сиз пор и не ответил на этот вопрос. А значит рано еще приступать к написанию каких-либо юнит-тестов.

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


Но так они это проверяют на основе знаний о файловой системе, а именно от этого хотелось вроде уйти.

Ну после нескольких сообщений я наконец понял, что FileSystemWatcher - это некий third party объект, а значит он работает правильно и тестировать его не надо. А ошибка у тебя была в инициализации.

Но если мы вернемся к тестированию, то значит тестировать тебе надо класс DirectoryWatcher, а для FileSystemWatcher сделать обертку. После этого ты просто сможешь эвент Created и проверять код хэндлера Watcher_Created. Никакие манипуляции с файловой системой для этого не будут нужны :)


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

Те строчки, что ты привел - это просто инициализация. Впрочем, на инициализацию тоже можно легко написать тест :)

#55 
AlexNek патриот15.04.21 22:20
AlexNek
NEW 15.04.21 22:20 
в ответ Программист 15.04.21 21:48
Собственно говоря, ты так до сиз пор и не ответил на этот вопрос

И не думаю что когда либо отвечу, в разрезе конкретно моего кода. Нет там никакой особой логики.

Нажали кнопу - появился диалог, взяли имя каталога для наблюдения

Нажали кнопу начали наблюдать за каталогом.

Кинули туда чего-то, пришло извещение, сделали какие то действия.


Всё самое интересное происходит на уровне файловой системы и во взаимодействии с кодом.


А ошибка у тебя была в инициализации.

Ну так именно это и хотелось проверить.


После этого ты просто сможешь эвент Created и проверять код хэндлера Watcher_Created.

Я и без этого могу проверять код хэндлера Watcher_Created ---_mainWorker.WorkOnNewItem(e);

Но там опять таки манипуляции с файлами, которые опять нужно как то имитировать. И имитация будет точно уж неполной.


Впрочем, на инициализацию тоже можно легко написать тест

ну и как это сделать не трогая файловую систему?

#56 
Программист коренной житель15.04.21 22:45
NEW 15.04.21 22:45 
в ответ AlexNek 15.04.21 22:20
ну и как это сделать не трогая файловую систему?

Делаешь обертку над FileSystemWatcher и проверяешь, что все проперти установлены правильно.

#57 
AlexNek патриот15.04.21 22:56
AlexNek
NEW 15.04.21 22:56 
в ответ Программист 15.04.21 22:45
и проверяешь, что все проперти установлены правильно.

А смысл в этом? Они то не снаружи выставляются.

Да и они все были установлены правильно - а нифига не работало.

#58 
Программист коренной житель15.04.21 23:10
NEW 15.04.21 23:10 
в ответ AlexNek 15.04.21 22:56

Смысла не очень много. Если только гарантировать, что никто случайно эти настройки не изменит.


Да и они все были установлены правильно - а нифига не работало.

Значит неправильно было выставлено. Ты потом сам написал, что один параметр не установил.

#59 
AlexNek патриот15.04.21 23:45
AlexNek
NEW 15.04.21 23:45 
в ответ Программист 15.04.21 23:10
Ты потом сам написал, что один параметр не установил

Ну так это я нашел только после реального теста с файловой системой.

Это всё к тому что не нужно тестировать системные функции - они и так правильно работают.

Как бы я с виртуальными тестами не извращался никогда бы не нашел.

#60 
Murr патриот16.04.21 00:50
Murr
NEW 16.04.21 00:50 
в ответ Программист 15.04.21 20:10
Не должен.

-----

Да ну? И как же ты будешь эмулировать результат переполнения буфера если об этом даже не в курсе?


это надо смотреть в доках.

-----

Ну так смотри.

А то получается ни доkи не посмотрел, ни практики не поимел, но об том КАК - вполне готов говорить... причем начиная с того что тебе непонятны описанные проблемы... спок

#61 
Murr патриот16.04.21 00:58
Murr
NEW 16.04.21 00:58 
в ответ AlexNek 15.04.21 21:23

достаточно для того чтобы извещение о добавлении нового каталога не приходило.

-----

Не-а... это мониторинг субфолдеров. Т.е. если есть вложенные папки - будет-не-будет трекировать в них тоже...

Удобно - задал "С:\\" с подкаталогами и весь диск мониторишь...

#62 
koder патриот16.04.21 06:01
koder
NEW 16.04.21 06:01 
в ответ AlexNek 15.04.21 21:06, Последний раз изменено 16.04.21 06:14 (koder)
В том то и дело что не знаю, догадываться могу, но не знаю, как он будете себя вести во всех ситуациях. На сетевом диске например.

Ты не можешь выяснять это юниттестами.

А отчего все должны запускаться при каждом коммите? Даже и на работе у нас было разделение, на ежедневные и после коммитные.

Ладно, при катгдом бильде. НО это неважно, политика фирмы, ты же должен расчитывать на то, что тесты будут долбиться постоянно много раз и в разных условиях, причем часто там, где конкретное исследование твоего мониторa нафиг не впало. Еще раз - коллега скачает код, код рухнет на бильде и именно коллега будет трахаться, не понимая, как его изменения могли привести к такому повреждению кода, что перестали идти юниттесты.

Ничего он думать не будет, у него будет сообщение с описанием проблемы. Типа "не могу создать тестовый каталог".

Ты походу никому не запарывал юниттестыулыб Результат - злоба за потерянное время.


Маловероятно для

Значит возможно. Значит нельзя.

После окончания теста каталог будет снесен вместе с содержимым? Безусловно и свободное место будет проверяться.

Представь, что у коллеги есть такой же каталог и там дорогие его сердцу фотографии шефа. Он запускает тесты, все прошло на ура и через пару дней он узнает, что ТВОЙ код что то удалил на ЕГО компе. Без запросов.

Зачем мне инвестировать время в приложение которое идет на помойку.

Точно затем же, зачем мы все это здесь обсуждаем. Какова цель создание приложения, которое идет на помойку? Научится делать правильно с учетом возможных последствий. Представь себе, что ты сдал униттест как учебное приложение во время собеседования. А там косяк...


#63 
koder патриот16.04.21 06:12
koder
NEW 16.04.21 06:12 
в ответ Murr 16.04.21 00:50, Последний раз изменено 17.04.21 05:39 (koder)
Да ну? И как же ты будешь эмулировать результат переполнения буфера если об этом даже не в курсе?

Мок не должен работать как оригинал. Более того, мок вообще не должен работать. Он должен уметь симулировать ответы оригинала. Нельзя протестовать юниттестами то, о чем не имеешь представления. Можно проверить свой код на устойчивость к общим ошибкам, но не к ошибке, о существовании которой ты не подозреваешь и которая возникает только в определенных условиях. Нельзя надеятся юниттестами что то отловить, о чем не подозреваешь - они предназначены для СТРОГО определенных целей и определенных программистом.

А то получается ни доки не посмотрел, ни практики не поимел, но об том КАК - вполне готов говорить... причем начиная с того что тебе непонятны описанные проблемы...

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

#64 
Программист коренной житель16.04.21 08:01
NEW 16.04.21 08:01 
в ответ AlexNek 15.04.21 23:45
Ну так это я нашел только после реального теста с файловой системой.

Ну если ты чтение мануалов хочешь заменить тестами, то у тебя долгий и трудный путь :)

FileSystemWatcher.NotifyFilter:

The default is the bitwise OR combination of LastWrite, FileName, and DirectoryName.


Это всё к тому что не нужно тестировать системные функции - они и так правильно работают.

Во-первых, тебе это говорили с самого начала.

Во-вторых, это правило распространяется не только на системные функции, но и вообще на все third party объекты. При этом это не просто объекты от посторонних производителей. При создании юнит-теста все внешние связи принимаются как работающие без ошибок. Даже если это "соседний" класс и тойже самой сборки, что и твой unit under test.


Как бы я с виртуальными тестами не извращался никогда бы не нашел.

Это да. Потому что искать надо было в мануалах. Тесты существуют не для поиска документации.

#65 
Программист коренной житель16.04.21 08:09
NEW 16.04.21 08:09 
в ответ Murr 16.04.21 00:50
Да ну? И как же ты будешь эмулировать результат переполнения буфера если об этом даже не в курсе?

Не понимаю, в чем проблема?


Ну так смотри.А то получается ни доkи не посмотрел, ни практики не поимел, но об том КАК - вполне готов говорить... причем начиная с того что тебе непонятны описанные проблемы...

AlexNek спрашивал как написать тест. При этом он не в состоянии ни описать проблему и ни сформулировать, что же он хочет протестировать. В таких условиях приходится фантазировать. А в результате выясняется, что он просто не прочитал мануал.

#66 
AlexNek патриот16.04.21 13:00
AlexNek
NEW 16.04.21 13:00 
в ответ Murr 16.04.21 00:58
Не-а... это мониторинг субфолдеров

Понимание данного аспекта приходит позже смущ

А поначалу кажется что всё по другому - "Gets or sets a value indicating whether subdirectories within the specified path should be monitored."

Если каталоги не мониторятся, то так вроде и нужно.

#67 
AlexNek патриот16.04.21 13:17
AlexNek
NEW 16.04.21 13:17 
в ответ koder 16.04.21 06:01
Ты не можешь выяснять это юниттестами.

Ну а чем тогда?

Меня сопровождение и прочее как-то совершенно не интересует в данное время.

Мне нужна какая то помощь во время разработки.

Да и на будущее делать эмулятор файловой системы совсем не хочется.


что у коллеги есть такой же каталог

Имя достаточно специфическое, да и можно документацию написать.

Это будет проще чем городить эмулятор файловой системы. Тем более что простых врапперов будет недостаточно.


Вот как раз сейчас новая проблема. Все по частям работает замечательно - а совместно фигвам. Чего то опять не учёл.


Научится делать правильно с учетом возможных последствий.

Ну если по теории нужно делать эмулятор и это будет правильно, то я не вижу когда данный путь будет приемлен. Затраты и результат просто несопоставимы.

#68 
AlexNek патриот16.04.21 13:22
AlexNek
NEW 16.04.21 13:22 
в ответ Программист 16.04.21 08:01
Ну если ты чтение мануалов хочешь заменить тестами

Это всё хорошо читать когда нашел проблему и ее решение.


При создании юнит-теста все внешние связи принимаются как работающие без ошибок.

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

#69 
Программист коренной житель16.04.21 13:56
NEW 16.04.21 13:56 
в ответ AlexNek 16.04.21 13:22
Да и на будущее делать эмулятор файловой системы совсем не хочется.

Mock-Object - это не эмулятор файловой системы :)


Это всё хорошо читать когда нашел проблему и ее решение.

Слушай, ну ведь дело-то не в этом. Дело в том, что ты не можешь сформулировать запрос.

В конце-концов, даже если бы не было проперти NotifyFilter, код DirectoryWatcher'а все равно можно сделать рабочим. Главное идентифицировать проблему. Ты этого не сделал. И тесты тут не при чем.


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

Нет. Есть разница межу "данные не имеют ошибок" и "компонента работает без ошибок".

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

#70 
koder патриот16.04.21 14:01
koder
NEW 16.04.21 14:01 
в ответ AlexNek 16.04.21 13:17
Меня сопровождение и прочее как-то совершенно не интересует в данное время.Мне нужна какая то помощь во время разработки.

AlexNek, ты определись, что тебе нужно. Если тебе нужно сделать законченное(пусть и учебное) классическое приложение с законченным циклом разработки, то нужно делать правильно. Если тебе нужно решить конкретную проблему(быстро выяснить, как что то работает), то неважно, какие средства ты у себя локально используешь. Они просто не должны попадать в общий репозиторий. Разумеется юниттесты удобны для запуска куска кода.

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

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

Затраты и результат просто несопоставимы.

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

#71 
koder патриот16.04.21 14:06
koder
NEW 16.04.21 14:06 
в ответ AlexNek 16.04.21 13:22
тогда получается что если мы принимаем данные от какого-то устройства, то они должны приходить без ошибок?

Ошибка - это неожиданная и не предусмотренная реакция кода на ситуацию. В шарпе ексцепшионы есть? так вот выброс исключения "переполнение буфера" - это не ошибка. Это ожидаемая реакция на черезвычайную ситуацию.Ошибка - это типа когда ты читаешь имя файла и если там есть пробел, то вдруг вылетает нульпойнтерексцепшион. И это никто не ожидает и так быть не должно.

#72 
Murr патриот16.04.21 18:21
Murr
NEW 16.04.21 18:21 
в ответ koder 16.04.21 06:12

Он должен уметь симулировать ответы оригинала.

------

Ну так для мока это и подразумевалось...

#73 
Murr патриот16.04.21 18:26
Murr
NEW 16.04.21 18:26 
в ответ koder 16.04.21 06:12

Тесты для системной функции нафиг никому не нужны.

-----

Но понять ее ограничения как-то надо? Тут либо доки грызть - а там не всегда все внятно описано, либо какие-то моменты прояснять тестированием. Заметь - Я не сказал - юнит тестами.

#74 
Murr патриот16.04.21 20:10
Murr
NEW 16.04.21 20:10 
в ответ Программист 16.04.21 08:09

он просто не прочитал мануал

-----

Два вопроса:

- Ты всегда однозначно понимаешь написанное в доках?

- Что делать... хотя... у тебя есть возможность сказать что это не твоя проблема....

#75 
Программист коренной житель16.04.21 20:27
NEW 16.04.21 20:27 
в ответ Murr 16.04.21 20:10

Странный ты.

Ты понимаешь, что в данном случае проблема не в мануале?

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

Ну это как если бы тебе дали зажигалку и сказали, "этой штукой разжигают огонь и можно круто пожарить шашлыки". А ты такой взял эту зажигалку, сел в машину и спалил ее к чертям, т.к. там тоже есть "зажигание" и вообще машина с ДВС едет за счет горения.


#76 
koder патриот16.04.21 22:31
koder
NEW 16.04.21 22:31 
в ответ Murr 16.04.21 18:26
либо какие-то моменты прояснять тестированием. Заметь - Я не сказал - юнит тестами.


Блин, я пока дочитал до конца, уже опровержение писать начал. Блин, ну нельзя же так вот последняя фраза и писать нечего😁

#77 
Murr патриот17.04.21 03:36
Murr
NEW 17.04.21 03:36 
в ответ koder 16.04.21 14:06

выброс исключения "переполнение буфера"

-----

А оно там есть? спок

#78 
koder патриот17.04.21 05:39
koder
NEW 17.04.21 05:39 
в ответ Murr 17.04.21 03:36

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


#79 
AlexNek патриот17.04.21 13:48
AlexNek
NEW 17.04.21 13:48 
в ответ Программист 16.04.21 13:56
В конце-концов, даже если бы не было проперти NotifyFilter, код DirectoryWatcher'а все равно можно сделать рабочим. Главное идентифицировать проблему.

Главное догадаться - какие то проблемы могут быть смущ

Поначалу хотелось иметь хоть что то.

#80 
AlexNek патриот17.04.21 14:13
AlexNek
NEW 17.04.21 14:13 
в ответ koder 16.04.21 14:01
ты определись, что тебе нужно.

На каждом шаге разное спок

Для начала мне нужно рабочее приложение.

Затем среда для его тестирования.

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

А прога в итоге и не работает всегда правильно.

Если бы у приложения была бы какая-то нетривиальная логика, то еще какой то смысл был бы. А так, просто последовательность шагов: сжать и переместить.

Но всё завязано именно на манипуляциях с файловой системой, которую трогать низзя.


На крупной фирме с сотней программистов

Сорри, с такими еще не сталкивался и думаю что уже и не получится. Чтобы целая сотня над чем то одним работала. смущ


Но в твоем случае (я не программирую на шарпе) на яве это элементарно

Не вижу особой разницы в языках, но и элементарности тоже не вижу.

#81 
AlexNek патриот17.04.21 14:16
AlexNek
NEW 17.04.21 14:16 
в ответ koder 16.04.21 14:06, Последний раз изменено 17.04.21 20:02 (AlexNek)
В шарпе ексцепшионы есть?

Естественно. Я вот только не слышал что в Яве WPF есть.

Ну вот если устройство мне посылает дату 30.02.2021 - это как класифицировать?

#82 
Murr патриот17.04.21 15:02
Murr
NEW 17.04.21 15:02 
в ответ Программист 16.04.21 20:27

и при этом не понял

------

Ну так разъяснил бы. На доки не кивай - там описание с проблеммами.

А то Я эту фигню пытался использовать года 4 назад и уже подзабыл.

Что вспоминал - пояснял.

Вот про поведение буфера - не помню - никогда не сталкивался...

#83 
Программист коренной житель17.04.21 16:31
NEW 17.04.21 16:31 
в ответ Murr 17.04.21 15:02, Последний раз изменено 17.04.21 16:32 (Программист)
Ну так разъяснил бы.

В этом топике уже все объяснено. Но боюсь, что ни ты, ни AlexNek просто не хотите понимать.


Так что изучайте сами :) А если появятся вопросы, то велком :)

#84 
koder патриот17.04.21 19:59
koder
NEW 17.04.21 19:59 
в ответ AlexNek 17.04.21 14:16
Ну вот если устройство мен


Я не понял предложение что значит "устройство мен"

#85 
AlexNek патриот17.04.21 20:02
AlexNek
NEW 17.04.21 20:02 
в ответ koder 17.04.21 19:59

Спасибо, исправил


Ну вот если устройство мне посылает дату 30.02.2021 - это как класифицировать?

#86 
AlexNek патриот17.04.21 22:01
AlexNek
NEW 17.04.21 22:01 
в ответ Программист 17.04.21 16:31
просто не хотите понимать.

мы не первые и не последние смущ


Recently there’s been some discussion in the community about a long-held belief regarding unit tests: A unit test should not touch the filesystem.

https://www.leadingagile.com/2017/12/should-unit-tests-tou...

#87 
MrSanders коренной житель17.04.21 22:54
NEW 17.04.21 22:54 
в ответ AlexNek 17.04.21 22:01

Ага. Первой беды не только в России, по всему миру на 100 лет вперёд припасено. Автора этого бложика явно припасли с запасом.

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

Если вы хотите тестировать стороннюю библиотеку - пожалуйста, ради бога. Но называйте эти тесты как минимум "интеграционными". Хотите протестировать скорость выполнения? Нет преграды патриотам. Но не называйте это юнит-тестом. Назовите "нагрузочным тестом".

Понимаете?

#88 
AlexNek патриот17.04.21 23:17
AlexNek
NEW 17.04.21 23:17 
в ответ MrSanders 17.04.21 22:54
Но не называйте это юнит-тестом

Да один фиг как назвать, главное что бы был польза.

#89 
koder патриот18.04.21 06:39
koder
NEW 18.04.21 06:39 
в ответ AlexNek 17.04.21 23:17
Да один фиг как назвать, главное что бы был польза.


Нет. Как раз очень важно. Юниттест это не просто технология, позволяющая запустить кусок кода без создания полного контекста приложения. Это еще и технология, которая применяется в определенных местах. Строго определенных. Именно поэтому юниттест с определенным кодом вызавает недоумение - он просто не лезет в эти самые места. То ты и не собираешься его туда пихать. У тебя другие цели.В результате мы перепинаемся уже под сотню постов на ровном месте.


Вопрос определениj и основанного на них понимания.

#90 
MrSanders коренной житель18.04.21 10:17
NEW 18.04.21 10:17 
в ответ AlexNek 17.04.21 23:17
Да один фиг как назвать, главное что бы был польза.

Садись, два! (c)


- Тема: велосипед, чтобы ездить на работу

- А в чём проблема?

- Мне до работы 150 км в одну сторону

- Тогда, наверное, нужен не велосипед а машина? Или на велосипеде доезжать только до вокзала?

- Какое гавно эти ваши велосипеды, а все рассказывают что только на них надо ездить

- Так может всё же нужна машина?

- Один фиг как называть, лишь бы на работу доехать.


Звучит глуповато, не?


Может всё же определиться для начала что же тестировать надо, а потом выбирать чем и как?

#91 
AlexNek патриот18.04.21 11:46
AlexNek
NEW 18.04.21 11:46 
в ответ MrSanders 18.04.21 10:17
Может всё же определиться для начала что же тестировать надо

По историческим причинам было наоборот смущ

Согласно условию задачи требовались юнит тесты. Но как оказалось, они смысла особого не имеют в данном случае.

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

Для "поиграться" всё слишком много по времени. По крайней мере, нашел проблемы и чему то научился.


Мне бы лучше приложение из Azure на свой сервер перекинуть, хоть абонплату сэкономил бы.

#92 
MrSanders коренной житель18.04.21 12:29
NEW 18.04.21 12:29 
в ответ AlexNek 18.04.21 11:46
Согласно условию задачи требовались юнит тесты. Но как оказалось, они смысла особого не имеют в данном случае.

Из моего опыта последних 10 лет - юнит тесты нужны всегда если проект должен жить дольше 6 месяцев. И смысл в них есть. Даже для геттера надо писать тест. Потому что уже не раз и не два были очепятки. А потом - ой, а чего это мы вместо 16 потоков используем 62342? А перепутали. Закопипейстелись. При инициализации менеджера uid пользователя из параметра конструктора записали и в поле uid и в поле maxThreads.

А чтобы найти эту примитивную ошибку, тратишь не минуту и не час. А потом еще и задеплой всё заново.

#93 
AlexNek патриот18.04.21 12:48
AlexNek
NEW 18.04.21 12:48 
в ответ MrSanders 18.04.21 12:29
если проект должен жить дольше 6 месяцев.

А если проект будет жить 0 часов, 0 минут?

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

При этом для разработки они мне почти бессмысленны.


Вот в другом проекте, где дофига логики, там без них и шагу ступить невозможно.

#94 
MrSanders коренной житель18.04.21 14:22
NEW 18.04.21 14:22 
в ответ AlexNek 18.04.21 12:48
А если проект будет жить 0 часов, 0 минут?

То даже код проекта можно не писать.

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

Сложность написания юнит-тестов - хороший индикатор дерьмовости кода.

#95 
AlexNek патриот18.04.21 15:28
AlexNek
NEW 18.04.21 15:28 
в ответ MrSanders 18.04.21 14:22
Сложность написания юнит-тестов - хороший индикатор дерьмовости кода.

не всегда. Вот что тут дерьмового?


compressor.CompressFile(sourceFile);

mover.MoveFile(sourceFile, desctinationFile)


#96 
MrSanders коренной житель18.04.21 15:54
NEW 18.04.21 15:54 
в ответ AlexNek 18.04.21 15:28

Практически всегда. В 95% случаев.

В приведённом коде проблем нет, но для него и юнит-тесты написать совершенно несложно. Делаем моки для copressor и mover и вперёд.

#97 
AlexNek патриот18.04.21 16:02
AlexNek
NEW 18.04.21 16:02 
в ответ MrSanders 18.04.21 15:54
Делаем моки для copressor и mover и вперёд.

Может быть я еще неправильно представляю себе как делать моки?


Для меня - это написать два тест враппера и передать их вместо реальных.

#98 
MrSanders коренной житель18.04.21 17:51
NEW 18.04.21 17:51 
в ответ AlexNek 18.04.21 16:02

Как именно делать моки - дело вкуса. Сегодня глупо не использовать для этого библиотеки. Я честно говоря не знаю что сейчас для шарпа есть, лет 5 назад даже easymock.net был, не знаю, может и жив ещё.

Главное чтобы с минимальными усилиями было получить реализацию интерфейса ICompressor (пусть он так называется), у которой мы определяем ТОЛЬКО метод CompressFile. А все остальные 20 методов нам глубоко не интересны. И для разных тестов определяем поведение этого метода:

1. что-то нам нужное вернёт (строку, код состояния, мок объекта)

2. вернет что-то неправильное (пустую строку, неизвестный код, нуль)

3. бросит исключение

И проверяем что наш код всё это правильно переварит.

#99 
AlexNek патриот18.04.21 19:57
AlexNek
NEW 18.04.21 19:57 
в ответ MrSanders 18.04.21 17:51

Ну вот вроде популярная либа Moq

https://habr.com/ru/post/150859/


Всё что она может сэкономить - это не писать заглушку.

Но усложнять код все равно придётся, так как и компрессор и мувер нужно передать извне в тестируемый класс. А еще есть и третий класс - обозреватель каталога.

То бишь в "главный класс" нужно передать минимум 3 совершенно не нужных параметра, а с экспортом и 4. Соответственно и количество лишних интерфейсов возрастает.

В общем, KISS - пошел нафиг.

Ну и как проверить конкретные имплементации интерфейсов вопрос остается открытым.

Например, как проверить, что когда компрессор создает файл, то этот файл будет игнорироваться обозревателем каталога. Хотя, даже как это проверить можно и что то придумать, а вот как до этого "дойти" в тестовой системе не имею представления.

MrSanders коренной житель18.04.21 20:29
NEW 18.04.21 20:29 
в ответ AlexNek 18.04.21 19:57
То бишь в "главный класс" нужно передать минимум 3 совершенно не нужных параметра, а с экспортом и 4. Соответственно и количество лишних интерфейсов возрастает.
В общем, KISS - пошел нафиг.

Насчёт ненужных я бы поспорил. И насчёт нарушения KISS. Если компрессор и мувер не передаются снаружи значит что? Значит класс такой "умный" что сам знает как их сделать. Во-первых это сложнее чем получить их снаружи. Во-вторых это а. дополнительная ответственность и б. нарушение open-close. Аж две буквы из SOlid поломали.

AlexNek патриот18.04.21 21:03
AlexNek
NEW 18.04.21 21:03 
в ответ MrSanders 18.04.21 20:29
Аж две буквы из SOlid поломали.

У меня есть одна проблема - не люблю слепо следовать догмам. Не люблю делать универсальных монстров и стрелять из пушки по воробьям.

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

Ну и делать конструкторы вьювмоделей с параметрами для ВПФа, тоже не очень хорошо.


Тем более, что прога не идет в промышленную эксплуатацию на многие годы.


Программист коренной житель18.04.21 21:15
NEW 18.04.21 21:15 
в ответ AlexNek 18.04.21 21:03, Последний раз изменено 18.04.21 21:17 (Программист)
Ну и делать конструкторы вьювмоделей с параметрами для ВПФа, тоже не очень хорошо.

Почему это?


Тем более, что прога не идет в промышленную эксплуатацию на многие годы.

Насколько я понимаю, в твоем случае речь идет о тестовом задании. Так вот при выполнении тестового задания от тебя хотят увидеть а) понимание технологии юнит-тестирования и б) красивое решение, желательно по SOLID.


AlexNek патриот18.04.21 21:28
AlexNek
NEW 18.04.21 21:28 
в ответ Программист 18.04.21 21:15
Почему это?

Добавь в подобную конструкцию еще параметры смущ


<Window.DataContext>
        <local:CustomViewModel />
</Window.DataContext>
...
<Window.Resources>
        <local:MyViewModel x:Key="MyViewModel"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource MyViewModel}">
    </Grid>
<pre>


от тебя хотят увидеть

Скорее услышать. Времени то челу дали всего час. Кто то за час всё сделает?

Программист коренной житель18.04.21 21:50
NEW 18.04.21 21:50 
в ответ AlexNek 18.04.21 21:28
Добавь в подобную конструкцию еще параметры

Ну просто инициализируешь ViewModel не в XAML, а в code behind, а именно:

     InitializeComponent();
     DataContext = new CustomViewModel(what-ever);


не вижу в этом никакой проблемы.


Скорее услышать. Времени то челу дали всего час. Кто то за час всё сделает?

Час конечно маловато. Но подход увидеть вполне можно.

AlexNek патриот18.04.21 22:07
AlexNek
NEW 18.04.21 22:07 
в ответ Программист 18.04.21 21:50
Ну просто инициализируешь ViewModel не в XAML

Получается что следуя одному принципу мы закрываем другие.

Не могу уже вспомнить конкретную проблему, но пришлось специально убирать все параметры из конструктора. Не всегда можно code behind пользовать


Но подход увидеть вполне можно.

Ну сделай эксперимент, что получится сделать за час. Даже на своём компе. Главное - не копипастить смущ

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

Программист коренной житель18.04.21 22:32
NEW 18.04.21 22:32 
в ответ AlexNek 18.04.21 22:07
Получается что следуя одному принципу мы закрываем другие.

Не понял, что мы закрываем?


Не могу уже вспомнить конкретную проблему, но пришлось специально убирать все параметры из конструктора. Не всегда можно code behind пользовать

Не встречал еще ситуации, когда нет code behind.

Если у тебя есть элегантный способ передать настройки во ViewModel, то было бы интересно посмотреть на этот способ. А то я эля таких ситуаций использую параметры контруктора :)


Ну сделай эксперимент, что получится сделать за час.

Честно говоря, мне лень :) Думаю, что в течении дня я бы сделал то задание.


koder патриот19.04.21 06:14
koder
NEW 19.04.21 06:14 
в ответ AlexNek 18.04.21 16:02, Последний раз изменено 19.04.21 06:21 (koder)
Может быть я еще неправильно представляю себе как делать моки?


Где то вот так


@Mock

Copressor copressor


Все. теперь обьект, которыj создаст библиотека мокито, можно использоват'

koder патриот19.04.21 06:20
koder
NEW 19.04.21 06:20 
в ответ AlexNek 18.04.21 19:57
То бишь в "главный класс" нужно передать минимум 3 совершенно не нужных параметра, а с экспортом и 4. Соответственно и количество лишних интерфейсов возрастает.

Не надо. Технологии WhiteBox, инектирование, подмена переменных класса во время выполнения. Это можно делать даже для приватных переменных. Но переменные можно делать наследуемыми и тестировать наследников класса с дополнительными сеттерами.Есть много способов внедрить мок вместо реального обьекта. А вот если нельзя, значит в классе проблемы. И функциональный и инитиализатионных код свален в одну кучу.

AlexNek патриот19.04.21 12:41
AlexNek
NEW 19.04.21 12:41 
в ответ Программист 18.04.21 22:32
Не понял, что мы закрываем?

Ну хотя бы инициализацию из ХАМЛа. Как передать во вьюв-модель из ХАМЛа что-то кроме строки я не знаю.


Не встречал еще ситуации, когда нет code behind.

Тоже было до поры до времени, пока более сложный UI не понадобился.


Если у тебя есть элегантный способ передать настройки во ViewModel

Они просто идут вторым шагом, через сервис например или через сообщения.


Думаю, что в течении дня я бы сделал

Я тоже так думал, но не получилось. смущ Там проблем больше чем вначале думаешь.

Но возьми даже 1/8 часть готового приложения, что это будет в итоге?

AlexNek патриот19.04.21 12:43
AlexNek
NEW 19.04.21 12:43 
в ответ koder 19.04.21 06:20
Есть много способов внедрить мок вместо реального обьекта

Я пока знаю только тот, который описал. Поищем другие "либы".

Программист коренной житель19.04.21 13:02
NEW 19.04.21 13:02 
в ответ AlexNek 19.04.21 12:41
Они просто идут вторым шагом, через сервис например или через сообщения.

Ну так и DI можно также делать ;)

AlexNek патриот19.04.21 13:03
AlexNek
NEW 19.04.21 13:03 
в ответ MrSanders 18.04.21 20:29
Во-вторых это а. дополнительная ответственность

Вот другая проблема есть, решение которой мне совершенно не нравиться, но пока не могу придумать лучше.


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

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

Каждая операция реализована как вызов функции из дополнительного класса. Но вот эти все вызовы расположены в одном месте и они все разные.

С одной стороны это файловый операции, а с другой стороны, добавление новых элементов в UI и их сохранение.


Хотелось, хотя бы отделить файловые операции и UI, только как тогда информировать нужный UI элемент об ошибке.

AlexNek патриот19.04.21 13:19
AlexNek
NEW 19.04.21 13:19 
в ответ Программист 19.04.21 13:02
Ну так и DI можно также делать

Если речь идёт о DI Container/Frameworks, то я их пока не переношу.

Когда всё приложение так построено, разобраться в его работе очень сложно.

Так поставил точку останова в конструкторе и знаешь кто и откуда вызвал. А с контейнером поди еще найди как эта инстасе получается т откуда пришел вызов.

Программист коренной житель19.04.21 13:22
NEW 19.04.21 13:22 
в ответ AlexNek 19.04.21 13:19
Если речь идёт о DI Container/Frameworks, то я их пока не переношу.

Нет, речь о том, что все зависимости можно устанавливать точно также как и передовать конфигурацию во ViewModel.

AlexNek патриот19.04.21 14:08
AlexNek
NEW 19.04.21 14:08 
в ответ Программист 19.04.21 13:22
то все зависимости можно устанавливать точно также как и передовать конфигурацию

Так дело то не только в этом - как передавать, а в том зачем передавать? Зачем создавать универсального монстра, если для этого нет объективных причин?

Программист коренной житель19.04.21 14:14
NEW 19.04.21 14:14 
в ответ AlexNek 19.04.21 14:08

От куда ты взял универсального монстра? Ты как-то не так понимаешь DI улыб

AlexNek патриот19.04.21 14:42
AlexNek
NEW 19.04.21 14:42 
в ответ Программист 19.04.21 14:14
Ты как-то не так понимаешь DI

Может быть. У меня есть просто различия, когда нужно, а когда нет. А не только - исключительно всё на интерфейсах внутри, а снаружи вся имплементация.

Ну зачем мне ещё добавлять "интерфейс компрессии файла" и выводить его наружу? Только для того, что может быть когда то, кто то захочет его имплементировать по другому, оставив при этом и старую версию.

Хочешь менять - меняй, всё в отдельном классе. Когда понадобится вторая имплементация, можно будет сделать, но никак не раньше того, чем вероятно может понадобится или понадобилось.

В данном случае - вероятность изменений практически нулевая.


Программист коренной житель19.04.21 15:45
NEW 19.04.21 15:45 
в ответ AlexNek 19.04.21 14:42
Ну зачем мне ещё добавлять "интерфейс компрессии файла" и выводить его наружу?

Ну тут есть несколько моментов:

1) для того, чтобы код был тестируемым.

2) чтобы класс отвечал только за то, чем он занимается. И не занимался 2-мя, 3-мя и более вещами. Single Responsibility.

3) расширяемость


У меня есть просто различия, когда нужно, а когда нет.

Ну просто для тебя "нужно" - это только расширяемость :) Но на самом деле расширяемость - это просто побочная плюшка :D


MrSanders коренной житель19.04.21 16:11
NEW 19.04.21 16:11 
в ответ AlexNek 19.04.21 13:03
Хотелось, хотя бы отделить файловые операции и UI, только как тогда информировать нужный UI элемент об ошибке.

Event-ы наше всё!

AlexNek патриот19.04.21 16:21
AlexNek
NEW 19.04.21 16:21 
в ответ Программист 19.04.21 15:45
1) для того, чтобы код был тестируемым.

Вот именно с этим у меня и наблюдаются проблемы.

Я не хочу исключительно только для тестирования добавлять море вещей которые мне совсем не нужны.


2) чтобы класс отвечал только за то, чем он занимается.

А класс и не занимается сжатием, за это отвечает другой класс.

Если кто-то захочет изменить сжатие, то он будет это менять в другом месте.


3) расширяемость

Зачем предусматривать расширяемость, когда эта расширяемость не понадобится.

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

AlexNek патриот19.04.21 16:34
AlexNek
NEW 19.04.21 16:34 
в ответ MrSanders 19.04.21 16:11
Event-ы наше всё!

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

Записывать все данные может быть и можно. Но для этого у меня и так внешний Action есть.

Программист коренной житель19.04.21 16:48
NEW 19.04.21 16:48 
в ответ AlexNek 19.04.21 16:21
Я не хочу исключительно только для тестирования добавлять море вещей которые мне совсем не нужны.

Ну нет проблем :) Просто в таком случае ты пишешь код, который нельзя протестировать юнит-тестами. Есть и другие способы протестировать код :)


А класс и не занимается сжатием, за это отвечает другой класс.
Если кто-то захочет изменить сжатие, то он будет это менять в другом месте.

Твой класс как минимум создает объект, который занимается сжатием и конфигурирует/инициализирует этот объект.


Зачем предусматривать расширяемость, когда эта расширяемость не понадобится.

Затем, что это приятный бонус, который ты получаешь совершенно бесплатно, если проектируешь софт по определенным правилам :)


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

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

AlexNek патриот19.04.21 17:31
AlexNek
NEW 19.04.21 17:31 
в ответ Программист 19.04.21 16:48
Твой класс как минимум создает объект

Ну и что, кто то всё равно должен его создать. Всё что мы теряем - это динамическая замена. Которая относится к разряду ненужных.


если проектируешь софт по определенным правилам

правила и так есть, только не следует понимать их буквально.

То бишь, нужно мне в классе, допустим, 10 операций, то всех их абсолютно обуть в классы и интерфейсы и инициализировать строго снаружи.


В автомобиле можно поставить вместо приборной доски полноценный дисплей

Можно, но вот парашют и крылья считаешь, что не нужно?

Вот у меня такое же деление и есть, когда нужно - то делаем, когда не нужно - то нет.


А вот лет 50 так назад, ты бы тоже считал, что можно поставить туды "полноценный дисплей"?

С другой стороны, у меня в ентом авто приборная доска и управление работает чисто механически. И что бы переделать всё в цифру нужно затратить много времени и денег.


То бишь, дырки для крепления сделать еще могу, а вот подсоединить текущие приборы через разъем ну никак не получится.


AlexNek патриот19.04.21 22:08
AlexNek
NEW 19.04.21 22:08 
в ответ AlexNek 19.04.21 17:31

Вообще то, как оказалось, есть более приемлемый метод для меня.

достаточно вместо

compressor.Compress(fileName);

написать

CompressFile(fileName);


virtual void CompressFile(string fileName)

{

compressor.Compress(fileName);

}


А затем уже замокать эту виртуальную функцию.

koder патриот20.04.21 06:48
koder
NEW 20.04.21 06:48 
в ответ AlexNek 17.04.21 20:02
Ну вот если устройство мне посылает дату 30.02.2021 - это как класифицировать?

Сорры. Только сейчас заметил


Это особенность устройства. Программист писал насчет фичи, но общий принцип такой - устройство может посылать инфу в определенном кодирунге, на китайском языке, в странном формате. Если такой вывод использовать нельзя, то и устройство использовать нельзя. Если можно с последующей обработкой. то нужен код обработки. Но долбить эту особенность устройства юниттестами (долбить - потому что юниттесты запускаются автоматически регуларно, проверяя код) нет смысла - особенность устройства извeстна и не изменится. А вот собственный код обработки особенности можно и нужно


Murr патриот20.04.21 12:15
Murr
NEW 20.04.21 12:15 
в ответ koder 20.04.21 06:48

особенность устройства известна и не изменится

-----

Хи-хи...

Из того что помню.

Три завода, три инсталяции Оракла.

Каждая инсталяция - мало того что другой версии, так еще и со своей локалью.

Соответственно - формат даты и времени - разный, порядок сравнения и сортировок - тоже разный.

Код - общий для всех баз...


нет смысла

-----

Оно, вообще-то, программируемое. безум

Программист коренной житель20.04.21 13:12
NEW 20.04.21 13:12 
в ответ Murr 20.04.21 12:15
Хи-хи... Из того что помню.Три завода, три инсталяции Оракла.Каждая инсталяция - мало того что другой версии, так еще и со своей локалью.Соответственно - формат даты и времени - разный, порядок сравнения и сортировок - тоже разный.Код - общий для всех баз..

Ты реально не понимаешь, что нет нужды тестировать порядок сравнения и сортировку в Оракле? Или просто прикидываешься?

AlexNek патриот20.04.21 13:25
AlexNek
NEW 20.04.21 13:25 
в ответ koder 20.04.21 06:48
Если такой вывод использовать нельзя, то и устройство использовать нельзя.

вывод использовать нельзя, но вот устройство нужно.

Это как раз и тестирует "мой" код - он не должен обваливаться если даже устройство пошлет что то неправильное.

Так что тесты нужны, хоть часть будет юнит тестами, а часть интеграцион тестами.


особенность устройства извeстна и не изменится

никакой документированной особенности устройства доверять нельзя смущ

Всё нужно проверять. Пару раз железячников на этом и поймали.

koder патриот20.04.21 15:42
koder
NEW 20.04.21 15:42 
в ответ Murr 20.04.21 12:15
Каждая инсталяция - мало того что другой версии, так еще и со своей локалью.

Как часто у одной инсталляции менялись свойства?


Оно, вообще-то, программируемое.

Ты хотел сказать конфигурируемое. Програмируемое - это дата 31.02.2021. Напрограмировали


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


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


Потом если у инсталляции установили китайскую локаль, то значит так надо было. Не думаю, что имеет смысл в приложении опрашивать текущую локаль базы данных. Я даже не заню, кто то это делает? Просто настраивают систему (прога+база) и это эта связка до следующей настройки считается неизменяемоj

Murr патриот20.04.21 21:19
Murr
NEW 20.04.21 21:19 
в ответ Программист 20.04.21 13:12

нет нужды

-----

Не-не, нету...

Есть нужда проверять правильно ли строится СКЛ... так ВБ6-лике спагетти...

Я как подумаю об коде в котором надо такое тестить так желание что-то делать пропадает напроч'...

Murr патриот20.04.21 21:23
Murr
NEW 20.04.21 21:23 
в ответ AlexNek 20.04.21 13:25

вывод использовать нельзя, но вот устройство нужно.

------

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

AlexNek патриот20.04.21 21:38
AlexNek
NEW 20.04.21 21:38 
в ответ Murr 20.04.21 21:23
надо дрючить девайсе из тестов

девайс не надо, только приложение.

Murr патриот20.04.21 21:38
Murr
NEW 20.04.21 21:38 
в ответ koder 20.04.21 15:42

Как часто у одной инсталляции менялись свойства?

------

А какая разница?

Я не контролирую сервера - может поменяться в любой момент и без уведомления.

То, что это не декаки с момента установки ситуацию никак не меняет.


Проверить все это невозможно даже в принципе.

-----

Ну наконец-то... правда пока не вижу понимания того что проверить можно только то об чем знаешь...



значит так надо было.

------

Да ну?

Мне вот всегда казалось, что это от непонимания того, что от этого что-то зависит.

По крайней мере в рамках одного предприятия.



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

------

Т.е. принимается как норма, что как только в запросе требуется фильтрация по дате, то приложение дожно упасть? Ну или выдать какую-нибудь чушь...



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

------

Еще раз.

Автоматизированное рабочее место.

Одна инсталяция программы.

Работает с тремя различными серверами, каждый из которых имеет свой диалект СКЛ и другую локаль.

Я чего - должен бегать туда каждый раз как девочке приспичит что-то сделать на другом серваке?

Murr патриот20.04.21 21:50
Murr
NEW 20.04.21 21:50 
в ответ AlexNek 20.04.21 21:38

девайс не надо, только приложение

------

Присылали мне как-то файлик для импорта.

Без документации на формат - только ссылка на то, что он в каком-то внутреннем стандарте третьей стороны - они ничего другого экспортировать не умели. Готового редера - не было.

Внутри только дат было три разных формата, причем один из них вводился текстом в ручную...

Так будем тестить приложение или будем дрючить источник?

koder патриот20.04.21 21:50
koder
NEW 20.04.21 21:50 
в ответ Murr 20.04.21 21:38
Я чего - должен бегать туда каждый раз как девочке приспичит что-то сделать на другом серваке?

Даже чаще. Проверять локаль. А вдруг девочке приспичило и ты пропустил смену локали😀

Программист коренной житель20.04.21 22:33
NEW 20.04.21 22:33 
в ответ koder 20.04.21 21:50

ЕМНИП Datetime - это просто число и локаль там по большому счету не нужна. А для того, чтобы безошибочно конвертнуть строку в DateTime можно использовать функцию CONVERT и передавать в ней дату в любом удобном и при этом заранее изместном виде :)


Подозреваю, что Murr как обычно простелил себе колено :)

Murr патриот20.04.21 23:02
Murr
NEW 20.04.21 23:02 
в ответ Программист 20.04.21 22:33

это просто число

------

Вообще-то, в контексте СКЛ это будет строка в определенном формате.


можно использовать функцию CONVERT

------

Можно.

Но можно упереться в ограничение на длинну выражения в IN... безум

И, кстати, КОНВЕРТ тормозит довольно прилично... хотя основное - он там вообще не нужен, если не требуется вывод в определенном формате...



Murr как обычно простелил себе колено

-----

Ну если понимае маленького момента что локаль базы и локаль сессии - это две независимых локали есть выстрел в колено - то - да, прострелил оба... спок

Как насчет изучения мат.части? улыб

Murr патриот20.04.21 23:05
Murr
NEW 20.04.21 23:05 
в ответ koder 20.04.21 21:50

и ты пропустил

-----

Да-да... Я как-то пропустил смену локали у более чем 9 млд девочек... и меня это как-то совсем не беспокоит... не дергают и хорошо...

AlexNek патриот21.04.21 11:32
AlexNek
NEW 21.04.21 11:32 
в ответ Murr 20.04.21 21:50
Без документации на формат...или будем дрючить источник?

В этом случае нужно как то добыть информацию, да и задача несколько другая.

В моём случае задача - приложение не должно вылетать при любых ошибках в источнике.

Поэтому что и как выдает источник меня не волнует. Меня волнует, как я буду принимать данные с ошибками.

Murr патриот21.04.21 13:41
Murr
NEW 21.04.21 13:41 
в ответ AlexNek 21.04.21 11:32

как я буду принимать данные с ошибками

------

А у меня задача какая-то другая? безум

AlexNek патриот21.04.21 14:11
AlexNek
NEW 21.04.21 14:11 
в ответ Murr 21.04.21 13:41
А у меня задача какая-то другая?

Видимо да, если ты собираешься тестировать передатчик, а не приёмник.

koder патриот21.04.21 17:53
koder
NEW 21.04.21 17:53 
в ответ AlexNek 21.04.21 11:32
В моём случае задача - приложение не должно вылетать при любых ошибках в источнике.Поэтому что и как выдает источник меня не волнует. Меня волнует, как я буду принимать данные с ошибками.

О! И если данные приходqт как текст, а ты конвертируешь его в обьект, то должен предусмотреть стандартные возможности - строка пустая или несуществует, строка не может быть конвертирована. И написать юниттесты для этих случаев, как реагирует твой код.

AlexNek патриот21.04.21 21:06
AlexNek
NEW 21.04.21 21:06 
в ответ koder 21.04.21 17:53
И написать юниттесты для этих случаев, как реагирует твой код

А кто с этим спорит? Так и было сделано.

Murr патриот21.04.21 22:33
Murr
NEW 21.04.21 22:33 
в ответ AlexNek 21.04.21 14:11

собираешься тестировать передатчик

------

Черный ящик без документации... не тестировать, а мокать... Как?

koder патриот22.04.21 07:36
koder
NEW 22.04.21 07:36 
в ответ Murr 21.04.21 22:33
Черный ящик без документации... не тестировать, а мокать... Как?

Элементарно. Какое то представление о черном ящике все таки есть. Ну все публичные методы там присутствуют. С описанием параметров вызова и checked исключениями.


Именно это и мокаем. Мок должен уметь принимать те параметры, какие есть у реального обьекта и возвращать то, что возвращает реальный обьекt


Murr патриот22.04.21 14:55
Murr
NEW 22.04.21 14:55 
в ответ koder 22.04.21 07:36

и возвращать то, что возвращает реальный обьекt

------

Именно этого мы как раз и не знаем...

koder патриот23.04.21 05:55
koder
NEW 23.04.21 05:55 
в ответ Murr 22.04.21 14:55, Последний раз изменено 23.04.21 05:55 (koder)
Именно этого мы как раз и не знаем...


Ну во первых мы точно знаем тип данных того, что возвращает обьект. Точно.

Во вторых мы знаем, что делать с тем, что возвращает обьект. Точно.


Поэтому тесты это реакция, как правильно реагирует НАША система на все мыслемые комбинации того, что возвращает чужой обьект. И мок это будет то, как мы себе это представляем.


Например чужой обект возвращает стринг. Значит наш мок должен уметь возвращать и null. И пофиг, может это делать настоящий обьект или нет


Напримет чужой обект возвращает обьект класса. Значит наш мок должен уметь возвращать и налль и недоинициализированный обьект класса. И пофиг, может это делать настоящий обьект или нет

Murr патриот23.04.21 06:29
Murr
NEW 23.04.21 06:29 
в ответ koder 23.04.21 05:55

обект возвращает стринг

-----

Как это замечательно, когда есть стринг! Буковки, циферьки, длина - так много информации с которой можно работать...

А как насчет какого-то двойчного набора слегка перемежаемого прерываниями? смущ

Да и со строками Я как-то обрисовывал весьма проблемный вариант - ЗигБии называется... безум

Программист коренной житель23.04.21 08:18
NEW 23.04.21 08:18 
в ответ koder 23.04.21 05:55
Ну во первых мы точно знаем тип данных того, что возвращает обьект. Точно.
Во вторых мы знаем, что делать с тем, что возвращает обьект. Точно.

Выдыхай уже :) Murr просто не знает, что такое "черный ящик" улыб

koder патриот23.04.21 11:11
koder
NEW 23.04.21 11:11 
в ответ Murr 23.04.21 06:29
А как насчет какого-то двойчного набора слегка перемежаемого прерываниями? смущДа и со строками Я как-то обрисовывал весьма проблемный вариант - ЗигБии называется...

В меру своей фантазии. Черный ящик возвращает что то. Ты точно знаешь, что с этим делать. Иначе ты вообще не можешь его использовать. Ты ТОЧНО знаешь, какие проблемы могут возникнуть, иначе ты не подготовил СВОЙ код и что же ты собираешься тестовать? Вот мок и возвращяет то, что ты ожидаешь. Все мыслимые варианты. Немыслемые и неожиданные не нужны, ты все равно не готов в своем коде их отрабатывать.


Буковки, циферьки, длина - так много информации с которой можно работать...

Именно. Если твой код имеет 100500 вариантов реакции на различные варианты - нужно 100500 вариантов поведения мока. Да, тесты рисовать может быть затратно по времени.

Murr патриот23.04.21 12:12
Murr
NEW 23.04.21 12:12 
в ответ koder 23.04.21 11:11

Ты ТОЧНО знаешь, какие проблемы могут возникнуть

-----

Ошибаешься.

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

Какие проблемы могут возникнуть?


иначе ты не подготовил СВОЙ код и что же ты собираешься тестовать?

-----

А почему Я должен его подготовить? У меня новомодное ТДД - сначал надо написать все тесты, а потом подгоняем под них код...


Вот мок и возвращяет то, что ты ожидаешь.

-----

Так Я не знаю что ожидать.

И доки не помогают т.к. не описывают ситуацию с достаточной полнотой.

Получить хоть какое-то понимание того что будет получатся, когда будет получатся, когда не будет получатся можно только серьезно протестив то с чем надо работать. И то не все сразу отловишь...



имеет 100500 вариантов реакции

-----

Мне, в большинстве случаев, хватает двух - принято и отвергнуто.

А вот какое из них будет - фиг его знает - даже написав корректный код по заданию получается что что-то работает не так как надо...

AlexNek патриот23.04.21 12:38
AlexNek
NEW 23.04.21 12:38 
в ответ Murr 23.04.21 12:12
в доках написано - получешь текстовое сообщение из двух частей

Ну если хоть что то написано, то это меняет дело. Тут уже чистая комбинаторика

Текст/ не текст/ничего

Одна часть/2/больше


А то что документации недостаточно, это никак не меняет дело с одним набором данных.

Можно его тестировать и изучать сколько угодно, но нет никакой гарантии что другой набор даст где то такие же результаты.

Должны быть некие соглашения и определенные рамки изменения данных.


Murr патриот23.04.21 13:10
Murr
NEW 23.04.21 13:10 
в ответ AlexNek 23.04.21 12:38

это никак не меняет дело с одним набором данных.

-----

Хи-хи...

В той сети которую Я упомянул до набора данных еще надо дойти.

Причем иногда - в прямом смысле слова - ногами - физически притопать туда где носимое устройство сможет дотянутся до другого, возможно так же носимого - сплошного покрытия сетью там нет - и поиметь возможность что-то получить/отправить.


Тут уже чистая комбинаторика

-----

Угу... Я сначала тоже так подумал... оказалось - зря.

Среди упомянутых нет как минимум еще двух-трех опций...

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

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



Должны быть некие соглашения и определенные рамки изменения данных.

------

Хи-хи... Ты хочешь другой протокол поверх или в дополнение к имеющемуся.

Увы - для этого надо поменять устройство... а после смены оно подлежит повторной сертификации... а на это никто не пойдет.

AlexNek патриот23.04.21 13:27
AlexNek
NEW 23.04.21 13:27 
в ответ Murr 23.04.21 13:10
В той сети которую Я упомянул до набора данных еще надо дойти.

Доступность набора данных - это вообще совершенно другая проблема.


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

А зачем их тогда вообще получать, если о них знать?


но гробят обработку на раз

Ну так дело в обработчике. Если правильно написано, то вне зависимости от исходных данных ничего не должно упасть.


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

Нет, только лишь нормальное описание имеющегося.

koder патриот23.04.21 13:43
koder
NEW 23.04.21 13:43 
в ответ Murr 23.04.21 12:12
А почему Я должен его подготовить?

Потому что неважно с чего ты начинаешь, с тестов или с кода. Ты должен знать, что нужно сделать. Если не знаешь - то ничего делать не надо.


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

Ну получил ты стринг. Ок. Это просто строка. Твой следующий шаг? Что ты будешь со строкой делать?

Так Я не знаю что ожидать.

Тогда ничего не делай. Что ты собираешься программировать, если ты ВООБЩЕ ничего не знаешь? Если ты вообще не знаешь, что придет с черного ящика, ты физически не можешь с ним работать.


т.к. не описывают ситуацию с достаточной полнотой.

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


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

Мок - это имитация реального обьекта насколько ты его понимаешь. Слово "серьезно" это несерьезно. Например у тебя неполное понимание работы обьекта и ты слепил мок. Ок. мок несовершенен. Ты "серьезно" гонял настоящий обьект, что бы понять. Ты можешь гарантировать, что понимание теперь 100%? Если нет, то твой мок лучше предыдущего, но принципиально то же самое - то, что он будет копией реального обьекта ты гарантировать не можешь.


Но это и не надо. Еще раз. Ты не учишисья работать с реальным обьектом - "черным ящиком" используя мок. Ты тестируешь СВОЙ код на все известные тебе варианты поведения реального "черного ящика".

Мне, в большинстве случаев, хватает двух - принято и отвергнуто.

Это варианты поведения твоего кода. Вариантов поведения мока больше. Например твой пример для составной строки. Мок прислал пустую строку - отвергнуто-тест прошел. Мок не ответил в таймаут. Мок прислал сообщение о ошибке. Мок прислал строку, где длина в буквах. Мок прислал строку без разделителя. Везде твой код должен отреагировать правильно, пусть одним вариантом реакции, но на 100500 вариантов ответа мока.

Murr патриот23.04.21 18:46
Murr
NEW 23.04.21 18:46 
в ответ AlexNek 23.04.21 13:27

А зачем их тогда вообще получать, если о них знать?

------

Их в документации нет, но они иногда случаютя...

и докопаться до них можно только при очень дотошном исследовании...


Если правильно написано, то вне зависимости от исходных данных ничего не должно упасть.

-----

Да ну? Там сеть без квитирования и без гарантии доставки...


только лишь нормальное описание имеющегося

------

Нормальное - есть. Но оно не покрывает фактическую работу устройства.

Мало того - при тестировании единичного устройства многое просто не видно.

Murr патриот23.04.21 19:19
Murr
NEW 23.04.21 19:19 
в ответ koder 23.04.21 13:43

Если не знаешь - то ничего делать не надо.

-----

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


Твой следующий шаг?

-----

По документации - вырежу данные и буду с ними работать.

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

Выяснить что-то можно только поработав плотненько с сетью устройств.



Что ты будешь со строкой делать?

-----

Вот это Я у тебя хотел узнать. смущ



ты физически не можешь с ним работать

------

А код надо сдавать и он должен быть рабочим.



только на ту глубину, насколько ты знаешь "черный ящик"

------

Т.е. ровно на столько, сколько написано в документации.

Написанное по документации в практической среде работать не будет.



Ты можешь гарантировать, что понимание теперь 100%?

-----

Нет. Но Я могу поднять понимание с 20% соответствующих документации до 97% соответствующих реальной системе.

Оставшиеся 3% Я все одно не смогу получить от устройства/среды, но могу хоть как-то интерполировать полученные из опыта 77% и задавить еще 2.9%.

Это уже будет неплохой результат. Очень даже хороший по сравнению с исходным. И даже где-то приемлемый.

Где-то, но не везде.

По секрету скажу - уже где-то с 50-60% эффективное решение будет не на уровне кода, а на уровне инфраструктуры - об этом ты вообще пока не задумывался... и даже после прочтения документации эти идеи не появятся.



твой код должен отреагировать правильно

-----

Угу. Осталось выяснить сааамую простую вещь - правильно в соответствии с документацией т.е. в 20% случаев, или правильно в соответствии с реальной ситуацией т.е. 97%.

Для 97% ты пока еще не перечислил все варианты и наиболее проблемную часть пока еще даже не упоминал.

Программист коренной житель23.04.21 19:44
NEW 23.04.21 19:44 
в ответ koder 23.04.21 13:43
Ты можешь запрограммировать (речь идет о исполнении задания) только на ту глубину, насколько ты знаешь "черный ящик".

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

Меня удивляет, что об этом приходится говорить.


AlexNek патриот23.04.21 19:48
AlexNek
NEW 23.04.21 19:48 
в ответ Murr 23.04.21 18:46
Их в документации нет, но они иногда случаютcя

Тогда получается, что мы о них не знаем.


Там сеть без квитирования и без гарантии доставки

У меня складывается впечатление что мы обсуждаем разные вещи.

Ты - свою бывшую проблему.

Я - просто данные

Сеть - это уже способ доставки данных.

Ну и способ доставки данных никак не связан с самими данными.

Это будет интересно только при приеме конкретного пакета.


Было бы интересно "увидеть" пример правильно спроектированного класса для приема данных, который падает при неправильных данных смущ


Нормальное - есть. Но оно не покрывает фактическую работу устройства.

Тогда это неполное описание. Другими словами ненормальное.


при тестировании единичного устройства многое просто не видно

Ну именно это я имел в виду, говоря про единичный набор данных.

И работа устройства это совсем не то, что мы рассматриваем - прием каких либо данных.

Murr патриот23.04.21 20:15
Murr
NEW 23.04.21 20:15 
в ответ AlexNek 23.04.21 19:48

Тогда получается, что мы о них не знаем.

-----

Ну так Я об этом уже не первый день говорю.

Да, можно написать в соответствии с документацией. И оно даже будет работать.

Но только в каких-то идеальных условиях.

В реальной среде - работать не будет - получаемое отличается от описанного.


способ доставки данных никак не связан с самими данными.

-----

Способ - нет. А вот что будет получено - уже, увы, да...


неполное описание

-----

Для отдельного изолированного устройства - вполне достаточное. смущ

А так - да, не полное, не описывает многое из того что имеет место быть.



Сеть - это уже способ доставки данных

-----

В данном случае - весьма сильно отличающаяся от привычных tcp/ip сетей.



У меня складывается впечатление что мы обсуждаем разные вещи.

-----

Угу...

Я всего лишь говорю, что чтобы сделать работающий код надо знать с чем работаешь.

Ну а мне пытаются объяснить что достаточно сделать по документации.

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

Murr патриот23.04.21 20:35
Murr
NEW 23.04.21 20:35 
в ответ Программист 23.04.21 19:44

У "черного ящика" есть только вход и выход.

-----

Угу...

Вот только не вполне определено что именно понимается под "черным ящиком".

Документация, которая доступна, описывает функционирование отдельного устройства.

Соответственно код написанный по данной документации будет корректно работать с устройством.

Можно тестировать - все пройдет нормально.


Вот только де-факто "черным ящиком" является не устройство, а сеть.

Документации на сеть - нет. Все что есть - устройств может быть много, они могут быть разаными и взаимодействовать.

А поведение устройства в сети весьма отличается от того что описано в документации.

AlexNek патриот23.04.21 21:03
AlexNek
NEW 23.04.21 21:03 
в ответ Murr 23.04.21 20:15
В реальной среде - работать не будет - получаемое отличается от описанного.

Ну так это задача никак не совместима с юнит тестами. В лучшем случае это integration test. И то это чисто для проверки, что мы не сломали то, о чём знаем.

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

Но, в реальной среде не работает...иногда. Например, если в каталоге (target) уже есть такой файл, он не перезаписывается, а выдается исключение. Которое обрабатывается правильно.


Почти полная аналогия с твоими устройствами.


Я всего лишь говорю, что чтобы сделать работающий код надо знать с чем работаешь.

А что кто то пытается с этим спорить?

Программист коренной житель23.04.21 21:37
NEW 23.04.21 21:37 
в ответ Murr 23.04.21 20:35
Вот только не вполне определено что именно понимается под "черным ящиком".

Вполне себе определено:

Чёрный я́щик — термин, используемый для обозначения системы, внутреннее устройство и механизм работы которой очень сложны, неизвестны или неважны в рамках данной задачи.


Вот только де-факто "черным ящиком" является не устройство, а сеть.

Ты уж определись, что у тебя там является черным ящиком.


Документации на сеть - нет. Все что есть - устройств может быть много, они могут быть разаными и взаимодействовать.
А поведение устройства в сети весьма отличается от того что описано в документации.

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

Как видишь, в тестировании нет никаких случайных величин.

Есть правда тестеры, которые ищут ошибки... но в конечном счете из 3-х параметров им известен 1, а остальные 2 (выход и сценарий) они ищут "в слепую". Но рещультат их работы все равно 3 известных параметра - вход, вызод и сценарий. Ну и лично я считаю, что эта работа - бесполезная трата времени, т.к. стоит дорого, а выхлоп минимальный.

Murr патриот24.04.21 03:00
Murr
NEW 24.04.21 03:00 
в ответ AlexNek 23.04.21 21:03

задача никак не совместима с юнит тестами.

-----

Вполне совместима.

Только надо выяснить как именно мокать систему...


Например, если в каталоге

-----

Ну а об чем Я спрашивал когда увидел описание задачи?

В винде там еще и локи на файлах случаются. Причем - неожиданные...


Почти полная аналогия с твоими устройствами.

-----

Аналогия только в том, что глюки редкие. По ФС всегда можно что-то откопать, а по этой сети практически ничего не находится - редкие задачи...


А что кто то пытается с этим спорить?

-----

Ну убедить то меня пытаются в другом... безум

koder патриот24.04.21 05:41
koder
NEW 24.04.21 05:41 
в ответ Murr 23.04.21 19:19, Последний раз изменено 24.04.21 05:45 (koder)
Осталось выяснить как ничего не делая получить работающий код...

Ты не получишь работающий код. Потому что ты просто не знаешь что делать улыб

-Приезжайте в гости

-А адрес?

-Да не надо адрес, так приезжайте.


Но Я могу поднять понимание с 20% соответствующих документации до 97%
уже где-то с 50-60% эффективное решение

Но почему 97%? Ну откуда ты вообще берешь оценку? Откуда беруться цифры при оценке понимания черного ящика? Ты месяц гонял тесты (ру юниттесты, простое исследование). Те готорые смог придумать и организовать. Как ты оцениваешь полноту тестов?


правильно в соответствии с документацией т.е. в 20% случаев,

Нет. 100% правильно в соответствии с твоим пониманием, как твой код обрабатывает работу черного ящика. Соответственно мок 100% имитирует твое понимание работы черного ящика. Тестируя месяцы и годы можно улучшить понимание работы самого ящика, но принцип написания мока не меняется - в любой момент времени, сразу после прочтения документации или после 20 лет непрерывных тестов мок 100 процентов имитирует ответ черного ящика в строго определенной ситуации. Определенной тобой, как программистом.


AlexNek патриот24.04.21 13:05
AlexNek
NEW 24.04.21 13:05 
в ответ Murr 24.04.21 03:00
Только надо выяснить как именно мокать систему...

Что то я очень в этом сомневаюсь.

Как я понял, у тебя имелась некая система, данные которой зависят от состояния самой системы, а состояния могут меняться от многих факторов.

И тебе бы хотелось написать тесты позволяющие убедится в работоспособности всей системы.


Ну убедить то меня пытаются в другом...

Мне кажется что нет. Только то, что ты хочешь получить от тестов то, что они тебе дать не могут.

Murr патриот24.04.21 19:35
Murr
NEW 24.04.21 19:35 
в ответ Программист 23.04.21 21:37

есть заранее известный вход

-----

Никак не хочешь понять что нет заранее известного входа... полностью известного, по крайней мере.

А того что известно - недостаточно для написания того что нужно...


эта работа - бесполезная трата времени

-----

Но и ее тоже надо делать...


Murr патриот24.04.21 20:05
Murr
NEW 24.04.21 20:05 
в ответ koder 24.04.21 05:41

Как ты оцениваешь

-----

Если Я каким-то образом получу больше информации об функциомнировании устройства/системы чем есть в документации, то процентик - повысится. Или будет наоборот? смущ

Тебя смущают конкретные цифирьки - ну обоснуй их неправильность...спок



ответ черного ящика в строго определенной ситуации

-----

Проблема в том, что в конкретном случае у тебя скорее не черный, а серый ящик.

Т.е. у тебя на одно внешнее воздействие имеется более чем один ответ.

И при этом ни один из полученных ответов может не соответствовать описанному в документации. смущ

Понять - можно. Но не програмно. Нужно физически цеплять аппаратный порт к железу и смотреть что там происходит. - тогда станет более-менее понятно чего надо ожидать в качестве ответа устроства/системы...

koder патриот25.04.21 05:51
koder
NEW 25.04.21 05:51 
в ответ Murr 24.04.21 20:05, Последний раз изменено 25.04.21 05:52 (koder)
Если Я каким-то образом получу больше информации об функциомнировании устройства/системы чем есть в документации, то процентик - повысится.


Вопрос стоял о целесообразности мероприятия. Например берем устройство и изучаем. И доклад - повысили информированность о системе до 97% - это одно. Доклад - а процентик то повысился Или наоборот? - это другое. Особенно если изучали месяц и к концу изучения забыли, что изучали улыб


ебя смущают конкретные цифирьки - ну обоснуй их неправильность...спок

Основой для получения циферок является критерии оценки конечного результата. И в первую очередь критерии целесообразности мероприятия. Хочу все знать - это не критерий. Цифры могут быть там, где критерии оценки в цифрах. Я стал умнее информированиее на 30% - это лохотрон по определению. Просто нет критериев для оценки.

Т.е. у тебя на одно внешнее воздействие имеется более чем один ответ.И при этом ни один из полученных ответов может не соответствовать описанному в документации.

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


Murr патриот25.04.21 07:03
Murr
NEW 25.04.21 07:03 
в ответ koder 25.04.21 05:51

получилось то, что получилось

-----

И даже как-то работает... безум

Но писать под него, не зная что там будет - почти без толку... спок

Программист коренной житель25.04.21 19:27
NEW 25.04.21 19:27 
в ответ Murr 24.04.21 19:35
Но и ее тоже надо делать...

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

MrSanders коренной житель25.04.21 19:49
NEW 25.04.21 19:49 
в ответ Программист 25.04.21 19:27
можно убить их время эмитируя полезную нагрузку :)

Гы-гы :) Заклёпочник он. Сначала надо эмиттер полезной нагрузки построить.

Ну или просто её имитировать :)

Murr патриот25.04.21 20:51
Murr
NEW 25.04.21 20:51 
в ответ Программист 25.04.21 19:27

можно описать как

-----

Так можно описать любую деятельность, в которой спрашивающий непосредственно не заинтересован.

При отсутствии интереса к чему-либо кроме тупого сидения перед зомбоящиком - интересов вообще не будет...

Программист коренной житель25.04.21 21:18
NEW 25.04.21 21:18 
в ответ Murr 25.04.21 20:51

Деятельность "пойди туда, не знаю куда. принеси то, не знаю что" является бесполезной. И это никак не зависит от заинтересованности.

Murr патриот25.04.21 22:26
Murr
NEW 25.04.21 22:26 
в ответ Программист 25.04.21 21:18

пойди туда, не знаю куда. принеси то, не знаю что

-----

Странно слышать это от инженера. Для техника - да, сойдет...

Программист коренной житель26.04.21 07:57
NEW 26.04.21 07:57 
в ответ Murr 25.04.21 22:26
Странно слышать это от инженера. Для техника - да, сойдет...

Согласен! Странно, когда инженер считает полезным тратить время в пустую.

1 2 3 4 5 6 7 8 9 все