diff --git a/Testing/Basic/Basic.sln b/Testing/Basic/Basic.sln new file mode 100644 index 0000000..0f7d475 --- /dev/null +++ b/Testing/Basic/Basic.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basic", "Basic.csproj", "{A2273AC7-A230-490E-ABB9-18E9039DE58F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A2273AC7-A230-490E-ABB9-18E9039DE58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2273AC7-A230-490E-ABB9-18E9039DE58F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2273AC7-A230-490E-ABB9-18E9039DE58F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2273AC7-A230-490E-ABB9-18E9039DE58F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0DA2FAD1-3453-416E-82CA-467B313E273B} + EndGlobalSection +EndGlobal diff --git a/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs b/Testing/Basic/Homework/1. ObjectComparison/ObjectComparison.cs index d544c47..1336281 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; @@ -14,16 +15,8 @@ public void CheckCurrentTsar() var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, 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(x => x.DeclaringType == typeof(Person) && x.Name == "Id")); } [Test] @@ -33,11 +26,25 @@ public void CheckCurrentTsar_WithCustomEquality() var actualTsar = TsarRegistry.GetCurrentTsar(); var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, new Person("Vasili III of Russia", 28, 170, 60, null)); - - // Какие недостатки у такого подхода? ClassicAssert.True(AreEqual(actualTsar, expectedTsar)); } + // Недостатки этого подхода: + // 1) Нечитаемость, так как логика скрыта в методе AreEqual, + // сторонний наблюдатель из теста даже не поймет, что Id в сравнении не учитывается, + // пока не провалится в метод + // + сам ClassicAssert плохо читается в сравнении с FluentAssertion + // + // 2) Не расширяемый: при добавлении новых полей и свойств нужно будет править этот метод, + // тесты будут выполняться неверно + // + // 3) Повторяющийся код сравнения свойств, выглядит не очень + // + // 4) Кода в таком подходе в несколько раз больше, чем в первом тесте + // + // Код с использованием FluentAssertion максимально читаемый + // (мы сразу видим, какие свойства исключаются при сравнении), + // гибкий и расширяемый, а также достаточно короткий. private bool AreEqual(Person? actual, Person? expected) { if (actual == expected) return true; diff --git a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs index 950c9bc..b354cf0 100644 --- a/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs +++ b/Testing/Basic/Homework/2. NumberValidator/NumberValidatorTests.cs @@ -1,31 +1,44 @@ - -using NUnit.Framework; -using NUnit.Framework.Legacy; +using NUnit.Framework; +using FluentAssertions; namespace HomeExercise.Tasks.NumberValidator; [TestFixture] public class NumberValidatorTests { - [Test] - public void Test() + [TestCase(-1, 0, TestName = "NegativePrecision")] + [TestCase(0, 0, TestName = "ZeroPrecision")] + [TestCase(1, -1, TestName = "NegativeScale")] + [TestCase(1, 2, TestName = "ScaleGreraterThenPrecision")] + public void ValidateConstructor_ThrowsException_WithUncorrectData(int precision, int scale) { - 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)); + Action action = () => new NumberValidator(precision, scale); + action.Should().Throw(); + } - 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")); + [TestCase(2, 1, TestName = "CorrectData")] + [TestCase(1, 0, TestName = "CorrectDataWithZeroScope")] + public void ValidateConstructor_DontThrowsException_WithCorrectData(int precision, int scale) + { + Action action = () => new NumberValidator(precision, scale); + action.Should().NotThrow(); + } + + [TestCase("0.0", true, true, TestName = "SimpleCorrectValueWithPoint")] + [TestCase("0,0", true, true, TestName = "SimpleCorrectValueWithComma")] + [TestCase("0", true, true, TestName = "SimpleDataWithoutValue")] + [TestCase("0.0", true, true, TestName = "SimpleCorrectValue")] + [TestCase("000.00", true, false, TestName = "TooMuchNumbers")] + [TestCase("0.000", true, false, TestName = "BigFracPart")] + [TestCase("-0.0", true, false, TestName = "NegativeValueForPositiveValidator")] + [TestCase("-0.0", false, true, TestName = "NegativeValueForNegativeValidator")] + [TestCase("+0.000", true, false, TestName = "PlusMustIncludeInPrecision")] + [TestCase("a.asd", true, false, TestName = "UncorrectValue")] + [TestCase("", true, false, TestName = "EmptyValue")] + [TestCase(null, true, false, TestName = "NullValue")] + public void Validator_IsValidate(string value, bool onlyPositive, bool expectedResult) + { + var validatorResult = new NumberValidator(4, 2, onlyPositive).IsValidNumber(value); + validatorResult.Should().Be(expectedResult, $"Проверка числа { value } для валидатора (4, 2, {onlyPositive})"); } } \ No newline at end of file