Sylvrec преди 4 години
ревизия
d03f2eef71

+ 63 - 0
.gitattributes

@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs     diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following 
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln       merge=binary
+#*.csproj    merge=binary
+#*.vbproj    merge=binary
+#*.vcxproj   merge=binary
+#*.vcproj    merge=binary
+#*.dbproj    merge=binary
+#*.fsproj    merge=binary
+#*.lsproj    merge=binary
+#*.wixproj   merge=binary
+#*.modelproj merge=binary
+#*.sqlproj   merge=binary
+#*.wwaproj   merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg   binary
+#*.png   binary
+#*.gif   binary
+
+###############################################################################
+# diff behavior for common document formats
+# 
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the 
+# entries below.
+###############################################################################
+#*.doc   diff=astextplain
+#*.DOC   diff=astextplain
+#*.docx  diff=astextplain
+#*.DOCX  diff=astextplain
+#*.dot   diff=astextplain
+#*.DOT   diff=astextplain
+#*.pdf   diff=astextplain
+#*.PDF   diff=astextplain
+#*.rtf   diff=astextplain
+#*.RTF   diff=astextplain

+ 363 - 0
.gitignore

@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd

+ 17 - 0
MyClasses/FileProcess.cs

@@ -0,0 +1,17 @@
+using System;
+using System.IO;
+
+namespace MyClasses
+{
+    public class FileProcess
+    {
+        public bool FileExists(string fileName)
+        {
+            if (string.IsNullOrEmpty(fileName))
+            {
+                throw new ArgumentNullException("filename");
+            }
+            return File.Exists(fileName);
+        }
+    }
+}

+ 7 - 0
MyClasses/MyClasses.csproj

@@ -0,0 +1,7 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+</Project>

