@oop_ru

Страница 323 из 785
Sergey
19.08.2017
08:48:34
https://gist.github.com/fesor/db60b4995880925b720be9c7cf75543f

перевел статью для внутренних нужд, это к вопросу о Integration tests are a scum

Jan
19.08.2017
09:04:06
@fes0r на Хабр не публиковал?

f4rt~
19.08.2017
09:14:06
?

Google
Sergey
19.08.2017
09:21:21
Андрей
19.08.2017
09:39:16
а помойму, смотря как к этому подходить 1. Если это фреймворк/либа, используешаяся во многих проектах (опенсоурс фрэймворк как яркий пример) - юнит тесты в целом- себя оправдывают. когда не жалко затратить время на покрытие тестами, в надежде что это снизить кол-во багов в последующих доработках/релизах. не 100% гарантия - но хоть чтото 2. Если это код конкретного проекта, то тут юнит тесты менее значимы, на мой взгляд. Юнит тесты удобны - когда тест пишеш не ради покрытия, а просто чтоб убедиться/проверить что все ок на момент реализации. причем пишеш его так, чтоб нежалко было удалить/отключить: если вдруг логика меняется - а на доработку самого теста времени нет. и что касается конкретного проекта - по мне - функциональные/интеграционные тесты там более значимы - когда небольшой тест покрывает сразу много функционала

хотя к статье это наверно мало относится :) к самое статье вроде претензий нет - со всем в целом там согласен +-

Sergey
19.08.2017
09:41:23
а помойму, смотря как к этому подходить 1. Если это фреймворк/либа, используешаяся во многих проектах (опенсоурс фрэймворк как яркий пример) - юнит тесты в целом- себя оправдывают. когда не жалко затратить время на покрытие тестами, в надежде что это снизить кол-во багов в последующих доработках/релизах. не 100% гарантия - но хоть чтото 2. Если это код конкретного проекта, то тут юнит тесты менее значимы, на мой взгляд. Юнит тесты удобны - когда тест пишеш не ради покрытия, а просто чтоб убедиться/проверить что все ок на момент реализации. причем пишеш его так, чтоб нежалко было удалить/отключить: если вдруг логика меняется - а на доработку самого теста времени нет. и что касается конкретного проекта - по мне - функциональные/интеграционные тесты там более значимы - когда небольшой тест покрывает сразу много функционала
там вывод статьи - нельзя говорить в общем имеют смысл юнит тесты или нет.

нужно под конкретный кейс смотреть. И да, я работаю в аутсорсе и считаю что даже на проект под 2-3 месяца юнит тесты нужны

Андрей
19.08.2017
09:42:23
да. и я согласен - с этим :) все - по ситуации

Sergey
19.08.2017
09:42:26
если разработчик умеет писать тесты и умеет писать тестируемый код, учитывает моменты которые описаны в статье, то это выходит дешевле, надежнее и предсказуемее с точки зрения внесения правок

что до Blackbox testing с интеграционными тестами - я честно последние наверное месяца 3 размышляю на эту тему и в целом я все меньше вижу в этом смысла

приемочные тесты - да, они нужны. Интеграционные - нет

только в очень редких случаях.

а юниты.... с ними только одна проблема - код который мы пишем

http://blog.thecodewhisperer.com/permalink/beyond-mock-objects

вот очень хорошая статья на эту тему которая демонстрирует пример. что как бы вот у нас тест 3-его уровня и вот бац и уже нет

Google
Sergey
19.08.2017
09:44:47
и совсем незначительные изменения потребовались.

именно по этому тесты это хорошо - неудобно тесты писать - больше шанс что что-то с кодом не так

Андрей
19.08.2017
09:51:12
Интеграционные тесты - тоже кстати думаю... пока ничего толкового не придумал :( сложность самих тестов пока получается высокой - высокий шанс что не взлетит - забьют поддерживать

finkel
19.08.2017
10:11:15
?
"Я имею ввиду, что когда мы проверяем как наш класс взаимодействует с другим классом, мы переходим к проверке деталей имплементации этого класса." во, я про это же спрашивал, когда юнит тесты первый раз увидел)

f4rt~
19.08.2017
10:11:54
я люблю простые юниты :D самодостаточные, без зависимостей

