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

Unit Test. Кто использует?

1707  1 2 3 4 5 6 все
Программист коренной житель10.11.16 11:38
NEW 10.11.16 11:38 
в ответ moose 10.11.16 10:28

Это все вопросы относительно предмета тестирования.

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


Но Вы говорите - не надо тестировать, там ничего не может пойти криво.

Я говорю, что WPF тестировать не надо :) Не знависимо от того, используется ли DynamicResource или StaticResource или button.Enabled = false - WPF в любом случае работает без ошибок.

#81 
Пирт гость10.11.16 18:26
NEW 10.11.16 18:26 
в ответ Программист 10.11.16 11:38

Может, уже не в тему мои 5 копеек, но сегодня вот пришло в голову: Agile нужен для того, чтобы продукт-оунеры/менеджеры ничерта не делали. В смысле, совсем ничерта, на каждый конкретный запрос "нам нужен детально проработанный сценарий/юзкейс/бэклог" отвечая "вот вам в общих чертах, остальное по ходу дела, ибо Agile. У вас же архитектура масштабируется? Тестами все покрыто? Вот и работайте, и не парьте меня своим планированием".

#82 
  moose местный житель10.11.16 23:14
NEW 10.11.16 23:14 
в ответ Программист 10.11.16 11:38

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

#83 
MrSanders старожил11.11.16 09:26
NEW 11.11.16 09:26 
в ответ Пирт 10.11.16 18:26
Agile нужен для того, чтобы продукт-оунеры/менеджеры ничерта не делали.

Не-а, делать им как раз постоянно что-то надо. Метаться между командой и "акционерами" (stakeholder)

вот вам в общих чертах, остальное по ходу дела, ибо Agile

В скраме не выйдет. В общих чертах добавить историю в бэклог - пожалста. Но пока не будет выполнено Definition of Ready (DoR) история а спринт не перенимается. На ревью проработали детально, тогда и программировать можно.


Неприятным сюрпризом для новообращенных скрамистов как раз таки становится количество времени, которое тратится на всевозможные планирования и согласования, тут тебе и пара ревью за спринт и ретроспектива и планирование спринта. А по идеологии во всем этом должна участвовать вся команда. Плюс скрам-мастер. У нас >25% (скорее 30%) рабочего времени скрам-команд уходят на всяческие совещания.


Планирование на ранней стадии - да, такого нет. Но определить "критерии качества" и "ограничивающие условия" (quality criteria, non-functional requirements) можно (и нужно для нового продукта) в т.н. "нулевом спринте". Архитектор(ы), product owner и stakeholder-ы должны определиться с "дорогими" (для изменения) вопросами.


Имхо, главная проблема agile вообще и scrum-а в часности это отсутствие понимания процесса у клиента.

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

#84 
Murr патриот14.11.16 11:53
Murr
NEW 14.11.16 11:53 
в ответ Программист 10.11.16 08:52

Собирался в тяпницу, но свалилась работа...


Зато будет неделька поискать решение...


Код - в аттачменте.

Методы, которые не получалось переработать следующие:

- loadDtStock_allBcds_loadInoiveNo_byOrder()

- loadDtStock_allBcds_loadInoiveNo_byLoad()

- loadRackNos()

может что и упустил.


Если интересует DXCR48 - могу запостить. Но там нет ничего интересного - строится СЯЛ-строка и результат возвращается как ДатаТабле.

#85 
Программист коренной житель14.11.16 15:29
14.11.16 15:29 
в ответ Murr 14.11.16 11:53
loadDtStock_allBcds_loadInoiveNo_byOrder()

Тут проблема только одна - DXCR48.loadDtInvoiceNo_byItem (...)

Я не знаю что это за функция, но ее надо закрыть заглушкой и тестировать так, как будто эта функция работает без ошибок.


Насколько я понимаю, DrOrder и DtInvoiceNo - это просто объект с данными, который тебе придется заполнять руками. Не могу сказать, понадобится ли тебе тут свой функционал.


loadDtStock_allBcds_loadInoiveNo_byLoad()

тут все также, как и в предыдущем случае - понадобится заглушка на DXCR48.loadDtInvoiceNo_byLoad(...) и DXCR48.loadDtInvoiceNo_byItem (...).

Единственное, что меня тут смущает - это DtInvoices.Compute(...) . Наверное придется таки делать обертку над DataTable.


loadRackNos()

тут самое интересное :)

DataTable таки придется подменить своей реализацией.

И при вызове DtStockOrderItems.Select() возвращать свои данные.



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

Это, конечно, не будет уже юнит-тестом, но возможно это будем разумным компромиссом. Это уже только ты можешь оценить.


Ну а DXCR48.loadDtInvoiceNo_byLoad(...) и DXCR48.loadDtInvoiceNo_byItem (...) надо будет тестировать отдельно. Я так понимаю, что это статические функции? Или DXCR48 - это синглтон?




#86 
Murr патриот14.11.16 16:25
Murr
NEW 14.11.16 16:25 
в ответ Программист 14.11.16 15:29

Тут проблема только одна

-----

Первая проблема в этом коде - то, что он не объектный. смущ


Насколько я понимаю, DrOrder и DtInvoiceNo - это просто объект с данными

-----

Угу... Причем оба - типа ДатаРов... и вполне взаимозаменяемые... Мало того что взаимозаменяемые, так еще и оба используются как источник параметров... От этого вокруг накручена логика, которая размазана и непонятна...