+ 31 - 0
MyClasses/MyClasses.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31702.278
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyClasses", "MyClasses.csproj", "{137C59BA-8393-4DF1-8A69-553038E3F7AC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyClassesTest", "..\MyClassesTest\MyClassesTest.csproj", "{6D09E872-E621-4F7B-9376-E3EC980D3CA6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{137C59BA-8393-4DF1-8A69-553038E3F7AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{137C59BA-8393-4DF1-8A69-553038E3F7AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{137C59BA-8393-4DF1-8A69-553038E3F7AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{137C59BA-8393-4DF1-8A69-553038E3F7AC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6D09E872-E621-4F7B-9376-E3EC980D3CA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6D09E872-E621-4F7B-9376-E3EC980D3CA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6D09E872-E621-4F7B-9376-E3EC980D3CA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6D09E872-E621-4F7B-9376-E3EC980D3CA6}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {AFC4962B-C8B7-445E-B33F-12A47ACDC369}
+	EndGlobalSection
+EndGlobal

+ 13 - 0
MyClasses/PersonClasses/Employee.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClasses.PersonClasses
+{
+    public class Employee : Person
+    {
+        
+    }
+}

+ 15 - 0
MyClasses/PersonClasses/Person.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClasses.PersonClasses
+{
+    public class Person
+    {
+        public string FirstName { get; set; }
+        public string LastName { get; set; }
+
+    }
+}

+ 92 - 0
MyClasses/PersonClasses/PersonManager.cs

@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClasses.PersonClasses
+{
+    public class PersonManager
+    {
+        public Person CreatePerson(string first,
+                                   string last,
+                                   bool isSupervisor)
+        {
+            Person ret = null;
+            if (!string.IsNullOrEmpty(first))
+            {
+                if (isSupervisor)
+                {
+                    ret = new Supervisor();
+                }
+                else
+                {
+                    ret = new Employee();
+                }
+
+                // Assign variables
+                ret.FirstName = first;
+                ret.LastName = last;
+            }
+            return ret;
+        }
+
+        /// <summary>
+        /// This method simulates retrieving a list of Person object
+        /// </summary>
+        /// <returns>A collection of Person objets</returns>
+       public List<Person> GetPeople()
+        {
+            List<Person> people = new List<Person>();
+
+            people.Add(new Person() { FirstName = "Paul", LastName = "Sheriff" });
+            people.Add(new Person() { FirstName = "John", LastName = "Kuhn" });
+            people.Add(new Person() { FirstName = "Jim", LastName = "Rulh" });
+
+            return people;
+        }
+
+        /// <summary>
+        /// This method simulate retieving a list of Supervisor object
+        /// </summary>
+        /// <returns>A collection of Supervisor objects</returns>
+        public List<Person> GetSupervisors()
+        {
+            List<Person> people = new List<Person>();
+
+            people.Add(CreatePerson("Paul", "Sheriff", true));
+            people.Add(CreatePerson("Michael", "Krasowski", true));
+
+            return people;
+        }
+
+        /// <summary>
+        /// This method simulates retrieving a list of Employee object
+        /// </summary>
+        /// <returns>A collection of Persons objects</returns>
+        public List<Person> GetEmployees()
+        {
+            List<Person> people = new List<Person>();
+
+            people.Add(CreatePerson("Steve", "Nystrom", false));
+            people.Add(CreatePerson("John", "Kuhn", false));
+            people.Add(CreatePerson("Jim", "Rulh", false));
+
+            return people;
+        }
+
+        /// <summary>
+        /// This method simulates retrieving a list of Supervisor and Employee object
+        /// </summary>
+        /// <returns>A collection of Supervisor and Employee objects</returns>
+        public List<Person> GetSupervisorAndEmployees()
+        {
+            List<Person> people = new List<Person>();
+
+            people.AddRange(GetEmployees());
+            people.AddRange(GetSupervisors());
+
+            return people;
+        }
+    }
+}

+ 13 - 0
MyClasses/PersonClasses/Supervisor.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClasses.PersonClasses
+{
+    public class Supervisor : Person
+    {
+        public List<Employee> Employees { get; set; }
+    }
+}

+ 93 - 0
MyClassesTest/CollectionAssertClassTest.cs

@@ -0,0 +1,93 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MyClasses.PersonClasses;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class CollectionAssertClassTest : TestBase
+    {
+        [TestMethod]
+        public void AreCollectionsEqualWithComparerTest()
+        {
+            PersonManager mgr = new PersonManager();
+            List<Person> peopleExpected = new List<Person>();
+            List<Person> peopleActual;
+
+            peopleExpected.Add(new Person() { FirstName = "Paul", LastName = "Sheriff" });
+            peopleExpected.Add(new Person() { FirstName = "John", LastName = "Kuhn" });
+            peopleExpected.Add(new Person() { FirstName = "Jim", LastName = "Rulh" });
+
+            peopleActual = mgr.GetPeople();
+
+            // Note : By default it compares the person objects to see if they are Equal (the
+            CollectionAssert.AreEqual(peopleExpected, peopleActual,
+                Comparer<Person>.Create((x, y) => x.FirstName == y.FirstName && x.LastName == y.LastName ? 0 : 1));
+        }
+
+        [TestMethod]
+        public void AreCollectionsEquivalentTest()
+        {
+            PersonManager mgr = new PersonManager();
+            List<Person> peopleExpected = new List<Person>();
+            List<Person> peopleActual;
+
+            // Get Person objects
+            peopleActual = mgr.GetPeople();
+
+            // Add same Person objects to new collection, but in a different order
+            peopleExpected.Add(peopleActual[1]);
+            peopleExpected.Add(peopleActual[2]);
+            peopleExpected.Add(peopleActual[0]);
+
+            CollectionAssert.AreEquivalent(peopleExpected, peopleActual);
+
+        }
+
+        [TestMethod]
+        public void IsCollectionOfTypeTest()
+        {
+            PersonManager mgr = new PersonManager();
+            List<Person> peopleActual = new List<Person>();
+
+            peopleActual = mgr.GetSupervisors();
+
+            CollectionAssert.AllItemsAreInstancesOfType(peopleActual, typeof(Supervisor));
+        }
+
+        [TestMethod]
+        public void AreCollectionsEqualTest()
+        {
+            PersonManager mgr = new PersonManager();
+            List<Person> peopleExpected = new List<Person>();
+            List<Person> peopleActual = new List<Person>();
+
+            peopleActual = mgr.GetPeople();
+            peopleExpected = peopleActual;
+
+            // Note : By default it compares the person objects to see if they are Equal (the
+            CollectionAssert.AreEqual(peopleExpected, peopleActual);
+        }
+
+        //[TestMethod]
+        public void AreCollectionsEqual()
+        {
+            PersonManager mgr = new PersonManager();
+            List<Person> peopleExpected = new List<Person>();
+            List<Person> peopleActual = new List<Person>();
+
+            peopleExpected.Add(new Person() { FirstName = "Paul", LastName = "Sheriff" });
+            peopleExpected.Add(new Person() { FirstName = "John", LastName = "Kuhn" });
+            peopleExpected.Add(new Person() { FirstName = "Jim", LastName = "Rulh" });
+
+            peopleActual = mgr.GetPeople();
+
+            // Note : By default it compares the person objects to see if they are Equal (the
+            CollectionAssert.AreEqual(peopleExpected, peopleActual);
+        }
+    }
+}

+ 76 - 0
MyClassesTest/FileProcessDataDriven.cs

@@ -0,0 +1,76 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MyClasses;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class FileProcessDataDriven : TestBase
+    {
+        [TestMethod]
+        public void FileExistsTestFromDB()
+        {
+            FileProcess fp = new FileProcess();
+            bool fromCall = false;
+            bool testFailed = false;
+            string fileName;
+            bool expectedValue;
+            bool causesException;
+            string sql = "SELECT * FROM tests.FileProcessTest";
+            string conn = TestContext.Properties["ConnectionString"].ToString();
+
+            // Load data from SQL server table
+            TestDataTable = LoadDataTable(sql, conn);
+
+            if (TestDataTable != null)
+            {
+                // Loop throught all row in table
+                foreach (DataRow row in TestDataTable.Rows)
+                {
+                    // Get values from data row
+                    fileName = row["FileName"].ToString();
+                    expectedValue = Convert.ToBoolean(row["ExpectedValue"]);
+                    causesException = Convert.ToBoolean(row["CausesException"]);
+
+                    try
+                    {
+                        //See if file exists
+                        fromCall = fp.FileExists(fileName);
+                    } 
+                    catch (ArgumentNullException)
+                    {
+                        // See if a null value was expected
+                        if (!causesException)
+                        {
+                            testFailed = true;
+                        }
+                    } 
+                    catch (Exception)
+                    {
+                        testFailed = true;
+                    }
+                    TestContext.WriteLine("Testing File: '{0}', Expected Value: '{1}', Actual Value: '{2}', Result: '{3}'", fileName, expectedValue, fromCall, (expectedValue == fromCall ? "Success" : "FAILED"));
+
+                    // Check assertion
+                    if (expectedValue != fromCall)
+                    {
+                        testFailed = true;
+                    }
+                }
+                if (testFailed)
+                {
+                    Assert.Fail("Data Driven Tests Have Failed, Check Additional Output for More Information.");
+                }
+            }
+            else
+            {
+                Assert.Fail("Something in the connection to DB.");
+            }
+        }
+    }
+}

+ 104 - 0
MyClassesTest/FileProcessOtherTest.cs

@@ -0,0 +1,104 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MyClasses;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class FileProcessOtherTest : TestBase
+    {
+        #region  Class Initialize and Cleanup Method
+        [ClassInitialize]
+        public static void InitializeClass(TestContext tc)
+        {
+            tc.WriteLine("In ClassInitialize() method");
+        }
+
+        [ClassCleanup]
+        public static void CleanUpClass()
+        {
+
+        }
+        #endregion
+
+        #region TestInitialize Method
+        [TestInitialize]
+        public void InitializeMethod()
+        {
+            TestContext.WriteLine("In TestInitialize() method");
+            WriteDescription(this.GetType()); // <-- See TestBase
+            if (TestContext.TestName.StartsWith("FileNameDoesExist"))
+            {
+                SetGoodFileName();
+                if (!string.IsNullOrEmpty(_goodFileName))
+                {
+                    TestContext.WriteLine("Creating file: " + _goodFileName);
+                    // Create the 'Good' file
+                    File.AppendAllText(_goodFileName, "Some Text");
+                }
+            }
+        }
+        #endregion
+        
+        #region TestCleanUp Method
+        [TestCleanup]
+        public void CleanUpMethod()
+        {
+            TestContext.WriteLine("In TestCleanup() method");
+            if (TestContext.TestName.StartsWith("FileNameDoesExist"))
+            {
+                // Delete File
+                if (File.Exists(_goodFileName))
+                {
+                    TestContext.WriteLine("Deleting file: " + _goodFileName);
+                    File.Delete(_goodFileName);
+                }
+            }
+        }
+        #endregion
+
+        [TestMethod]
+        public void AreSameTest()
+        {
+            FileProcess x = new FileProcess();
+            FileProcess y = new FileProcess();
+
+            Assert.AreNotSame(x, y);
+        }
+
+        [TestMethod]
+        public void AreEqualTest()
+        {
+            string str1 = "Paul";
+            string str2 = "paul";
+
+            Assert.AreEqual(str1, str2, true);
+        }
+
+        [TestMethod]
+        public void AreNotEqualTest()
+        {
+            string str1 = "Paul";
+            string str2 = "John";
+
+            Assert.AreNotEqual(str1, str2);
+        }
+
+        //[TestMethod]
+        public void FileNameDoesExistsSimpleMessage()
+        {
+            FileProcess fp = new FileProcess();
+            bool fromCall;
+
+            fromCall = fp.FileExists(_goodFileName);
+
+            Assert.IsFalse(fromCall,
+                "File {0} Does Not Exist.", _goodFileName);
+        }
+    }
+}

+ 158 - 0
MyClassesTest/FileProcessTest.cs

@@ -0,0 +1,158 @@
+using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MyClasses;
+using System;
+using System.IO;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class FileProcessTest : TestBase
+    {
+        private const string BAD_FILE_NAME = @"C:\NotExists.bad";
+
+        [ClassInitialize()]
+        public static void ClassInitialize(TestContext tc)
+        {
+            // TODO Initialize for all tests in class
+            tc.WriteLine("In ClassInitialize() method");
+        }
+
+        [ClassCleanup()]
+        public static void ClassCleanup()
+        {
+            // TODO Cleanup after all test in class
+        }
+
+        [TestInitialize]
+        public void TestInitialize()
+        {
+            TestContext.WriteLine("In TestInitialize() method");
+            WriteDescription(this.GetType()); // <-- See TestBase
+            if (TestContext.TestName.StartsWith("FileNameDoesExist"))
+            {
+                SetGoodFileName();
+                if (!string.IsNullOrEmpty(_goodFileName))
+                {
+                    TestContext.WriteLine("Creating file: " + _goodFileName);
+                    // Create the 'Good' file
+                    File.AppendAllText(_goodFileName, "Some Text");
+                }
+            }
+        }
+
+        [TestCleanup]
+        public void TestCleanup()
+        {
+            TestContext.WriteLine("In TestCleanup() method");
+            if (TestContext.TestName.StartsWith("FileNameDoesExist"))
+            {
+                // Delete File
+                if (File.Exists(_goodFileName))
+                {
+                    TestContext.WriteLine("Deleting file: " + _goodFileName);
+                    File.Delete(_goodFileName);
+                }
+            }
+        }
+
+        [TestMethod]
+        [DataRow(1, 1, DisplayName = "First Test (1,1)")]
+        [DataRow(42, 42, DisplayName = "Second Test (42,42)")]
+        public void AreNumbersEqual(int num1, int num2)
+        {
+            Assert.AreEqual(num1, num2);
+        }
+
+        [TestMethod]
+        [DeploymentItem("FileToDeploy.txt")]
+        [DataRow(@"C:\Windows\Regedit.exe", DisplayName = "Regedit.exe")]
+        [DataRow("FileToDeploy.txt", DisplayName = "Deployment Item: FileToDeploy.txt")]
+        public void FileNameUsingDataRow(string fileName)
+        {
+            FileProcess fp = new FileProcess();
+            bool fromCall;
+
+            if (!fileName.Contains(@"\"))
+            {
+                fileName = TestContext.DeploymentDirectory + @"\" + fileName;
+            }
+            TestContext.WriteLine("Checking File " + fileName);
+            fromCall = fp.FileExists(fileName);
+            Assert.IsTrue(fromCall);
+        }
+
+        [TestMethod]
+        [Description("Check to see if a file exists.")]
+        [Owner("Sylvain")]
+        [Priority(1)]
+        [TestCategory("NoException")]
+        //[Ignore]
+        public void FileNameDoesExist()
+        {
+            FileProcess fp = new FileProcess();
+            bool fromCall;
+
+            TestContext.WriteLine(@"Checking File " + _goodFileName);
+
+            fromCall = fp.FileExists(_goodFileName);
+
+            Assert.IsTrue(fromCall);
+        }
+
+        //[TestMethod]
+        [Timeout(4000)]
+        public void SimulateTimeout()
+        {
+            System.Threading.Thread.Sleep(200);
+        }
+
+        [TestMethod]
+        [Description("Check to see if a file does not exists.")]
+        [Owner("Sylvain")]
+        [Priority(1)]
+        [TestCategory("NoException")]
+        public void FileNameDoesNotExist()
+        {
+            FileProcess fp = new FileProcess();
+            bool fromCall;
+            TestContext.WriteLine(@"Checking File " + BAD_FILE_NAME);
+            fromCall = fp.FileExists(BAD_FILE_NAME);
+            Assert.IsFalse(fromCall);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        [Description("Check for a throw ArgumentNullException using ExceptedException.")]
+        [Owner("Sylvain")]
+        [Priority(2)]
+        [TestCategory("Exception")]
+        public void FileNameNullOrEmpty_UsingAttribute()
+        {
+            FileProcess fp = new FileProcess();
+            fp.FileExists("");
+        }
+
+        [TestMethod]
+        [Description("Check for a throw ArgumentNullException using try...catch.")]
+        [Owner("Sylvain")]
+        [Priority(2)]
+        [TestCategory("Exception")]
+        public void FileNameNullOrEmpty_UsingTryCatch()
+        {
+            FileProcess fp = new FileProcess();
+
+            try
+            {
+                fp.FileExists("");
+            }
+            catch (ArgumentNullException)
+            {
+                // Test was a success
+                return;
+            }
+            // Fail the test
+            Assert.Fail("Call to FileExists() dit NOT throw an ArgumentNullException.");
+        }
+    }
+}

+ 1 - 0
MyClassesTest/FileToDeploy.txt

@@ -0,0 +1 @@
+Some text

+ 10 - 0
MyClassesTest/MyClasses.runsettings

@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='utf-8'?>
+<RunSettings>
+	<TestRunParameters>
+		<Parameter name="GoodFileName"
+			value="[AppPath]\TestFile.txt" />
+    <Parameter name="ConnectionString" 
+               value="Server=DESKTOP-GS6C5S7;Database=Sandbox;Integrated Security=Yes" />
+
+  </TestRunParameters>
+</RunSettings>

+ 27 - 0
MyClassesTest/MyClassesTest.csproj

@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
+    <PackageReference Include="coverlet.collector" Version="3.0.2" />
+    <PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\MyClasses\MyClasses.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="FileToDeploy.txt">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+</Project>

+ 28 - 0
MyClassesTest/MyClassesTestInitialization.cs

@@ -0,0 +1,28 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class MyClassesTestInitialization
+    {
+        [AssemblyInitialize()]
+        public static void AssemblyInitialize(TestContext tc)
+        {
+            // TODO Initialize for all test within an assembly
+            tc.WriteLine("In AssemblyInitialize() method");
+        }
+
+        [AssemblyCleanup()]
+        public static void AssemblyCleanup()
+        {
+            // TODO : Clean up after all
+            // test in an assembly
+
+        }
+    }
+}

+ 49 - 0
MyClassesTest/PersonTest.cs

@@ -0,0 +1,49 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MyClasses.PersonClasses;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class PersonTest : TestBase
+    {
+        #region Initialize and Cleanup class Test
+        [ClassInitialize]
+        public static void InitializeClass(TestContext tc)
+        {
+
+        }
+
+        [ClassCleanup]
+        public static void CleanUpClass()
+        {
+
+        }
+        #endregion
+
+        [TestMethod]
+        public void IsNullTest()
+        {
+            PersonManager mgr = new PersonManager();
+            Person per;
+
+            per = mgr.CreatePerson("", "Sheriff", true);
+
+            Assert.IsNull(per);
+        }
+
+        [TestMethod]
+        public void IsIntanceOfTypeTest()
+        {
+            PersonManager mgr = new PersonManager();
+            Person per;
+
+            per = mgr.CreatePerson("Paul", "Sheriff", true);
+            Assert.IsInstanceOfType(per, typeof(Supervisor));
+        }
+    }
+}

+ 46 - 0
MyClassesTest/StringAssertClassTest.cs

@@ -0,0 +1,46 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    [TestClass]
+    public class StringAssertClassTest : TestBase
+    {
+        [TestMethod]
+        public void ContainsTest()
+        {
+            string str1 = "Steve Nystrom";
+            string str2 = "Nystrom";
+
+            StringAssert.Contains(str1, str2);
+        }
+        
+        [TestMethod]
+        public void StartsWithTest()
+        {
+            string str1 = "All Lower Case";
+            string str2 = "All Lower";
+
+            StringAssert.StartsWith(str1, str2);
+        }
+
+        [TestMethod]
+        public void IsAllLowerCaseTest()
+        {
+            Regex r = new(@"^([^A-Z])+$");
+            StringAssert.Matches("all lower case", r);
+        }
+
+        //[TestMethod]
+        public void IsNotAllLowerCaseTest()
+        {
+            Regex re = new(@"^([^A-Z])+$");
+            StringAssert.Matches("ALL LOWER CASE", re);
+        }
+    }
+}

+ 81 - 0
MyClassesTest/TestBase.cs

@@ -0,0 +1,81 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MyClassesTest
+{
+    public class TestBase
+    {
+        public TestContext TestContext { get; set; }
+        public DataTable TestDataTable { get; set; }
+
+        protected string _goodFileName;
+
+        protected void SetGoodFileName()
+        {
+            _goodFileName = TestContext.Properties["GoodFileName"].ToString();
+            if (_goodFileName.Contains("[AppPath]"))
+            {
+                _goodFileName = _goodFileName.Replace("[AppPath]",
+                    Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
+            }
+        }
+
+        protected void WriteDescription(Type type)
+        {
+            string testName = TestContext.TestName;
+            // Find the test method currently executing
+            MemberInfo method = type.GetMethod(testName);
+            if (method != null)
+            {
+                // See if the [Description] attribute exists on this test
+                Attribute attr = method.GetCustomAttribute(
+                    typeof(DescriptionAttribute));
+                if (attr != null)
+                {
+                    // Cast the attribute to a DescriptionAttribute
+                    DescriptionAttribute dattr = (DescriptionAttribute)attr;
+                    // Display the test description
+                    TestContext.WriteLine("Test Description: " + dattr.Description);
+                }
+            }
+        }
+
+        public DataTable LoadDataTable(string sql, string connection)
+        {
+            TestDataTable = null;
+
+            try
+            {
+                // Create connection
+                using (SqlConnection connectionObject = new SqlConnection(connection))
+                {
+                    // Create command object
+                    using (SqlCommand commandObject = new SqlCommand(sql, connectionObject))
+                    {
+                        // Create a SQL Data Adapter
+                        using (SqlDataAdapter da = new SqlDataAdapter(commandObject))
+                        {
+                            TestDataTable = new DataTable();
+                            da.Fill(TestDataTable);
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                TestContext.WriteLine("Error in LoadDataTable() method." + Environment.NewLine + ex.Message);
+                return null;
+            }
+            return TestDataTable;
+        }
+
+
+    }
+}

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+
+Implementing C# Unit Testing Using Visual Studio 2019 and .NET 5
+by Paul D. Sheriff
+
+Learn how to start unit testing to improve the quality of your applications.
+
+https://app.pluralsight.com/library/courses/basic-unit-testing-csharp-developers/table-of-contents

+ 19 - 0
SQLQuery.sql

@@ -0,0 +1,19 @@
+CREATE SCHEMA tests
+GO
+
+CREATE TABLE tests.FileProcessTest
+(
+	FileName varchar(255) NULL,
+	ExpectedValue [bit] NOT NULL,
+	CausesException [bit] NOT NULL
+)
+GO
+
+INSERT INTO tests.FileProcessTest
+VALUES ('C:\Windows\Regedit.exe', 1, 0);
+
+INSERT INTO tests.FileProcessTest
+VALUES ('C:\BadFileName.txt', 0, 0);
+
+INSERT INTO tests.FileProcessTest
+VALUES (null, 0, 1);