From 165bea96642b21786d802c284df1d2e577c45efe Mon Sep 17 00:00:00 2001 From: marchenko <1maks_2055@mail.ru> Date: Fri, 24 Oct 2025 14:49:27 +0500 Subject: [PATCH 1/5] initial --- .../Homework/1. ObjectComparison/ObjectComparison.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index d544c47..c860e6b 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using FluentAssertions; +using NUnit.Framework; using NUnit.Framework.Legacy; namespace HomeExercise.Tasks.ObjectComparison; @@ -15,6 +16,8 @@ public void CheckCurrentTsar() new Person("Vasili III of Russia", 28, 170, 60, null)); // Перепишите код на использование Fluent Assertions. + AreEqualFuent(actualTsar, expectedTsar).Should().Be(true); + ClassicAssert.AreEqual(actualTsar.Name, expectedTsar.Name); ClassicAssert.AreEqual(actualTsar.Age, expectedTsar.Age); ClassicAssert.AreEqual(actualTsar.Height, expectedTsar.Height); @@ -26,6 +29,11 @@ public void CheckCurrentTsar() ClassicAssert.AreEqual(expectedTsar.Parent.Parent, actualTsar.Parent.Parent); } + private bool AreEqualFuent(Person? actual, Person? expected) + { + return true; + } + [Test] [Description("Альтернативное решение. Какие у него недостатки?")] public void CheckCurrentTsar_WithCustomEquality() From 150b2978b505df14e32a2435b86ed7b70b69cf75 Mon Sep 17 00:00:00 2001 From: marchenko <1maks_2055@mail.ru> Date: Fri, 24 Oct 2025 18:53:14 +0500 Subject: [PATCH 2/5] =?UTF-8?q?=D0=94=D0=97=20=D0=A1=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1. ObjectComparison/ObjectComparison.cs | 82 ++++++++++++++----- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index c860e6b..31c667b 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -5,35 +5,78 @@ namespace HomeExercise.Tasks.ObjectComparison; public class ObjectComparison { - [Test] - [Description("Проверка текущего царя")] - [Category("ToRefactor")] - public void CheckCurrentTsar() + #region test data + private static Person currentTsar = TsarRegistry.GetCurrentTsar(); + private static Person tsarCopy = new Person("Ivan IV The Terrible", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + private static Person person0Parents = new Person("1", 1, 1, 1, null); + private static Person person0ParentsCopy = new Person("1", 1, 1, 1, null); + private static Person person1Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, null)); + private static Person person1ParentsСopy = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, null)); + private static Person person2Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); + private static Person person2ParentsCopy = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); + #endregion + private static IEnumerable TsarCheck_Cases() { - var actualTsar = TsarRegistry.GetCurrentTsar(); + yield return new TestCaseData(null, null).SetName("Пустые аргументы"); + yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя"); + yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя"); + yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель"); + yield return new TestCaseData(person2Parents, person2ParentsCopy).SetName("Родитель у родителя"); + } - var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, - new Person("Vasili III of Russia", 28, 170, 60, null)); + private static IEnumerable TsarCheck_FailCases() + { + var tsarCopy = new Person("Ivan IV The", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); - // Перепишите код на использование Fluent Assertions. - AreEqualFuent(actualTsar, expectedTsar).Should().Be(true); + yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка неправильного царя"); + yield return new TestCaseData(person0Parents, person1ParentsСopy).SetName("Разный родитель"); + yield return new TestCaseData(person1Parents, person2ParentsCopy).SetName("Разный родитель у родителя"); + yield return new TestCaseData(currentTsar, person0Parents).SetName("Полностью разные"); + } - ClassicAssert.AreEqual(actualTsar.Name, expectedTsar.Name); - ClassicAssert.AreEqual(actualTsar.Age, expectedTsar.Age); - ClassicAssert.AreEqual(actualTsar.Height, expectedTsar.Height); - ClassicAssert.AreEqual(actualTsar.Weight, expectedTsar.Weight); + [Test, TestCaseSource(nameof(TsarCheck_Cases))] + [Description("Проверка текущего царя")] + [Category("ToRefactor")] + public void CheckCurrentTsar(Person? actualTsar, Person? expectedTsar) + { + // Перепишите код на использование Fluent Assertions. + AreEqualFuent(actualTsar, expectedTsar); + } - 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); + [Test, TestCaseSource(nameof(TsarCheck_FailCases))] + public void FailCheckCurrentTsar(Person? actualTsar, Person? expectedTsar) + { + Action act = () => AreEqualFuent(actualTsar, expectedTsar); + act.Should().Throw(); } - private bool AreEqualFuent(Person? actual, Person? expected) + private void AreEqualFuent(Person? actual, Person? expected) { - return true; + actual.Should().BeEquivalentTo(expected, options => + options + .Excluding(t => t.Id) + .Excluding(t => t.Parent!) // Игнорировать Parent + ); + if (actual != null && expected != null) + { + if (actual.Parent != null && expected.Parent != null) + { + AreEqualFuent(actual.Parent, expected.Parent); + } + if (actual.Parent == null || expected.Parent == null) + { + actual.Parent.Should().BeNull(); + expected.Parent.Should().BeNull(); // Если один из родителей null то оба должны быть null + } + } } + // При добавлении новых полей в Person придется расширять условие в return еще больше; + // Тест должен пройти по всем Parent прежде чем дать результат, + // в моем тесте при различии полей, он сразу прервется выкинув исключение; + // Я добавил TestCaseSource для добавления новых кейсов, в данном тесте данные собираются в нем; + // Использование FluentAssertions упрощает прочтение кода в моем тесте; + [Test] [Description("Альтернативное решение. Какие у него недостатки?")] public void CheckCurrentTsar_WithCustomEquality() @@ -50,6 +93,7 @@ private bool AreEqual(Person? actual, Person? expected) { if (actual == expected) return true; if (actual == null || expected == null) return false; + // Большой return return actual.Name == expected.Name && actual.Age == expected.Age From db5b445be7cd27406f0bc815b2df60c8d0aaecd6 Mon Sep 17 00:00:00 2001 From: marchenko <1maks_2055@mail.ru> Date: Fri, 24 Oct 2025 20:06:52 +0500 Subject: [PATCH 3/5] =?UTF-8?q?=D0=94=D0=97=20=D0=A0=D0=B5=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1. ObjectComparison/ObjectComparison.cs | 41 +++---- .../2. NumberValidator/NumberValidator.cs | 2 +- .../NumberValidatorTests.cs | 102 ++++++++++++++---- 3 files changed, 104 insertions(+), 41 deletions(-) diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index 31c667b..f1535dd 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -15,25 +15,33 @@ public class ObjectComparison private static Person person2Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); private static Person person2ParentsCopy = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); #endregion - private static IEnumerable TsarCheck_Cases() - { - yield return new TestCaseData(null, null).SetName("Пустые аргументы"); - yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя"); - yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя"); - yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель"); - yield return new TestCaseData(person2Parents, person2ParentsCopy).SetName("Родитель у родителя"); - } - + private static IEnumerable TsarCheck_FailCases() { - var tsarCopy = new Person("Ivan IV The", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + var tsarFailedCopy = new Person("Ivan IV The", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); - yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка неправильного царя"); + yield return new TestCaseData(currentTsar, tsarFailedCopy).SetName("Проверка неправильного царя"); yield return new TestCaseData(person0Parents, person1ParentsСopy).SetName("Разный родитель"); yield return new TestCaseData(person1Parents, person2ParentsCopy).SetName("Разный родитель у родителя"); yield return new TestCaseData(currentTsar, person0Parents).SetName("Полностью разные"); } + [Test, TestCaseSource(nameof(TsarCheck_FailCases))] + public void FailCheckCurrentTsar(Person? actualTsar, Person? expectedTsar) + { + Action act = () => AreEqualFuent(actualTsar, expectedTsar); + act.Should().Throw(); + } + + private static IEnumerable TsarCheck_Cases() + { + yield return new TestCaseData(null, null).SetName("Пустые аргументы"); + yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя"); + yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя"); + yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель"); + yield return new TestCaseData(person2Parents, person2ParentsCopy).SetName("Родитель у родителя"); + } + [Test, TestCaseSource(nameof(TsarCheck_Cases))] [Description("Проверка текущего царя")] [Category("ToRefactor")] @@ -43,19 +51,12 @@ public void CheckCurrentTsar(Person? actualTsar, Person? expectedTsar) AreEqualFuent(actualTsar, expectedTsar); } - [Test, TestCaseSource(nameof(TsarCheck_FailCases))] - public void FailCheckCurrentTsar(Person? actualTsar, Person? expectedTsar) - { - Action act = () => AreEqualFuent(actualTsar, expectedTsar); - act.Should().Throw(); - } - private void AreEqualFuent(Person? actual, Person? expected) { actual.Should().BeEquivalentTo(expected, options => options .Excluding(t => t.Id) - .Excluding(t => t.Parent!) // Игнорировать Parent + .Excluding(t => t.Parent) // Игнорировать Parent ); if (actual != null && expected != null) { @@ -66,7 +67,7 @@ private void AreEqualFuent(Person? actual, Person? expected) if (actual.Parent == null || expected.Parent == null) { actual.Parent.Should().BeNull(); - expected.Parent.Should().BeNull(); // Если один из родителей null то оба должны быть null + expected.Parent.Should().BeNull(); } } } diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidator.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidator.cs index 327ce9c..55c3c61 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidator.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidator.cs @@ -17,7 +17,7 @@ public NumberValidator(int precision, int scale = 0, bool onlyPositive = false) if (precision <= 0) throw new ArgumentException("precision must be a positive number"); if (scale < 0 || scale >= precision) - throw new ArgumentException("precision must be a non-negative number less or equal than precision"); + throw new ArgumentException("scale must be a non-negative number less or equal than precision"); numberRegex = new Regex(@"^([+-]?)(\d+)([.,](\d+))?$", RegexOptions.IgnoreCase); } diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs index 950c9bc..0d6eabc 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs @@ -1,4 +1,6 @@  +using System.Runtime.CompilerServices; +using FluentAssertions; using NUnit.Framework; using NUnit.Framework.Legacy; @@ -7,25 +9,85 @@ namespace HomeExercise.Tasks.NumberValidator; [TestFixture] public class NumberValidatorTests { - [Test] - public void Test() - { - 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)); - - 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")); + #region Constructor tests + + private static IEnumerable Constructor_MustThrow() + { + yield return new TestCaseData(-1, 2, true); + yield return new TestCaseData(-1, 2, false); + yield return new TestCaseData(1, -2, true); + yield return new TestCaseData(-1, -2, false); + yield return new TestCaseData(1, 2, true); + yield return new TestCaseData(1, 1, false); + } + + private static IEnumerable Constructor_NotThrow() + { + yield return new TestCaseData(1, 0, true); + yield return new TestCaseData(int.MaxValue, int.MaxValue-1, true); + } + + [Test, TestCaseSource(nameof(Constructor_MustThrow))] + public void Constructor_Throw_OnInvalidArgument(int precision, int scale, bool onlyPositive) + { + Action action = () => new NumberValidator(precision, scale, onlyPositive); + action.Should().Throw(); + } + + [Test, TestCaseSource(nameof(Constructor_NotThrow))] + public void Constructor_NotThrow_OnValidArgument(int precision, int scale, bool onlyPositive) + { + Action action = () => new NumberValidator(precision, scale, onlyPositive); + action.Should().NotThrow(); + } + + #endregion + + #region IsValidNumber tests + + private static IEnumerable CorrectNumbers_Cases() + { + yield return new TestCaseData(17, 2, true, new string[] { "0.0", "0" }); + + yield return new TestCaseData(4, 2, false, new string[] { "-1.23", "12.32" }); + + yield return new TestCaseData(4, 2, true, new string[] {"+1.23", "32"}); + + yield return new TestCaseData(20, 19, false, new string[] {"1.1234567890123456789", "1123456789012345678.9"}); + } + private static IEnumerable IncorrectNumbers_Cases() + { + yield return new TestCaseData(3, 2, true, new string[] { "00.00", "-0.00", "a.sd", "+0.00", "+1.23" }); + + yield return new TestCaseData(4, 2, true, new string[] {"-0.00", "-1.23"}); + + yield return new TestCaseData(17, 2, false, new string[] {"0.sd00", "O12322121.23"}); + + yield return new TestCaseData(19, 18, false, new string[] {"1.1234567890123456789", "12345678912345678900.01"}); + } + + [Test, TestCaseSource(nameof(CorrectNumbers_Cases))] + public void IsValidNumber_CorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) + { + var validator = new NumberValidator(precision, scale, onlyPositive); + + foreach (var number in numbers) + { + validator.IsValidNumber(number).Should().BeTrue(); + } + } + + [Test, TestCaseSource(nameof(IncorrectNumbers_Cases))] + public void IsValidNumber_IncorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) + { + var validator = new NumberValidator(precision, scale, onlyPositive); + + foreach (var number in numbers) + { + validator.IsValidNumber(number).Should().BeFalse(); + } + } + + #endregion } \ No newline at end of file From 1b2de5ed619033acf42cf867d8cf68470097b639 Mon Sep 17 00:00:00 2001 From: marchenko <1maks_2055@mail.ru> Date: Wed, 29 Oct 2025 02:20:04 +0500 Subject: [PATCH 4/5] =?UTF-8?q?Refactor=20=D0=94=D0=97=20Testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1. ObjectComparison/ObjectComparison.cs | 156 +++++++++++++----- .../Homework/1. ObjectComparison/Person.cs | 9 + .../NumberValidatorTests.cs | 88 ++++++---- 3 files changed, 181 insertions(+), 72 deletions(-) diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index f1535dd..48a517d 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -1,4 +1,5 @@ -using FluentAssertions; +using System.Runtime.CompilerServices; +using FluentAssertions; using NUnit.Framework; using NUnit.Framework.Legacy; @@ -8,69 +9,140 @@ public class ObjectComparison #region test data private static Person currentTsar = TsarRegistry.GetCurrentTsar(); private static Person tsarCopy = new Person("Ivan IV The Terrible", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + private static Person tsarCopyDifferent = new Person("Ivan IV The Kind", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + private static Person person0Parents = new Person("1", 1, 1, 1, null); - private static Person person0ParentsCopy = new Person("1", 1, 1, 1, null); + private static Person person0ParentsCopy = Person.Copy(person0Parents); + private static Person person0ParentsLimits = new Person(string.Empty, int.MaxValue, int.MinValue, 0, null); + private static Person person0ParentsLimitsCopy = Person.Copy(person0ParentsLimits); private static Person person1Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, null)); - private static Person person1ParentsСopy = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, null)); + private static Person person1ParentsСopy = Person.Copy(person1Parents); + private static Person person1ParentsDifferent = new Person("1", 1, 1, 1, new Person("3", 3, 3, 3, null)); private static Person person2Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); - private static Person person2ParentsCopy = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); + private static Person person2ParentsCopy = Person.Copy(person2Parents); + private static Person person2ParentsDifferent = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("5", 5, 5, 5, null))); #endregion - private static IEnumerable TsarCheck_FailCases() + private static IEnumerable FieldCompare_SuccessCases() { - var tsarFailedCopy = new Person("Ivan IV The", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); + yield return new TestCaseData(null, null).SetName("Пустые аргументы"); + yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя"); + yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя"); + yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель"); + yield return new TestCaseData(person0Parents, person1ParentsСopy).SetName("Разные родители"); + yield return new TestCaseData(person2Parents, person2ParentsDifferent).SetName("Разные прародители"); + yield return new TestCaseData(person0ParentsLimits, person0ParentsLimitsCopy).SetName("Проверка с граничными значениями полей"); + } - yield return new TestCaseData(currentTsar, tsarFailedCopy).SetName("Проверка неправильного царя"); - yield return new TestCaseData(person0Parents, person1ParentsСopy).SetName("Разный родитель"); - yield return new TestCaseData(person1Parents, person2ParentsCopy).SetName("Разный родитель у родителя"); + [Test, TestCaseSource(nameof(FieldCompare_SuccessCases))] + [Description("Проверка Person по полям - поля равны")] + public void AreEqual_NotThrows_OnEqualFields(Person? actual, Person? expected) + { + actual.Should().BeEquivalentTo(expected, options => + options + .Excluding(t => t.Id) + .Excluding(t => t.Parent) + ); + } + + private static IEnumerable FieldCompare_FailCases() + { + yield return new TestCaseData(currentTsar, null).SetName("Сравнение с null"); + yield return new TestCaseData(currentTsar, tsarCopyDifferent).SetName("Проверка неправильного царя"); yield return new TestCaseData(currentTsar, person0Parents).SetName("Полностью разные"); + yield return new TestCaseData(person0ParentsLimits, person0Parents).SetName("Просто разные"); + } + + [Test, TestCaseSource(nameof(FieldCompare_FailCases))] + [Description("Проверка Person по полям - поля разные")] + public void AreEqual_Throws_OnDifferentFields(Person? actual, Person? expected) + { + actual.Should().NotBeEquivalentTo(expected, options => + options + .Excluding(t => t.Id) + .Excluding(t => t.Parent) + ); } - [Test, TestCaseSource(nameof(TsarCheck_FailCases))] - public void FailCheckCurrentTsar(Person? actualTsar, Person? expectedTsar) + private static IEnumerable FullCompare_SuccessCases() { - Action act = () => AreEqualFuent(actualTsar, expectedTsar); - act.Should().Throw(); + yield return new TestCaseData(null, null).SetName("Пустые аргументы при полном сравнении"); + yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя при полном сравнении"); + yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя при полном сравнении"); + yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель при полном сравнении"); + yield return new TestCaseData(person2Parents, person2ParentsCopy).SetName("Родитель у родителя при полном сравнении"); } - - private static IEnumerable TsarCheck_Cases() + + + [Test, TestCaseSource(nameof(FullCompare_SuccessCases))] + [Description("Проверка Person по Parent - Parent равны")] + public void AreEqual_NotThrows_OnEqualPersons(Person? actual, Person? expected) { - yield return new TestCaseData(null, null).SetName("Пустые аргументы"); - yield return new TestCaseData(currentTsar, tsarCopy).SetName("Проверка царя"); - yield return new TestCaseData(person0Parents, person0ParentsCopy).SetName("Нет родителя"); - yield return new TestCaseData(person1Parents, person1ParentsСopy).SetName("Есть родитель"); - yield return new TestCaseData(person2Parents, person2ParentsCopy).SetName("Родитель у родителя"); - } + actual.Should().BeEquivalentTo(expected, options => + options + .Excluding(t => t.Id) + .Using(ctx => + { + AreEqual_NotThrows_OnEqualFields(ctx.Subject, ctx.Expectation); + if (ctx.Subject != null && ctx.Expectation != null) + { + if (ctx.Subject.Parent != null && ctx.Expectation.Parent != null) + { + AreEqual_NotThrows_OnEqualPersons(ctx.Subject.Parent, ctx.Expectation.Parent); + } + else + { + ctx.Subject.Parent.Should().BeEquivalentTo(ctx.Expectation.Parent, options => + options + .Excluding(t => t.Id) + .Excluding(t => t.Parent) + ); + } + } + } + ) + .WhenTypeIs() + ); + } - [Test, TestCaseSource(nameof(TsarCheck_Cases))] - [Description("Проверка текущего царя")] - [Category("ToRefactor")] - public void CheckCurrentTsar(Person? actualTsar, Person? expectedTsar) + private static IEnumerable FullCompare_FailCases() { - // Перепишите код на использование Fluent Assertions. - AreEqualFuent(actualTsar, expectedTsar); + yield return new TestCaseData(currentTsar, null).SetName("Сравнение с null при полном сравнении"); + yield return new TestCaseData(currentTsar, tsarCopyDifferent).SetName("Проверка неправильного царя при полном сравнении"); + yield return new TestCaseData(currentTsar, person1Parents).SetName("Полностью разные при полном сравнении"); + yield return new TestCaseData(person1Parents, person0Parents).SetName("Родитель null при полном сравнении"); + yield return new TestCaseData(person1Parents, person1ParentsDifferent).SetName("Разные родители при полном сравнении"); + yield return new TestCaseData(person2Parents, person2ParentsDifferent).SetName("Разные прародители при полном сравнении"); } - private void AreEqualFuent(Person? actual, Person? expected) + [Test, TestCaseSource(nameof(FullCompare_FailCases))] + [Description("Проверка Person по Parent - Parent различны")] + public void AreEqual_Throw_OnDifferentPersons(Person? actual, Person? expected) { - actual.Should().BeEquivalentTo(expected, options => + actual.Should().NotBeEquivalentTo(expected, options => options .Excluding(t => t.Id) - .Excluding(t => t.Parent) // Игнорировать Parent + .Using(ctx => + { + AreEqual_NotThrows_OnEqualFields(ctx.Subject, ctx.Expectation); + if (ctx.Subject != null && ctx.Expectation != null) + { + if (ctx.Subject.Parent != null && ctx.Expectation.Parent != null) + { + AreEqual_NotThrows_OnEqualPersons(ctx.Subject.Parent, ctx.Expectation.Parent); + } + else + { + (ctx.Subject.Parent == null && ctx.Expectation.Parent == null).Should().BeTrue(); + } + } + } + ) + .WhenTypeIs() ); - if (actual != null && expected != null) - { - if (actual.Parent != null && expected.Parent != null) - { - AreEqualFuent(actual.Parent, expected.Parent); - } - if (actual.Parent == null || expected.Parent == null) - { - actual.Parent.Should().BeNull(); - expected.Parent.Should().BeNull(); - } - } } + + //Как будто бы если оставлять обобщенный метод кода становится меньше // При добавлении новых полей в Person придется расширять условие в return еще больше; // Тест должен пройти по всем Parent прежде чем дать результат, diff --git a/Testing/Basic/Homework/1. ObjectComparison/Person.cs b/Testing/Basic/Homework/1. ObjectComparison/Person.cs index 4846867..425d3f7 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/Person.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/Person.cs @@ -18,4 +18,13 @@ public Person(string name, int age, int height, int weight, Person parent) Weight = weight; Parent = parent; } + + public static Person? Copy(Person? source) + { + if (source is null) + { + return null; + } + return new Person(source.Name, source.Age, source.Height, source.Weight, Person.Copy(source.Parent)); + } } \ No newline at end of file diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs index 0d6eabc..99d9a61 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs @@ -11,64 +11,87 @@ public class NumberValidatorTests { #region Constructor tests - private static IEnumerable Constructor_MustThrow() + private static IEnumerable Constructor_MustThrow_OnPrecisionExceed() { - yield return new TestCaseData(-1, 2, true); - yield return new TestCaseData(-1, 2, false); - yield return new TestCaseData(1, -2, true); - yield return new TestCaseData(-1, -2, false); - yield return new TestCaseData(1, 2, true); - yield return new TestCaseData(1, 1, false); + yield return new TestCaseData(0, 0, false).SetName("Некорректная длина"); + yield return new TestCaseData(-1, -1, false).SetName("Некорректная длина"); + yield return new TestCaseData(-2, 2, true).SetName("Некорректная длина"); + yield return new TestCaseData(0, -3, false).SetName("Некорректная длина"); + yield return new TestCaseData(-5, -5, false).SetName("Некорректная длина"); } - private static IEnumerable Constructor_NotThrow() + private static IEnumerable Constructor_MustThrow_OnScaleExceed() { - yield return new TestCaseData(1, 0, true); - yield return new TestCaseData(int.MaxValue, int.MaxValue-1, true); + yield return new TestCaseData(1, 2, true).SetName("Некорректная точность"); + yield return new TestCaseData(1, 1, false).SetName("Некорректная точность"); + yield return new TestCaseData(1, -1, false).SetName("Некорректная точность"); } - [Test, TestCaseSource(nameof(Constructor_MustThrow))] - public void Constructor_Throw_OnInvalidArgument(int precision, int scale, bool onlyPositive) + private static IEnumerable Constructor_NotThrow_OnValidArguments() + { + yield return new TestCaseData(1, 0, true).SetName("Корректные аргументы"); + yield return new TestCaseData(int.MaxValue, int.MaxValue-1, true).SetName("Корректные аргументы"); + } + + [Test] + [ + TestCaseSource(nameof(Constructor_MustThrow_OnPrecisionExceed)), + TestCaseSource(nameof(Constructor_MustThrow_OnScaleExceed)) + ] + public void Constructor_Throws_OnInvalidArgument(int precision, int scale, bool onlyPositive) { Action action = () => new NumberValidator(precision, scale, onlyPositive); action.Should().Throw(); } - [Test, TestCaseSource(nameof(Constructor_NotThrow))] - public void Constructor_NotThrow_OnValidArgument(int precision, int scale, bool onlyPositive) + [Test, TestCaseSource(nameof(Constructor_NotThrow_OnValidArguments))] + public void Constructor_NotThrows_OnValidArgument(int precision, int scale, bool onlyPositive) { Action action = () => new NumberValidator(precision, scale, onlyPositive); action.Should().NotThrow(); } - + #endregion #region IsValidNumber tests - private static IEnumerable CorrectNumbers_Cases() + private static IEnumerable IsValidNumbers_ValidNumbersCases() { - yield return new TestCaseData(17, 2, true, new string[] { "0.0", "0" }); + yield return new TestCaseData(17, 2, true, new string[] { "0.0", "0", "012322121.23" }).SetName("Правильные числа"); - yield return new TestCaseData(4, 2, false, new string[] { "-1.23", "12.32" }); - - yield return new TestCaseData(4, 2, true, new string[] {"+1.23", "32"}); + yield return new TestCaseData(4, 2, false, new string[] { "-1,23", "12,32" }).SetName("Правильные числа"); - yield return new TestCaseData(20, 19, false, new string[] {"1.1234567890123456789", "1123456789012345678.9"}); + yield return new TestCaseData(4, 2, true, new string[] { "+1,23", "32" }).SetName("Правильные числа"); + + yield return new TestCaseData(20, 19, false, new string[] { "1,1234567890123456789", "1123456789012345678.9" }).SetName("Правильные числа"); } - private static IEnumerable IncorrectNumbers_Cases() + + private static IEnumerable IsValidNumbers_TooBigNumbersCases() { - yield return new TestCaseData(3, 2, true, new string[] { "00.00", "-0.00", "a.sd", "+0.00", "+1.23" }); + yield return new TestCaseData(3, 2, false, new string[] { "00.00", "-0.00", "+0.00", "01,24" }).SetName("Слишком большие числа"); + + yield return new TestCaseData(19, 18, false, new string[] { "1.1234567890123456789", "12345678912345678900.01" }).SetName("Слишком большие числа"); + + } + private static IEnumerable IsValidNumbers_WithWrongSignCases() + { + yield return new TestCaseData(4, 2, true, new string[] { "-0.00", "-1.23" }).SetName("Числа с неправильным знаком");; - yield return new TestCaseData(4, 2, true, new string[] {"-0.00", "-1.23"}); + yield return new TestCaseData(4, 3, true, new string[] { ".000", "+.124" }).SetName("Числа без целой части");; + } + + private static IEnumerable IsValidNumbers_WithLiteralsCases() + { + yield return new TestCaseData(4, 2, true, new string[] { "O.00", "_0.00"}).SetName("Некорректные символы"); - yield return new TestCaseData(17, 2, false, new string[] {"0.sd00", "O12322121.23"}); + yield return new TestCaseData(17, 2, false, new string[] {"0.sd00", "OIOIIOIO"}).SetName("Некорректные символы");; - yield return new TestCaseData(19, 18, false, new string[] {"1.1234567890123456789", "12345678912345678900.01"}); + yield return new TestCaseData(19, 18, false, new string[] {"1,12 0123456789", "1678912345678900 . 01", "#!@$:|><1,2?%^&*()"}).SetName("Некорректные символы");; } - [Test, TestCaseSource(nameof(CorrectNumbers_Cases))] - public void IsValidNumber_CorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) + [Test, TestCaseSource(nameof(IsValidNumbers_ValidNumbersCases))] + public void IsValidNumber_IsTrue_OnCorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) { var validator = new NumberValidator(precision, scale, onlyPositive); @@ -78,8 +101,13 @@ public void IsValidNumber_CorrectNumber(int precision, int scale, bool onlyPosit } } - [Test, TestCaseSource(nameof(IncorrectNumbers_Cases))] - public void IsValidNumber_IncorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) + [Test] + [ + TestCaseSource(nameof(IsValidNumbers_TooBigNumbersCases)), + TestCaseSource(nameof(IsValidNumbers_WithLiteralsCases)), + TestCaseSource(nameof(IsValidNumbers_WithWrongSignCases)) + ] + public void IsValidNumber_IsFalse_OnIncorrectNumber(int precision, int scale, bool onlyPositive, string[] numbers) { var validator = new NumberValidator(precision, scale, onlyPositive); From 598bb2c8700315c5f0236ac1cce3305c96a84f8f Mon Sep 17 00:00:00 2001 From: marchenko <1maks_2055@mail.ru> Date: Wed, 29 Oct 2025 20:05:18 +0500 Subject: [PATCH 5/5] Refactor --- Testing/Advanced/Advanced.csproj | 20 ++++---- Testing/Basic/Basic.csproj | 16 +++--- .../1. ObjectComparison/ObjectComparison.cs | 50 +++---------------- .../Homework/1. ObjectComparison/Person.cs | 9 ++-- 4 files changed, 31 insertions(+), 64 deletions(-) diff --git a/Testing/Advanced/Advanced.csproj b/Testing/Advanced/Advanced.csproj index 1a7435e..355ffea 100644 --- a/Testing/Advanced/Advanced.csproj +++ b/Testing/Advanced/Advanced.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -7,16 +7,16 @@ - - + + - - - - - - - + + + + + + + diff --git a/Testing/Basic/Basic.csproj b/Testing/Basic/Basic.csproj index d23dca2..c4f36ef 100644 --- a/Testing/Basic/Basic.csproj +++ b/Testing/Basic/Basic.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -7,16 +7,16 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + + + + 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 48a517d..7df95b5 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs @@ -12,14 +12,14 @@ public class ObjectComparison private static Person tsarCopyDifferent = new Person("Ivan IV The Kind", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); private static Person person0Parents = new Person("1", 1, 1, 1, null); - private static Person person0ParentsCopy = Person.Copy(person0Parents); + private static Person person0ParentsCopy = person0Parents.Copy()!; private static Person person0ParentsLimits = new Person(string.Empty, int.MaxValue, int.MinValue, 0, null); - private static Person person0ParentsLimitsCopy = Person.Copy(person0ParentsLimits); + private static Person person0ParentsLimitsCopy = person0ParentsLimits.Copy()!; private static Person person1Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, null)); - private static Person person1ParentsСopy = Person.Copy(person1Parents); + private static Person person1ParentsСopy = person1Parents.Copy()!; private static Person person1ParentsDifferent = new Person("1", 1, 1, 1, new Person("3", 3, 3, 3, null)); private static Person person2Parents = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("3", 3, 3, 3, null))); - private static Person person2ParentsCopy = Person.Copy(person2Parents); + private static Person person2ParentsCopy = person2Parents.Copy()!; private static Person person2ParentsDifferent = new Person("1", 1, 1, 1, new Person("2", 2, 2, 2, new Person("5", 5, 5, 5, null))); #endregion @@ -81,27 +81,7 @@ public void AreEqual_NotThrows_OnEqualPersons(Person? actual, Person? expected) actual.Should().BeEquivalentTo(expected, options => options .Excluding(t => t.Id) - .Using(ctx => - { - AreEqual_NotThrows_OnEqualFields(ctx.Subject, ctx.Expectation); - if (ctx.Subject != null && ctx.Expectation != null) - { - if (ctx.Subject.Parent != null && ctx.Expectation.Parent != null) - { - AreEqual_NotThrows_OnEqualPersons(ctx.Subject.Parent, ctx.Expectation.Parent); - } - else - { - ctx.Subject.Parent.Should().BeEquivalentTo(ctx.Expectation.Parent, options => - options - .Excluding(t => t.Id) - .Excluding(t => t.Parent) - ); - } - } - } - ) - .WhenTypeIs() + .Excluding(t => t.Path.EndsWith("Id")) ); } @@ -122,27 +102,11 @@ public void AreEqual_Throw_OnDifferentPersons(Person? actual, Person? expected) actual.Should().NotBeEquivalentTo(expected, options => options .Excluding(t => t.Id) - .Using(ctx => - { - AreEqual_NotThrows_OnEqualFields(ctx.Subject, ctx.Expectation); - if (ctx.Subject != null && ctx.Expectation != null) - { - if (ctx.Subject.Parent != null && ctx.Expectation.Parent != null) - { - AreEqual_NotThrows_OnEqualPersons(ctx.Subject.Parent, ctx.Expectation.Parent); - } - else - { - (ctx.Subject.Parent == null && ctx.Expectation.Parent == null).Should().BeTrue(); - } - } - } - ) - .WhenTypeIs() + .Excluding(t => t.Path.EndsWith("Id")) ); } - //Как будто бы если оставлять обобщенный метод кода становится меньше + // А что так можно было что ли? // При добавлении новых полей в Person придется расширять условие в return еще больше; // Тест должен пройти по всем Parent прежде чем дать результат, diff --git a/Testing/Basic/Homework/1. ObjectComparison/Person.cs b/Testing/Basic/Homework/1. ObjectComparison/Person.cs index 425d3f7..458dd04 100644 --- a/Testing/Basic/Homework/1. ObjectComparison/Person.cs +++ b/Testing/Basic/Homework/1. ObjectComparison/Person.cs @@ -6,10 +6,10 @@ public class Person public static int IdCounter = 0; public int Age, Height, Weight; public string Name; - public Person Parent; + public Person? Parent; public int Id; - public Person(string name, int age, int height, int weight, Person parent) + public Person(string name, int age, int height, int weight, Person? parent) { Id = IdCounter++; Name = name; @@ -18,6 +18,8 @@ public Person(string name, int age, int height, int weight, Person parent) Weight = weight; Parent = parent; } + + public Person? Copy() => Copy(this)!; public static Person? Copy(Person? source) { @@ -25,6 +27,7 @@ public Person(string name, int age, int height, int weight, Person parent) { return null; } - return new Person(source.Name, source.Age, source.Height, source.Weight, Person.Copy(source.Parent)); + return new Person(source.Name, source.Age, source.Height, source.Weight, Person.Copy(source.Parent!)!); } + } \ No newline at end of file