понадобится заглушка на

-----

Я чуток сошлюсь вперед - "Это, конечно, не будет уже юнит-тестом..." - Ну а раз ЭТО все одно не юнит-тест, то может и не надо заглушек? смущ

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

В общем делаю так - данные берутся из пром.базы и по ним считается "что там надо". Заодно отлаживается и конвертация СЯЛ - там изменения редки, элементарны, ошибки обнаруживаются почти сразу текущими тестами, отдельных тестов нет.



DataTable таки придется подменить своей реализацией

-----

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



меня тут смущает - это DtInvoices.Compute(...)

-----

Это - самое простое - оно выносится в класс таблицы/субсета и там легко и просто заменяется на пересчет ЛИНКом... до тех пор пока не передается фильтр... с фильтром - труба... пока.



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

-----

Аккурат над этим сегодня сижу...

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


В переработанном виде те три метода, об которых шла речь сейчас выглядят так (см. аттач.). На них хоть что-то понятно...

#87 
Murr патриот14.11.16 16:31
Murr
NEW 14.11.16 16:31 
в ответ Murr 14.11.16 16:25

В общем - мне больше нужна правильная реализация Селекта для ДатаРов-аррай, чем полный враппер ДатаТабле.

-----

Если кто знает где лежит оригинальный Селект - киньте ссылкой. Мне нужно чтобы исходный материал был ДатаРов-аррай, результат - ДатаРов-аррай, параметры - строковые.


Как вариант - автоконвертер из параметров в линк.

#88 
Murr патриот14.11.16 18:50
Murr
NEW 14.11.16 18:50 
в ответ Murr 14.11.16 16:31

Дописался...


------ Discover test started ------

========== Discover test finished: 83 found (0:00:00.4650465) ==========

No tests found to run.


смущ

#89 
Simple Nothing is f*cked18.11.16 13:17
Simple
NEW 18.11.16 13:17 
в ответ Программист 14.11.16 15:29

Читаю Ошерова (треть прочел). Пока что многовато того, что я уже знал (из книги Физерса, которую Ошеров тоже часто упоминает), но некоторые советы типа "только один мок на тест" уже наталкивают на правильные мысли. От .нет удается пока что успешно абстрагироваться :)

#90 
MrSanders старожил18.11.16 15:01
NEW 18.11.16 15:01 
в ответ Simple 18.11.16 13:17

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

#91 
Simple Nothing is f*cked18.11.16 15:12
Simple
NEW 18.11.16 15:12 
в ответ MrSanders 18.11.16 15:01

Вопрос в определении, что такое мок. Есть моки, стабы и фейки.

#92 
MrSanders старожил18.11.16 18:15
NEW 18.11.16 18:15 
в ответ Simple 18.11.16 15:12

Нда-с, посмотрел я что Ошеров называет моками.

The main thing to remember about mocks versus stubs is that mocks are just like stubs, but you assert against the mock object, whereas you do not assert against a stub.

Загнался он. Для меня моки по Фаулеру - "объект с запрограммированными ожиданиями".

#93 
  moose местный житель19.11.16 00:16
NEW 19.11.16 00:16 
в ответ Simple 18.11.16 13:17

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

#94 
Simple Nothing is f*cked20.11.16 16:03
Simple
NEW 20.11.16 16:03 
в ответ MrSanders 18.11.16 18:15

А мне нравится его классификация. Уже прикидываю, как я буду это прилеплять к своему легаси-проекту. Как раз написал для него gradle build, теперь можно и тесты делать потихоньку.

#95 
Simple Nothing is f*cked20.11.16 16:04
Simple
NEW 20.11.16 16:04 
в ответ moose 19.11.16 00:16

Ессно, для меня это имеет сугубо практическое значение.

#96 
MrSanders старожил20.11.16 22:14
NEW 20.11.16 22:14 
в ответ Simple 20.11.16 16:03
А мне нравится его классификация.

Слишком далеки они от народа (с). По крайней мере в яве. Все три основных фреймворка для создания "test doubles" (EasyMock, jMockit, Mockito) понимают под моками "объекты с поведением / ожиданиями". И все они позволяют "легким движением руки" собирать данные с помощью моков, чтобы их проверять. (т.е. одной строчкой превратить объект из стаба в мок).

#97 
Simple Nothing is f*cked21.11.16 13:24
Simple
NEW 21.11.16 13:24 
в ответ MrSanders 20.11.16 22:14

Вот, кстати, Фаулер: http://martinfowler.com/articles/mocksArentStubs.html

по-моему, вполне похоже на ошеровские выкладки. Все пока не читал, сохранил в инсту :)

#98 
MrSanders старожил21.11.16 14:11
NEW 21.11.16 14:11 
в ответ Simple 21.11.16 13:24

Чем же оно похоже-то? У Фаулера:

  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Т.е. стабы это "заглушки". Программируем то что надо, что не надо оставляем пустым, где надо что-то собрать - храним. Моки - "имитаторы", декларируем поведение для вызовов - тут верни 1, тут брось эксепшен.

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

#99 
Simple Nothing is f*cked21.11.16 14:23
Simple
NEW 21.11.16 14:23 
в ответ MrSanders 21.11.16 14:11

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

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

1 2 3 4 5 6 все