finkel
19.08.2017
10:12:28
не завязанные на реализацию

Sergei
19.08.2017
10:13:35
Статья интересная, я считаю что идеальный юнит тест это одна строка, аssertThat(что то там) а самое сложное это вогнать тестируемый класс в нужное состояние и получается куча строк до самого ассерта, у меня был простой класс у которого было три или четыре стейта и сложность была как раз в этом, а когда становится сложно тестировать то понимаешь что что то не так.

f4rt~
19.08.2017
10:14:11
проблема в том, что на примере калькулятора писать тест легко

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

для меня юнит, иной раз, что то недостижимое(

finkel
19.08.2017
10:16:22
ну по идеи, можно же не проверять, что такой-то сервис будет вызван. Просто делаешь моки, чтоб ничего не сломалось. Реализация поменяется, ничего не сломается. Но правда моки останутся ненужные

f4rt~
19.08.2017
10:21:03
я все хотел посмотреть как у @fes0r на работе пишут юнит тесты для апишек

finkel
19.08.2017
10:21:48
f4rt~
19.08.2017
10:21:58
вот я про то же

finkel
19.08.2017
10:22:08
звучит как "функциональный тест")

Sergei
19.08.2017
10:22:17
проблема в том, что на примере калькулятора писать тест легко
Не особо, автор статьи привёл хреновые примеры

f4rt~
19.08.2017
10:22:44
вот меня больше интересует rest/hateoas и как на это писать юнит

Sergei
19.08.2017
10:23:54
как здесь в сообщениях форматировать код кто подскажет? теги?

