From 63e360f24f6fb55383b8598d2ee787ae25dda4d5 Mon Sep 17 00:00:00 2001 From: Aleksandr Balashov Date: Sun, 26 Oct 2025 21:42:44 +0500 Subject: [PATCH 1/2] homework --- Testing/Basic/Basic.csproj | 2 +- .../1. ObjectComparison/ObjectComparison.cs | 22 ++++--- .../NumberValidatorTests.cs | 65 ++++++++++++++----- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/Testing/Basic/Basic.csproj b/Testing/Basic/Basic.csproj index d23dca2..7478478 100644 --- a/Testing/Basic/Basic.csproj +++ b/Testing/Basic/Basic.csproj @@ -11,7 +11,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index d544c47..ca6cb5b 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -1,5 +1,6 @@ using NUnit.Framework; using NUnit.Framework.Legacy; +using FluentAssertions; namespace HomeExercise.Tasks.ObjectComparison; public class ObjectComparison @@ -15,15 +16,13 @@ public void CheckCurrentTsar() new Person("Vasili III of Russia", 28, 170, 60, null)); // Перепишите код на использование Fluent Assertions. - ClassicAssert.AreEqual(actualTsar.Name, expectedTsar.Name); - ClassicAssert.AreEqual(actualTsar.Age, expectedTsar.Age); - ClassicAssert.AreEqual(actualTsar.Height, expectedTsar.Height); - ClassicAssert.AreEqual(actualTsar.Weight, expectedTsar.Weight); - - ClassicAssert.AreEqual(expectedTsar.Parent!.Name, actualTsar.Parent!.Name); - ClassicAssert.AreEqual(expectedTsar.Parent.Age, actualTsar.Parent.Age); - ClassicAssert.AreEqual(expectedTsar.Parent.Height, actualTsar.Parent.Height); - ClassicAssert.AreEqual(expectedTsar.Parent.Parent, actualTsar.Parent.Parent); + + actualTsar.Should().BeEquivalentTo(expectedTsar, options => options + .Excluding(tsar => tsar.Id) + .Excluding(tsar => tsar.Parent!.Id)); + // Мы заменили 8 строчек тестов одной, так же если параметры класса Person поменяются в будущем нам не потребуется писать доп тесты, + // потому что FluentAssertions сравнивает все свойства, + // через Excluding мы исключили параметр id, чтобы тест не падал } [Test] @@ -34,7 +33,10 @@ public void CheckCurrentTsar_WithCustomEquality() var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); - // Какие недостатки у такого подхода? + // Какие недостатки у такого подхода? + + // Нам придется переписывать метод AreEqual каждый раз когда меняется класс Person, при падении мы получим только + // Что ожидалось True, а пришло False или наоборт, непонятно где ошибка ClassicAssert.True(AreEqual(actualTsar, expectedTsar)); } diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs index 950c9bc..ba388ad 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs @@ -7,25 +7,54 @@ namespace HomeExercise.Tasks.NumberValidator; [TestFixture] public class NumberValidatorTests { - [Test] - public void Test() + // тут решил добавить проверку на текст с ошибкой потому что иначе если первое верно срабатывала вторая проверка падала и + // получалось неверно и непонятно что упало + // например precision 1 и scale 1 и тест первый ниже проходит хотя должен не проходить + [TestCase(-1, 2, "precision must be a positive number", + TestName = "precision не может быть отрицательным")] + [TestCase(0, 2, "precision must be a positive number", + TestName = "precision не может быть равен 0")] + [TestCase(1, 2, "precision must be a non-negative number less or equal than precision", + TestName = "scale не может быть больше precision")] + [TestCase(1, 1, "precision must be a non-negative number less or equal than precision", + TestName = "scale не может быть равен precision")] + [TestCase(1, -1, "precision must be a non-negative number less or equal than precision", + TestName = "scale не может быть отрицательным")] + public void ConstructorWhenParametersInvalid(int precision, int scale, string expectedMessage) { - Assert.Throws(() => new NumberValidator(-1, 2, true)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); - Assert.Throws(() => new NumberValidator(-1, 2, false)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); + Assert.That( + () => new NumberValidator(precision, scale, true), + Throws.TypeOf() + .With.Message.EqualTo(expectedMessage) + ); + } + + [TestCase(1, 0, TestName = "scale может быть равен 0")] + [TestCase(7, 5, TestName = "общий тест")] + public void ConstructorWhenParametersValid(int precision, int scale) + { + Assert.DoesNotThrow(() => new NumberValidator(precision, scale, true)); + } + + + [TestCase(6, 2, false, "-1.23", true, TestName = "Валидное отрицательное число")] + [TestCase(6, 2, true, "+1.23", true, TestName = "Валидное положительное число")] + [TestCase(1, 0, true, "0", true, TestName = "Валидное целое число")] + [TestCase(4, 2, true, "+1.23", true, TestName = "Валидное число где знак и цифры укладываются в precision")] + [TestCase(6, 2, true, "+1,23", true, TestName = "Валидное число через запятую")] + [TestCase(3, 2, true, "00.00", false, TestName = "Ошибка: вышло за пределы precision")] + [TestCase(3, 2, true, "-0.00", false, TestName = "Ошибка: отрицательное число при onlyPositive=true")] + [TestCase(3, 2, true, "+0.00", false, TestName = "Ошибка: превышена точность из-за знака")] + [TestCase(6, 2, true, "0.000", false, TestName = "Ошибка: дробная часть превышает scale")] + [TestCase(3, 2, true, "-1.23", false, TestName = "Ошибка: отрицательное число при onlyPositive=true")] + [TestCase(3, 2, true, "a.sd", false, TestName = "Ошибка: нечисловая строка")] - ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0")); - ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("00.00")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-0.00")); - ClassicAssert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+0.00")); - ClassicAssert.IsTrue(new NumberValidator(4, 2, true).IsValidNumber("+1.23")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+1.23")); - ClassicAssert.IsFalse(new NumberValidator(17, 2, true).IsValidNumber("0.000")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-1.23")); - ClassicAssert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("a.sd")); + public void IsValidNumber_Tests(int precision, int scale, bool onlyPositive, string input, bool expectedResult) + { + NumberValidator validator = new NumberValidator(precision, scale, onlyPositive); + Boolean result = validator.IsValidNumber(input); + + ClassicAssert.AreEqual(expectedResult, result, + $"Упал для значения '{input}' с параметрами precision = {precision}, scale = {scale}, onlyPositive = {onlyPositive}"); } } \ No newline at end of file From 2324d609d8642aa000bd93dc5934e7a21e2db708 Mon Sep 17 00:00:00 2001 From: Aleksandr Balashov Date: Tue, 28 Oct 2025 18:14:28 +0500 Subject: [PATCH 2/2] fix --- .../1. ObjectComparison/ObjectComparison.cs | 11 +-- .../NumberValidatorTests.cs | 71 ++++++++++++++----- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index ca6cb5b..1901413 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -16,13 +16,16 @@ public void CheckCurrentTsar() new Person("Vasili III of Russia", 28, 170, 60, null)); // Перепишите код на использование Fluent Assertions. - - actualTsar.Should().BeEquivalentTo(expectedTsar, options => options - .Excluding(tsar => tsar.Id) - .Excluding(tsar => tsar.Parent!.Id)); + + actualTsar + .Should() + .BeEquivalentTo(expectedTsar, options => options + .Excluding(info => info.Path.EndsWith(".Id") || info.Path == "Id") + ); // Мы заменили 8 строчек тестов одной, так же если параметры класса Person поменяются в будущем нам не потребуется писать доп тесты, // потому что FluentAssertions сравнивает все свойства, // через Excluding мы исключили параметр id, чтобы тест не падал + } [Test] diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs index ba388ad..f3607a5 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs @@ -1,6 +1,7 @@  using NUnit.Framework; using NUnit.Framework.Legacy; +using FluentAssertions; namespace HomeExercise.Tasks.NumberValidator; @@ -10,51 +11,83 @@ public class NumberValidatorTests // тут решил добавить проверку на текст с ошибкой потому что иначе если первое верно срабатывала вторая проверка падала и // получалось неверно и непонятно что упало // например precision 1 и scale 1 и тест первый ниже проходит хотя должен не проходить + [TestCase(-1, 2, "precision must be a positive number", TestName = "precision не может быть отрицательным")] [TestCase(0, 2, "precision must be a positive number", TestName = "precision не может быть равен 0")] + public void Constructor_WhenInvalidPrecisionProvided_ShouldThrow(int precision, int scale, string expectedMessage) + { + Action act = () => new NumberValidator(precision, scale, true); + act + .Should() + .Throw() + .WithMessage(expectedMessage + ); + } + + [TestCase(1, 2, "precision must be a non-negative number less or equal than precision", TestName = "scale не может быть больше precision")] [TestCase(1, 1, "precision must be a non-negative number less or equal than precision", TestName = "scale не может быть равен precision")] [TestCase(1, -1, "precision must be a non-negative number less or equal than precision", TestName = "scale не может быть отрицательным")] - public void ConstructorWhenParametersInvalid(int precision, int scale, string expectedMessage) + public void Constructor_WhenInvalidScaleProvided_ShouldThrow(int precision, int scale, string expectedMessage) { - Assert.That( - () => new NumberValidator(precision, scale, true), - Throws.TypeOf() - .With.Message.EqualTo(expectedMessage) - ); + Action act = () => new NumberValidator(precision, scale, true); + + act + .Should() + .Throw() + .WithMessage(expectedMessage + ); } + [TestCase(1, 0, TestName = "scale может быть равен 0")] - [TestCase(7, 5, TestName = "общий тест")] - public void ConstructorWhenParametersValid(int precision, int scale) + [TestCase(7, 5, TestName = "Тест на создание объекта с правильными параметрами")] + public void Constructor_WhenValidParametersProvided_ShouldNotThrow(int precision, int scale) { - Assert.DoesNotThrow(() => new NumberValidator(precision, scale, true)); + Action act = () => new NumberValidator(precision, scale, true); + + act + .Should() + .NotThrow( + $"Не должно быть исключения при создании NumberValidator с precision={precision}, scale={scale}"); } - [TestCase(6, 2, false, "-1.23", true, TestName = "Валидное отрицательное число")] [TestCase(6, 2, true, "+1.23", true, TestName = "Валидное положительное число")] [TestCase(1, 0, true, "0", true, TestName = "Валидное целое число")] [TestCase(4, 2, true, "+1.23", true, TestName = "Валидное число где знак и цифры укладываются в precision")] [TestCase(6, 2, true, "+1,23", true, TestName = "Валидное число через запятую")] + public void IsValidNumber_WhenValidInputProvided_ShouldReturnTrue(int precision, int scale, bool onlyPositive, string input, bool expectedResult) + { + var validator = new NumberValidator(precision, scale, onlyPositive); + var result = validator.IsValidNumber(input); + + result + .Should() + .BeTrue( + $"Ожидалось, что '{input}' будет валидным при precision={precision}, scale={scale}, onlyPositive={onlyPositive}" + ); + } + [TestCase(3, 2, true, "00.00", false, TestName = "Ошибка: вышло за пределы precision")] - [TestCase(3, 2, true, "-0.00", false, TestName = "Ошибка: отрицательное число при onlyPositive=true")] + [TestCase(4, 2, true, "-0.00", false, TestName = "Ошибка: отрицательное число при onlyPositive=true")] [TestCase(3, 2, true, "+0.00", false, TestName = "Ошибка: превышена точность из-за знака")] [TestCase(6, 2, true, "0.000", false, TestName = "Ошибка: дробная часть превышает scale")] - [TestCase(3, 2, true, "-1.23", false, TestName = "Ошибка: отрицательное число при onlyPositive=true")] [TestCase(3, 2, true, "a.sd", false, TestName = "Ошибка: нечисловая строка")] + public void IsValidNumber_WhenInvalidInputProvided_ShouldReturnFalse(int precision, int scale, bool onlyPositive, string input, bool expectedResult) + { + var validator = new NumberValidator(precision, scale, onlyPositive); + var result = validator.IsValidNumber(input); - public void IsValidNumber_Tests(int precision, int scale, bool onlyPositive, string input, bool expectedResult) - { - NumberValidator validator = new NumberValidator(precision, scale, onlyPositive); - Boolean result = validator.IsValidNumber(input); - - ClassicAssert.AreEqual(expectedResult, result, - $"Упал для значения '{input}' с параметрами precision = {precision}, scale = {scale}, onlyPositive = {onlyPositive}"); + result + .Should() + .BeFalse( + $"Ожидалось, что '{input}' будет невалидным при precision={precision}, scale={scale}, onlyPositive={onlyPositive}" + ); } } \ No newline at end of file