-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Брозовский Максим #12
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
У нас все тесты(кроме тестов на конструктор) можно разделить на два вида благодаря тому, что у нас возвращается bool:
- С валидным значением
- С невалидным значением
Мб так и поступим, вместо дублирования?
@@ -36,6 +30,9 @@ public void CheckCurrentTsar_WithCustomEquality() | |||
|
|||
// Какие недостатки у такого подхода? | |||
ClassicAssert.True(AreEqual(actualTsar, expectedTsar)); | |||
// Нужно писать сам предикат AreEqual (лишний код в котором можно ошибиться) | |||
// + его надо поддерживать (при расширении класса Person нужно менять логику AreEqual) | |||
// В AreEqual нет Assert, значит при падении теста не будет информации о том как упал тест (причина падения) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Рассмотри еще кейс, когда у царя поле parent будет указывать на уже встречающегося царя в родословной. Нам же ничего не мешает так сделать :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Случай несколько вырожден, но формально возможен.
В таком случае возникнет бесконечная рекурсия.
Рассмотрим простой случай: есть actualTsar и пусть actualTsar.Parent.Parent = actualTsar.
Тогда при сравнении AreEqual(actualTsar, actualTsar) мы будем сравнивать их Parent, но у них тоже есть Parent, а значит их мы тоже будем сравнивать и т. д.
Таким образом мы получим бесконечную последовательность вызовов AreEqual для каждого Parent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему вырожден?
Ты не смотри на это как в жизни реально есть, у тебя написан код, который такое допускает.
И т.к мы не можем менять с тобой сурсы, давай обложимся на уровне тестов хотя бы
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Окей согласен
|
||
namespace HomeExercise.Tasks.NumberValidator; | ||
|
||
[TestFixture] | ||
public class NumberValidatorTests | ||
{ | ||
[Test] | ||
public void Test() | ||
public void NumberValidator_ThrowsArgumentException_WhenPrecisionIsNegative() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Проверяется единственный набор аргументов.
Тесты тебе нужны, чтобы при изменении кода отловить какое-то нарушение поведение. Хочется, чтобы тест отражал все варианты.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
[Test] | ||
public void NumberValidator_ThrowsArgumentException_WhenScaleLessThanZero() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
То же самое, что выше
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
[Test] | ||
public void NumberValidator_ThrowsArgumentException_WhenScaleLessThanZero() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Нет проверки на пограничные кейсы
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
[Test] | ||
public void NumberValidator_ThrowsArgumentException_WhenScaleGreaterOrEqualThanPrecision() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Один тест содержит сразу два теста. Давай разделим
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
[Test] | ||
public void NumberValidator_DoesNotThrow_WhenScaleLessThanPrecision() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если работает все только когда разница между ними 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[TestCase("-99", 3, false)] | ||
[TestCase("9999999", 7, true)] | ||
[TestCase("-999999999", 10, false)] | ||
public void IsValidNumber_ShouldBeTrue_WhenValueIsInteger(string value, int precision, bool onlyPositive) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если Int переполнен?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если scale тоже позадавать?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если с нуля начинается?
В общем еще много тестов можно написать :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Арабские цифры мы проверили, а другие будем проверять?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[TestCase("-300", 3, false)] | ||
[TestCase("300", 2, false)] | ||
[TestCase("-1234567890", 10, false)] | ||
public void IsValidNumber_ShouldBeFalse_WhenValueIsInteger(string value, int precision, bool onlyPositive) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Условие(WhenValueInInteger) должно отражать почему тест работает.
Если я открою тесты и посмотрю почему они упали, я увижу такую картину:
- IsValidNumber_ShouldBeTrue_WhenValueIsInteger
- IsValidNumber_ShouldBeFalse_WhenValueIsInteger
Условие одно, результаты разные. Придется лезть явно в код и читать почему тесты падают, из описания я мало что пойму
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[TestCase("-1234567890.1234567890", 21, 10, false)] | ||
[TestCase("0.0", 2, 1,false)] | ||
[TestCase("300.52", 5, 2, true)] | ||
public void IsValidNumber_ShouldBeTrue_WhenValueIsFloatNumber(string value, int precision, int scale, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А еще запятую можно ставить вместо точки
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[TestCase("+300.52")] | ||
[TestCase("-999.99")] | ||
[TestCase("-101")] | ||
public void IsValidNumber_ShouldBeTrue_WhenValueHasSign(string value) => TestShouldBeTrue(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А мы же отрицательные проверили в кейсаъ IsValidNumber_ShouldBeTrue_WhenValueIsInteger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- added some edge cases for constructor -- rework test schema for IsValidNumber -- added more testcases
@@ -36,6 +30,9 @@ public void CheckCurrentTsar_WithCustomEquality() | |||
|
|||
// Какие недостатки у такого подхода? | |||
ClassicAssert.True(AreEqual(actualTsar, expectedTsar)); | |||
// Нужно писать сам предикат AreEqual (лишний код в котором можно ошибиться) | |||
// + его надо поддерживать (при расширении класса Person нужно менять логику AreEqual) | |||
// В AreEqual нет Assert, значит при падении теста не будет информации о том как упал тест (причина падения) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему вырожден?
Ты не смотри на это как в жизни реально есть, у тебя написан код, который такое допускает.
И т.к мы не можем менять с тобой сурсы, давай обложимся на уровне тестов хотя бы
[TestCase(-1, 0, PrecisionErrorMessage, Description = "precision < 0")] | ||
[TestCase(-10, 1, PrecisionErrorMessage, Description = "precision < 0")] | ||
[TestCase(0, 0, PrecisionErrorMessage, Description = "precision == 0")] | ||
[TestCase(0, 2, PrecisionErrorMessage, Description = "precision == 0")] | ||
[TestCase(5, -1, ScaleErrorMessage, Description = "scale < 0")] | ||
[TestCase(5, -6, ScaleErrorMessage, Description = "scale < 0")] | ||
[TestCase(1, 2, ScaleErrorMessage, Description = "scale > precision")] | ||
[TestCase(1, 10, ScaleErrorMessage, Description = "scale > precision")] | ||
[TestCase(1, 1, ScaleErrorMessage, Description = "scale == precision")] | ||
[TestCase(2, 2, ScaleErrorMessage, Description = "scale == precision")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Там прям TestName вроде есть
[TestCase(17, 10)] | ||
[TestCase(3, 2)] | ||
[TestCase(1, 0)] | ||
[TestCase(6, 5)] | ||
[TestCase(300, 52)] | ||
public void NumberValidator_DoesNotThrow_WithValidParams(int precision, int scale) | ||
{ | ||
Action act = () => new NumberValidator(precision, scale); | ||
act.Should().NotThrow(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А нам правда важно тестировать валидные аргументы?
Типа, у тебя дофига тестов, которые это уже предполагают и в случае чего, мы поймем на них.
[TestCase("", 17, 10, false)] | ||
[TestCase(null, 17, 10, false)] | ||
[TestCase("II", 17, 10, false)] | ||
[TestCase("III", 17, 10, false)] | ||
[TestCase("VI", 17, 10, false)] | ||
[TestCase("X", 17, 10, false)] | ||
[TestCase("seven.eleven", 17, 10, false)] | ||
[TestCase("five/two", 17, 10, false)] | ||
[TestCase("11.11.11", 17, 10, false)] | ||
[TestCase("11.22,33", 17, 10, false)] | ||
[TestCase("55,22,33", 17, 10, false)] | ||
[TestCase("1\\2", 17, 10, false)] | ||
[TestCase("-100", 4, 0, true)] | ||
[TestCase("-0.00", 3, 2, true)] | ||
[TestCase("+1,23", 3, 2, true)] | ||
[TestCase("1.123", 4, 2, true)] | ||
[TestCase("0.000", 5, 2, true)] | ||
[TestCase("a.sd", 17, 10, false)] | ||
[TestCase("52", 1, 0, true)] | ||
[TestCase("-300", 3, 0, false)] | ||
[TestCase("300", 2, 0, false)] | ||
[TestCase("-1234567890", 10, 0, false)] | ||
[TestCase("-1.23", 3, 2, false)] | ||
[TestCase("-1234567890.1234567890", 20, 10, false)] | ||
[TestCase("100", 2, 1, true)] | ||
[TestCase("X,Y", 3, 2, true)] | ||
[TestCase("1\n.5", 3, 2, true)] | ||
[TestCase("+-15", 3, 2, false)] | ||
[TestCase("300_000", 17, 10, false)] | ||
[TestCase("52 000", 17, 10, false)] | ||
[TestCase("1/2", 17, 10, false)] | ||
[TestCase("12 . 22", 17, 10, false)] | ||
[TestCase("12 , 22", 17, 10, false)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай докинем информации о тесте? Если что-то упадет, то придется аргументы разбирать
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Например, кейс [TestCase("-300", 4, 0, false)] из другого тестового метода будет сложно понять по аргументам, придется лезть в реализацию и специфику.
[TestCase("+1.23", 17, 10, false)] | ||
[TestCase("+3.52", 15, 10, false)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А чем эти тесты отличаются?
[TestCase("100", 2, 1, true)] | ||
[TestCase("X,Y", 3, 2, true)] | ||
[TestCase("1\n.5", 3, 2, true)] | ||
[TestCase("+-15", 3, 2, false)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если два одинаковых знака?
.Excluding(p => p.Id) | ||
.Excluding(p => p.Parent.Id)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А p.Parent.Parent.Id мы не будем учитывать? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Мы в другом треде говорили про бесконечную рекурсию. А тут какое поведение будет?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В моем старом решение нет, потому что там если будет Parent.Parent, то их Id могут не совпасть и тогда мы упадем с ошибкой что Id не одинаковы (поэтому Id надо исключать у всех), но если их Id и Parent.Id совпадут, то да, будет бесконечная рекурсия
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Я писал тест исходя из actualTsar и expectedTsar, поэтому я не стал брать рекуретное обобщение
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Но так действительно лучше
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
но оно не поможет с рекурсией(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
оно и не должно, впрочем
[TestCase("II", 17, 10, false)] | ||
[TestCase("III", 17, 10, false)] | ||
[TestCase("VI", 17, 10, false)] | ||
[TestCase("X", 17, 10, false)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кроме римских есть еще различные цифры, и числа из них, на удивление, будут валидными :)
[TestCase("-1234567890.1234567890", 20, 10, false)] | ||
[TestCase("100", 2, 1, true)] | ||
[TestCase("X,Y", 3, 2, true)] | ||
[TestCase("1\n.5", 3, 2, true)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А если неэкранируемый на конце? или в начале?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше похожие кейсы рядом писать, чтобы контекст постоянно не переключать(например,100 и 300)
[TestCase("55,22,33", 17, 10, false)] | ||
[TestCase("1\\2", 17, 10, false)] | ||
[TestCase("-100", 4, 0, true)] | ||
[TestCase("-0.00", 3, 2, true)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Интересный же кейс) Почему положительного кейса нету такого?
[TestCase("2", 1, 0, true, TestName = "2 should be valid number")] | ||
[TestCase("52", 2, 1, true, TestName = "52 should be valid number")] | ||
[TestCase("-300", 4, 0, false, TestName = "-300 should be valid number")] | ||
[TestCase("+300", 4, 0, true, TestName = "+300 should be valid number")] | ||
[TestCase("-99", 3, 2, false, TestName = "-99 should be valid number")] | ||
[TestCase("9999999", 7, 1, false, TestName = "9999999 should be valid number")] | ||
[TestCase("2147483649", 10, 1, false, TestName = "Int overflow should be valid number")] | ||
[TestCase("-1234567890", 11, 8, false, TestName = "-1234567890 should be valid number")] | ||
[TestCase("0101010", 20, 12, false, TestName = "0101010 should be valid number")] | ||
[TestCase("01110.01010", 10, 5, true, TestName = "01110.01010 should be valid number")] | ||
[TestCase("01110,01010", 10, 5, true, TestName = "01110,01010 should be valid number")] | ||
[TestCase("+01110,01010", 11, 5, true, TestName = "+01110,01010 should be valid number")] | ||
[TestCase("-1234567890.1234567890", 21, 10, false, TestName = "-1234567890.1234567890 should be valid number")] | ||
[TestCase("+0.0", 3, 1, false, TestName = "+0.0 should be valid number")] | ||
[TestCase("0.000", 4, 3, true, TestName = "0.000 should be valid number")] | ||
[TestCase("300.52", 5, 2, true, TestName = "300.52 should be valid number")] | ||
[TestCase("+3.52", 15, 10, false, TestName = "+3.52 should be valid number")] | ||
[TestCase("+300,52", 17, 10, false, TestName = "+300,52 should be valid number")] | ||
[TestCase("1,23", 17, 10, false, TestName = "1,23 should be valid number")] | ||
[TestCase("+100", 4, 1, true, TestName = "+100 should be valid number")] | ||
[TestCase("100\n", 4, 2, true, TestName = "100\n should be valid number")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Каждый тест кейс - это тестирование какого-то конкретного случая. И этот случай хотелось бы описать словами, т.к сейчас мне придется лезть в код и смотреть почему этот аргумент валидный или наоборот невалидный.
Сейчас в случаях, где указаны просто аргументы в TestName'е, как будто нет смысла. Я и так смогу посмотреть аргументы, а мне важен что это за случай.
В случае с 100\n у меня вообще кажется в TestName'е при запуске тестов по итогу будет просто 100?) И как понять что было не так?
Это можно было бы назвать типа: When \n at the end of a number
[TestCase("", 17, 10, false, TestName = "empty string should be invalid number")] | ||
[TestCase(null, 17, 10, false, TestName = "null should be invalid number")] | ||
[TestCase("II", 17, 10, false, TestName = "II should be invalid number")] | ||
[TestCase("III", 17, 10, false, TestName = "III should be invalid number")] | ||
[TestCase("VI", 17, 10, false, TestName = "VI should be invalid number")] | ||
[TestCase("X", 17, 10, false, TestName = "X should be invalid number")] | ||
[TestCase("ఎనమద", 4, 0 , true, TestName = "ఎనమద should be invalid number")] | ||
[TestCase("తమమద", 4, 0 , true, TestName = "తమమద should be invalid number")] | ||
[TestCase("0xFF", 4, 0, true, TestName = "0xFF should be invalid number")] | ||
[TestCase("0x1A", 4, 0, true, TestName = "0x1A should be invalid number")] | ||
[TestCase("0o75", 4, 0, true, TestName = "0o75 should be invalid number")] | ||
[TestCase("0o44", 4, 0, true, TestName = "0o44 should be invalid number")] | ||
[TestCase("0b1010", 6, 0, true, TestName = "0b1010 should be invalid number")] | ||
[TestCase("0b01110.01010", 10, 5, true, TestName = "0b01110.01010 should be invalid number")] | ||
[TestCase("seven.eleven", 17, 10, false, TestName = "seven.eleven should be invalid number")] | ||
[TestCase("five/two", 17, 10, false, TestName = "five/two should be invalid number")] | ||
[TestCase("11.11.11", 17, 10, false, TestName = "11.11.11 should be invalid number")] | ||
[TestCase("+127.000.001", 17, 10, false, TestName = "+127.000.001 should be invalid number")] | ||
[TestCase("11.22,33", 17, 10, false, TestName = "11.22.33 should be invalid number")] | ||
[TestCase("55,22,33", 17, 10, false, TestName = "55.22.33 should be invalid number")] | ||
[TestCase("+1\\2", 17, 10, false, TestName = "+1\\2 should be invalid number")] | ||
[TestCase("X,Y", 3, 2, true, TestName = "X,Y should be invalid number")] | ||
[TestCase("1\n.5", 3, 2, true, TestName = "1\n.5 should be invalid number")] | ||
[TestCase("\n2.4", 3, 2, true, TestName = "\n2.4 should be invalid number")] | ||
[TestCase("+-15", 3, 2, false, TestName = "+-15 should be invalid number")] | ||
[TestCase("--10", 4, 2, false, TestName = "--10 should be invalid number")] | ||
[TestCase("++1", 3, 0, true, TestName = "++1 should be invalid number")] | ||
[TestCase("300_000", 17, 10, false, TestName = "300_000 should be invalid number")] | ||
[TestCase("52 000", 17, 10, false, TestName = "52 000 should be invalid number")] | ||
[TestCase("1/2", 17, 10, false, TestName = "1/2 should be invalid number")] | ||
[TestCase("12 . 22", 17, 10, false, TestName = "12 . 22 should be invalid number")] | ||
[TestCase("12 , 22", 17, 10, false, TestName = "12 , 22 should be invalid number")] | ||
[TestCase("a.sd", 17, 10, false, TestName = "a.sd should be invalid number")] | ||
[TestCase("-100", 4, 0, true, TestName = "-100 should be invalid number because onlyPositive is true")] | ||
[TestCase("+1,23", 3, 2, true, TestName = "+1.23 should be invalid number because precision < 4")] | ||
[TestCase("1.123", 4, 2, true, TestName = "1.123 should be invalid number because scale < 3")] | ||
[TestCase("0.00", 5, 1, true, TestName = "0.000 should be invalid number because scale < 2")] | ||
[TestCase("52", 1, 0, true, TestName = "52 should be invalid number because precision < 2")] | ||
[TestCase("-300", 3, 0, false, TestName = "-300 should be invalid number because precision < 4")] | ||
[TestCase("300", 2, 0, false, TestName = "300 should be invalid number because precision < 3")] | ||
[TestCase("+100", 3, 0, false, TestName = "+100 should be invalid number because precision < 4")] | ||
[TestCase("-1.23", 3, 2, false, TestName = "-1.23 should be invalid number because precision < 4")] | ||
[TestCase("-1234567890.1234567890", 20, 10, false, TestName = "-1234567890.1234567890 should be invalid number because precision < 21")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут тоже: мне недостаточно просто знать аргументов, мне важно знать какой сценарий покрывает тест
No description provided.