f4rt~
19.08.2017
10:24:06
`

3 штуки

Google
finkel
19.08.2017
10:24:21
вот меня больше интересует rest/hateoas и как на это писать юнит
я опять что-то не понимаю, причем тут юнит тесты?)

Sergei
19.08.2017
10:25:48
Что касается примеров в статье я думаю они не очень, нужно везде использовать интерфейсы. и я бы убрал у калькулятора метод гетХистори потому что это не ответственность калькулятора, что касается этого куска примера, нарушается srp принципл, (для тестов это тоже нужно) Здесь тот кто пишет тест не доверяет классу StorageService потому что он должен быть интерфейсом, а не классом. Мы должны доверять интерфейсу, его контракту, а здесь тестируется ещё и реализация StorageService(херовое название) в тестах в которых мы тестируем калькулятор... [Test] public void When3AddsThenGetHistory_ShouldReturnOnlyThose3Results() { // Arrange IStorageService storageServiceMock = Mocker.Mock <IStorageService>(); storageServiceMock.Stub(service => service.IsServiceOnline()) .Return(true); storageServiceMock.Stub(service => service.GetHistorySession(1)) .Return(new List <int>{4, 7, 9}); var calculator = new Calculator(storageServiceMock); calculator.Add(1, 3); calculator.Add(2, 5); calculator.Add(3, 6); // Act var result = calculator.GetHistory(); // Assert storageServiceMock.AssertWasCalled(service => service.GetHistorySession(1); Assert.Equal(4, result[0]); Assert.Equal(7, resut[1]); Assert.Equal(9, result[2]); Assert.Equal(3, result.Count); }

f4rt~
19.08.2017
10:26:05
я опять что-то не понимаю, причем тут юнит тесты?)
последние слайды Фесора, чо я смотрел

integration testing sucks

Sergei
19.08.2017
10:36:16
Что касается примеров в статье я думаю они не очень, нужно везде использовать интерфейсы. и я бы убрал у калькулятора метод гетХистори потому что это не ответственность калькулятора, что касается этого куска примера, нарушается srp принципл, (для тестов это тоже нужно) Здесь тот кто пишет тест не доверяет классу StorageService потому что он должен быть интерфейсом, а не классом. Мы должны доверять интерфейсу, его контракту, а здесь тестируется ещё и реализация StorageService(херовое название) в тестах в которых мы тестируем калькулятор... [Test] public void When3AddsThenGetHistory_ShouldReturnOnlyThose3Results() { // Arrange IStorageService storageServiceMock = Mocker.Mock <IStorageService>(); storageServiceMock.Stub(service => service.IsServiceOnline()) .Return(true); storageServiceMock.Stub(service => service.GetHistorySession(1)) .Return(new List <int>{4, 7, 9}); var calculator = new Calculator(storageServiceMock); calculator.Add(1, 3); calculator.Add(2, 5); calculator.Add(3, 6); // Act var result = calculator.GetHistory(); // Assert storageServiceMock.AssertWasCalled(service => service.GetHistorySession(1); Assert.Equal(4, result[0]); Assert.Equal(7, resut[1]); Assert.Equal(9, result[2]); Assert.Equal(3, result.Count); }
Я заменяю этот хреновый тест который тестирует сразу всё и нарушает SRP принципл на тот который тестирует одну вешь за один раз. @Test @Test public void shouldReturnHistoryWhenGetHistoryInvoked() { int[] expectedHistory = new int[]{1}; ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); when(mockService.getHistory()).thenReturn(expectedHistory); assertThat(calculator.getHistory(), is(expectedHistory)); Тот тест который я рефакторил тестировал и работу калькулятора, (правильно ли он считает) и работу сервиса, правильно ли он хранит, и то что он возвращает правильный результат. Но на самом деле намерением того теста было тестирование интеракции и теперь тот теста стал таким каким он и должен быть. PS вот пастебин, с тем же кодом, т.к. форматирование плохо работает https://pastebin.com/8hmKqz4M

Я заменяю этот хреновый тест который тестирует сразу всё и нарушает SRP принципл на тот который тестирует одну вешь за один раз. @Test @Test public void shouldReturnHistoryWhenGetHistoryInvoked() { int[] expectedHistory = new int[]{1}; ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); when(mockService.getHistory()).thenReturn(expectedHistory); assertThat(calculator.getHistory(), is(expectedHistory)); Тот тест который я рефакторил тестировал и работу калькулятора, (правильно ли он считает) и работу сервиса, правильно ли он хранит, и то что он возвращает правильный результат. Но на самом деле намерением того теста было тестирование интеракции и теперь тот теста стал таким каким он и должен быть. PS вот пастебин, с тем же кодом, т.к. форматирование плохо работает https://pastebin.com/8hmKqz4M
Здесь я полностью доверяю Service и его контракту так же как и базовым классам стринг, аррайЛист и так далее, почему? Потому что тесты которые полностью покрывают находятся в другом месте, не в классе CalculatorTest а в классе ServiceTest.

Я заменяю этот хреновый тест который тестирует сразу всё и нарушает SRP принципл на тот который тестирует одну вешь за один раз. @Test @Test public void shouldReturnHistoryWhenGetHistoryInvoked() { int[] expectedHistory = new int[]{1}; ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); when(mockService.getHistory()).thenReturn(expectedHistory); assertThat(calculator.getHistory(), is(expectedHistory)); Тот тест который я рефакторил тестировал и работу калькулятора, (правильно ли он считает) и работу сервиса, правильно ли он хранит, и то что он возвращает правильный результат. Но на самом деле намерением того теста было тестирование интеракции и теперь тот теста стал таким каким он и должен быть. PS вот пастебин, с тем же кодом, т.к. форматирование плохо работает https://pastebin.com/8hmKqz4M
здесь можно было бы ещё упростить тест, выбросив проверяемое значение возвращаемого массива, но его легче обмануть, дёрнуть метод сервиса, а возвращать постоянно один и тот же массив. Но зато тест упроститься и станет ещё короче. @Test public void shouldReturnHistoryWhenGetHistoryInvoked() { ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); calculator.getHistory(); verify(mockService.getHistory()).times(1); }

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

Потом ещё нужно написать метод т.е. тест который будет гарантировать то что результат вычеслений калькулятора попадёт в историю
@Test public void shouldAddAdditonResultToHistory() { ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); calculator.add(2,3); verify(mockService).addHistory(5))); } И всё, каждый метод тестирует только одну вещь

@Test public void shouldAddAdditonResultToHistory() { ServiceHistory mockService = mock(ServiceHistory.class); Calculator calculator = new CalculatorImpl(mockService); calculator.add(2,3); verify(mockService).addHistory(5))); } И всё, каждый метод тестирует только одну вещь
Как там в ооп, классы это сущности, которые умеют делать определённые вещи, каждая сущность делает одну вещь и делает это хорошо, Сущности обмениваются сообщениями. В тестах мы и проверяем какими они сообщениями обмениваются, а не копируем реализацию.

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

Sergey
19.08.2017
12:50:14
"Я имею ввиду, что когда мы проверяем как наш класс взаимодействует с другим классом, мы переходим к проверке деталей имплементации этого класса." во, я про это же спрашивал, когда юнит тесты первый раз увидел)
ну для юнит тестов знать детали реализации это нормально, как никак эти тесты болльше расчитаны на проектирование. Другое дело что знать они должны по минимуму и юнит тесты подстегивать тебя должны к тому что бы разделять поведение верно по объектам

вот меня больше интересует rest/hateoas и как на это писать юнит
у тубя есть "объект" формирующий json-ку. И у тебя есть объект дающий данные для json-ки. Вуаля. Проверяем схему.

f4rt~
19.08.2017
12:51:34
хм

Sergey
19.08.2017
12:51:42
я все хотел посмотреть как у @fes0r на работе пишут юнит тесты для апишек
пока у нас обычные интеграционные тесты и то если есть и это рак

f4rt~
19.08.2017
12:51:51
ну вот да(

Sergey
19.08.2017
12:51:52
но вот хочу сместить все в сторону именно юнит тестов

ибо как бы там не говорили о "тестах черного ящика" готовить стэкт для интеграционных тестов та еще радость

стэйт*

Google
Sergey
19.08.2017
12:53:36
http request -> http response

проще всего будет в терминах бихата - на каждый сценарий свои фикстуры выставляются

Aleh
19.08.2017
12:54:16
а тем кто юзает cucumber/behat вопрос: на каком уровне абстракции они лезут в ваше приложение?

Sergey
19.08.2017
12:54:31
ну и есть парочка проектов где QA писали интеграционные тесты (сам понимаешь что там))

https://www.youtube.com/watch?v=FyCYva9DhsI

Kirito
19.08.2017
20:56:36
Посоветуйте статьи или книгу или сайт чтобы понять ООП

Sergei
19.08.2017
20:59:21
Гради Буч, "Объектно-ориентированный анализ и проектирование"

Kirito
19.08.2017
21:05:48
Спс

Sergey
20.08.2017
09:31:19
Спс
придумай потом как проверить что ты реально понимаешь ооп а не просто классы юзаешь)

Sergey
20.08.2017
12:43:21
это называется "собеседование"

формализовать это в виде "теста" нельзя

Aliaksandr
20.08.2017
12:45:27
формализовать это в виде "теста" нельзя
Если собеседовать можно, значит и формализовать можно.

Sergey
20.08.2017
12:47:34
я просто сверяю свое представление с чужим представлением. Я не могу это в виде "теста" задать.

это субъективная оценка весьма

Saen
21.08.2017
08:02:56
я вот недавно был на собеседовании где с меня хотели от руки код ;)

я даже немного поулыбался)

Sergey
21.08.2017
08:03:14
редко но бывает

Google
Saen
21.08.2017
08:03:29
не, на джуниора да, а так уже не особо интересно

Sergey
21.08.2017
08:04:05
не, на джуниора да, а так уже не особо интересно
проблема рынка. Приходит к тебе на собес мега синьер там и все такое и не может даже простую задачку решить. При том что "компилирующийся и рабочий код" от него не требуется - только идея

а что они творят с ООП - это отдельная история

Saen
21.08.2017
08:04:50
так я сказал что усно готов рассказать, но эта идея не особо понравилась собеседующему)

f4rt~
21.08.2017
08:05:43
я помню один раз и меня попросили, а я когда на white board пишу вообще туплю дико, предложил заменить реальный код на uml что бы дать понять мысль, мне отказали)

Sergey
21.08.2017
08:05:44
так я сказал что усно готов рассказать, но эта идея не особо понравилась собеседующему)
зависит от задачи. Мне нужно видеть как человек мыслит и как он примерно пишет код. При этом я не хочу на это тратить больше 5-ти минут собеседоваемого или давать тестовые задания

Saen
21.08.2017
08:06:21
вероятно значит тебе и работник не особо нужен

зачем тратить свое и его время

Sergey
21.08.2017
08:06:43
зачем тратить свое и его время
действительно, зачем вообще собеседовать

Страница 323 из 785