Skip to content

Шубин Игорь#51

Open
Nevisinn wants to merge 4 commits intokontur-courses:masterfrom
Nevisinn:master
Open

Шубин Игорь#51
Nevisinn wants to merge 4 commits intokontur-courses:masterfrom
Nevisinn:master

Conversation

@Nevisinn
Copy link

Copy link

@Yrwlcm Yrwlcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

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

//Fluent Assertions
actualTsar.Should()
.BeEquivalentTo(expectedTsar, options => options
.Excluding((IMemberInfo memberInfo) => memberInfo.Name == "Id"));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Круто, что нашел правильное решение! Его можно еще чуть чуть доработать, если воспользуемся шарповым оператором, который умеет названия переменных доставать) Тогда этот тест сам будет актуализироваться ренеймингом через IDE

Comment on lines +31 to +45

// Какие недостатки у такого подхода?
/*
Недостатки:
1. При падении теста нет возможности отследить причину, так как вывод теста это True либо False
2. Нет обработки рекурсии, приложение может упасть с ошибкой переполнения стека при циклических ссылках Parent.
3. При измении Person (удаление/добавление свойств), придется модифицировать метод

Мое решение лучше тем, что:
1. В случае не прохождения теста, выводит все причины
2. Отсутствие дублирования кода
3. Обработка рекурсии под капотом: рекурсия выполняется до 10 уровней, далее тест падает с ошибкой, что есть
циклическая зависимость
4. Person расширяем: нет необходимости в модификации метода
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все верно, вопросов нет

Comment on lines 9 to 17
[TestCase(1, 0, true, TestName = "OnlyPositiveIsTrue")]
[TestCase(1, 0, false, TestName = "OnlyPositiveIsFalse")]
[TestCase(int.MaxValue, 0, false, TestName = "PrecisionMaxValue")]
public void Constructor_WhenValidArguments_ReturnVoid(int precision, int scale, bool onlyPositive)
{
var func = () => new NumberValidator(precision, scale, onlyPositive);

func.Should().NotThrow();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эти тесты кажется не очень информативные. Сценарии которые они покрывают, уже тестируются например в тесте IsValidNumber_WithValidArguments_ReturnsTrue. Предлагаю их удалить

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В тесте IsValidNumber_WithValidArguments_ReturnsTrue у меня упор идет на Value, предполагается, что остальные аргументы верные. В этом же тесте я проверяю precision, scale, onlyPositive, что при верных аргументах все будет работать, как задумано. Например, если их уберем, потом спустя время как-то поменяется код и упадет тест в IsValidNumber_WithValidArguments_ReturnsTrue, но не по вине Value, а в TestName будет что-то про Value, что тогда? Достаточно будет просто дебагом пройтись и следовательно подобные тесты в Constructor_WhenValidArguments_ReturnVoid это излишне?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В этом же тесте я проверяю precision, scale, onlyPositive, что при верных аргументах все будет работать, как задумано

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

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

Я бы предложил на это посмотреть так: могут ли у нас быть сценарии, при которых эти тесты упадут, а все остальные, которые мы уже написали, будут зелеными?

  • И если да - то лучше найти пример и как раз его покрыть тестом.
  • А если нет, то тогда эти тесты дублируют какой-то сценарий и их можно не запускать. Вроде мелочь, но лучше когда у тебя упало условно 10 тестов, а не 13 :)

И как раз по такой же логике можно понять, почему Constructor_WithInvalidArguments_ThrowsArgumentException должны остаться. Если мы неправильно инициализируем NumberValidator он должен упасть, но во всех других тестах, мы его инициализируем правильно и это не проверяем

но не по вине Value, а в TestName будет что-то про Value, что тогда

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

System.ArgumentException : ...
   at HomeExercise.Tasks.NumberValidator.NumberValidator..ctor(Int32 precision, Int32 scale, Boolean onlyPositive) in ...\2. NumberValidator\NumberValidator.cs:line 18

Достаточно будет просто дебагом пройтись

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

Comment on lines 19 to 23
[TestCase(-1, 2, false, TestName = "PrecisionIsNegative")]
[TestCase(1, 2, false, TestName = "ScaleGreaterThanPrecision")]
[TestCase(1, 1, false, TestName = "ScaleEqualsPrecision")]
[TestCase(1, -1, false, TestName = "NegativeScale")]
public void Constructor_WithInvalidArguments_ThrowsArgumentException(int precision, int scale, bool onlyPositive)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Предлагаю тут еще докинуть тест на precision 0, тоже краевой сценарий

[TestCase(1, -1, false, TestName = "NegativeScale")]
public void Constructor_WithInvalidArguments_ThrowsArgumentException(int precision, int scale, bool onlyPositive)
{
var func = () => new NumberValidator(precision, scale, onlyPositive);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Совсем придираюсь, но думаю нужно переменную более информативно назвать, func слишком общее понятие :)

Comment on lines 33 to 35
[TestCase(3, 2, true, "+1.23", ExpectedResult = false, TestName = "PositiveValue")]
[TestCase(4, 2, true, "-1.23", ExpectedResult = false, TestName = "NegativeValue")]
[TestCase(6, 3, true, "-1 .2 3", ExpectedResult = false, TestName = "NumberWithEmptySpace")]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тесты перенес, но что за клевая штука?) Тоже нужна подсказка

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если мы разделили тесты на те которые ожидают только true и те которые ожидают только false, мы можем явно не прописывать ExpectedResult = true в каждом тесте, а написать это один раз в теле теста)

[TestCase(30, 2, true, null, ExpectedResult = false, TestName = "NullValue")]
[TestCase(30, 2, true, "Hello world!", ExpectedResult = false, TestName = "Text")]
[TestCase(30, 2, true, "0+0", ExpectedResult = false, TestName = "InvalidSignPosition")]
[TestCase(4, 2, true, "+-0.0", ExpectedResult = false, TestName = "DuplicateSigns")]
Copy link

@Yrwlcm Yrwlcm Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link

@Yrwlcm Yrwlcm Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Еще раз глянул реализацию NumberValidator-а, скорее моя формулировка не совсем правильная, сори. Моя идея была в том, что у нас в этом тесте и таком же ниже, подается на вход 5 символов, а precision 4 символа.

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

[TestCase(30, 2, true, "a.sd", ExpectedResult = false, TestName = "Letters")]
[TestCase(30, 2, true, "1.sd", ExpectedResult = false, TestName = "MixedNumericAndLetters")]
[TestCase(30, 2, true, "1.\n", ExpectedResult = false, TestName = "MixedNumericAndControlCharacter")]
[TestCase(4, 2, true, "+\n.10", ExpectedResult = false, TestName = "MixedNumericAndPositiveLeadingControlCharacter")]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тот же самый вопрос

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот тут ответил

[TestCase(6, 3, true, "-1 .2 3", ExpectedResult = false, TestName = "NumberWithEmptySpace")]
[TestCase(30, 2, true, "922337203685477580711.0", ExpectedResult = true, TestName = "VeryLargeWholePartNumber")]
[TestCase(31, 30, true, "0.922337203685477580711", ExpectedResult = true, TestName = "VeryLargeFractionalPartNumber")]
public bool IsValidNumber_WithValidArguments_ReturnsTrue(int precision, int scale, bool onlyPositive, string value)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

[TestCase(30, 2, true, "+++", ExpectedResult = false, TestName = "MultipleSigns")]
[TestCase(30, 2, true, " ", ExpectedResult = false, TestName = "WhitespaceOnly")]
[TestCase(30, 2, true, ".12", ExpectedResult = false, TestName = "MissingIntegerPart")]
public bool IsValidNumber_WithInvalidArguments_ReturnsFalse(int precision, int scale, bool onlyPositive, string value)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И еще забыли покрыть сценарии с разным onlyPositive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants