Test Unit Programming |
The following topics descriptive the code pattern of test unit and test case with Microsoft.VisualStudio.QualityTools.UnitTestFramework and SIC.Test.Helper.
Uses assembly SIC.Test.Helper for programming test units.
This topic contains the following sections:
A test project can creates by project template
This it's base for adding any test units.
Test project create base folder structure and puts references.
An example of test project into solution explorer window
A Test Unit can creates by project item template
An example of test unit
using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SIC.Test.Helper.Test { // UNDONE: next step: edit comment and rename file/class name (syntax: ProjectNameTestClassName) /// <summary> /// Test unit for /// </summary> /// <remarks> /// Requirement: none<para /> /// External Data: none<para /> /// Details about base test unit see <see cref="SIC.Test.Helper.TestUnit"/> /// </remarks> /// <seealso cref="SIC.Test.Helper"/> /// <seealso cref="SIC.Test.Helper.TestUnit"/> /// <seealso cref="SIC.Test.Helper.Directory"/> /// <seealso cref="SIC.Test.Helper.Print"/> /// <seealso cref="SIC.Test.Helper.Log"/> /// <seealso cref="SIC.Test.Helper.Session"/> [TestClass()] public class SOWITestUnit1 : SIC.Test.Helper.TestUnit { #region --- test initialize --- /// <summary> /// Test directories setting /// </summary> protected override void OnDirectorySetting() { // TOSET: Test Environment (directories) this.DirectorySetting( pDataRedirecting: @"C:\Work\Data\", pDataRedirect: false, //* regular to project directory + Data * pResultRedirecting: @"C:\Work\", //* if empty then to project directory + Result * pResultRedirect: false); } /// <summary> /// Test session setting /// Note: object Directory and Log is available. /// </summary> protected override void OnSessionSetting() { // UNDONE: next step: Needed? Yes, implement logic. No, delete this task. base.OnSessionSetting(); } /// <summary> /// Test initialize for test environment settings. /// Note: object Directory and Log is available. /// </summary> protected override void OnTestInitialize() { // UNDONE: next step: Needed? Yes, implement logic. No, delete this task. base.OnTestInitialize(); } #endregion #region --- test clean up --- /// <summary> /// Test clean up /// </summary> protected override void OnTestCleanup() { // UNDONE: next step: Needed? Yes, implement logic. No, delete this task. base.OnTestCleanup(); } #endregion #region --- test object --- #endregion #region --- test case --- // UNDONE: next step: implement test cases (code snippet scsTestCase) #endregion } }
For more information see (sorted A-Z)
Session token will uses for SOWI Management handling with a SOWI Config file (.sconfig). Uses for Win application or for App modules. Usage for Web application see WebHost.
This example puts a test unit session token
/// <summary> /// Test session setting /// Note: object Directory and Log is available. /// </summary> protected override void OnSessionSetting() { // TOSET: login for session this.SessionSetting("UserName", "Password"); //base.OnSessionSetting(); //* without session token * }
When there are several test cases that need a session, it is recommended to store the properties (user name and his password) as project properties. This properties already exist in a SOWI Test Project (Template)
This example puts a test unit session token about project properties TestUnitSessionSetting (assembly by entry attribute, see also SICEntryAssemblyAttribute)
this.SessionSetting();
The Session Token can be using for test case with the property TestUnitSessionToken
This example create a test object SOWIAppStandard for test case with SOWI Management handling
lSOWIAppStandard = new SOWIApp.Foundation.Test.TestObject.SOWIAppStandard(this.SessionToken);
This example puts a web host HTTP context object.
Call from SIC.Test.Helper.WebHost method Create(String). This create a web host
/// <summary> /// Test session setting /// Note: object Directory and Log is available. /// </summary> protected override void OnSessionSetting() { SIC.Test.Helper.WebHost.Create(); //* created a HTTP context object * //base.OnSessionSetting(); //* without session token * }
When useage web application with SOWI Web Standard Controller then to login with SOWI Web Helper Session Login method
/// <summary> /// Test session setting /// Note: object Directory and Log is available. /// </summary> protected override void OnSessionSetting() { SIC.Test.Helper.WebHost.Create(); //* created a HTTP context object * SOWIWeb.Helper.Session.LogIn(Properties.Settings.Default.UserName, Properties.Settings.Default.UserPassword); //base.OnSessionSetting(); //* without session token * }
1. Create a test case with code snippet "scsTestCase"
2. The code snippet writes following code
3. Fill input fields
What does this test case tests?
Write text in test case header code comment.
Write a short description.
Important: make link to method what tests because his method comment has a detail description about function.
4. Go to the task tokens UNDONE
Important |
---|
Note about test stop watch: does not logs between method TestStart and TestEnd because it distorts the test duration. |
Tip |
---|
Writes a task token //TOSET for changes values e.g. to 0 for a flawed test result |
Tip |
---|
Can use \t as a tabulator |
Tip |
---|
Using code snippets: |
/// <summary> /// Test case for ... <br /> /// (ToDo: past method summary what tests) /// </summary> /// <remarks> /// Requirement: none<para /> /// External Data: none /// </remarks> /// <seealso cref="reference what does this test case tests?"/> [TestCategory("Test category not defined")] [TestMethod] public void TestProjectClassMethodParameter() { SIC.Test.Helper.Print.WriteSectionLine(); //* section line (only Debug window) * this.Log.Write(this.Log.Name); //* start test log writes to Debug window and to protocol file * #region --- Preparation --- this.Log.WriteTitle("TEST PREPARATION"); this.Log.Write("Test variable..."); // UNDONE: next step: definie test values and the correct result values (example: int lValueA = 10; int lResultCorrect = 3;) //--- // TOSET: test values and correct result values //--- //* protocol test preparation * // UNDONE: next step: definie the protocol test preparation (example: this.Log.Write("Value A", lValueA.ToString());) this.Log.Write("Test prepared"); #endregion #region --- Execution --- this.Log.WriteTitle("TEST EXECUTION"); // UNDONE: next step: log test case code (example: this.Log.Write("Calculation A / B...");) this.Log.TestStart(); try { // UNDONE: next step: implement test case code (example: lResult = lValueA / lValueB;) } catch (Exception ex) { this.Log.IsTrue(ref ex); } this.Log.TestEnd(); //* protocol test execution * // UNDONE: next step: definie the protocol test execution (example: this.Log.Write("Result ", lResult.ToString());) this.Log.Write("Test executed"); #endregion #region --- Analysis --- this.Log.WriteTitle("TEST ANALYSIS"); //* conditions * // UNDONE: next step: definie the test analysis (example: this.Log.IsTrue((lResultCorrect == lResult), "The result should be " + lResultCorrect.ToString(), "The result is correct");) this.Log.IsTrue(false, "No conditions"); //* write result of conditions * this.Log.Result(); #endregion }
Test Case Example
/// <summary> /// Test case for arithmetic addition /// </summary> /// <remarks> /// Requirement: none<para /> /// External Data: none /// </remarks> [TestCategory("SOWI Testing")] [TestMethod] public void TestArithmeticAddition() { SIC.Test.Helper.Print.WriteSectionLine(); //* section line (only Debug window) * this.Log.Write(this.Log.Name); //* start test log writes to Debug window and to protocol file * #region --- Preparation --- this.Log.WriteTitle("TEST PREPARATION"); this.Log.Write("Test variable..."); //--- // TOSET: test values int lValueA = 10; //* Test with a wrong result. Change value in lValueB to a other number. Comment or uncomment next line. * int lValueB = 5; //lValueB = 3; int lResultCorrect = 15; //--- int lResult = -1; //* protocol test preparation * this.Log.Write("Value A", lValueA.ToString()); this.Log.Write("Value B", lValueB.ToString()); this.Log.Write("Correct result ", lResultCorrect.ToString()); this.Log.Write("Test prepared"); #endregion #region --- Execution --- this.Log.WriteTitle("TEST EXECUTION"); this.Log.Write("Calculation A + B..."); this.Log.TestStart(); try { lResult = lValueA + lValueB; } catch (Exception ex) { this.Log.IsTrue(ref ex); } this.Log.TestEnd(); //* protocol test execution * this.Log.Write("Result ", lResult.ToString()); this.Log.Write("Test executed"); #endregion #region --- Analysis --- this.Log.WriteTitle("TEST ANALYSIS"); //* conditions * this.Log.IsTrue((lResultCorrect == lResult), "The result should be " + lResultCorrect.ToString(), "The result is correct"); //* write result of conditions * this.Log.Result(); #endregion }
Test case output
If it's required then implement this code pattern.
Note: below objects isn't available: TestContext, Directory, Log, Session
/// <summary> /// Test assembly initialize /// </summary> /// <remarks>Some objects isn't available (Directory, Log, Session)</remarks> /// <param name="pTestContext">Test context object properties because the class TestContext object isn't available</param> [AssemblyInitialize()] public static void AssemblyInitialize(TestContext pTestContext) { SIC.Test.Helper.Print.WriteSection(System.Reflection.MethodBase.GetCurrentMethod().Name.ToString()); }
If it's required then implement this code pattern.
Note: below objects isn't available: Directory, Log, Session
/// <summary> /// Test class initialize /// </summary> /// <remarks>Some objects isn't available (Directory, Log, Session)</remarks> /// <param name="pTestContext">Test context object properties because the class TestContext object isn't available</param> [ClassInitialize()] public static void ClassInitialize(TestContext pTestContext) { SIC.Test.Helper.Print.WriteSection(System.Reflection.MethodBase.GetCurrentMethod().Name.ToString()); }
If it's required then implement this code pattern.
Note: below objects isn't available: TestContext, Directory, Log, Session
/// <summary> /// Test class (test unit) clean up /// </summary> /// <remarks>Some objects isn't available (TestContext, Directory, Log, Session)</remarks> [ClassCleanup()] public static void ClassCleanup() { SIC.Test.Helper.Print.WriteSection(System.Reflection.MethodBase.GetCurrentMethod().Name.ToString()); }
If it's required then implement this code pattern.
Note: below objects isn't available: TestContext, Directory, Log, Session
/// <summary> /// Test assembly (test unit) clean up /// </summary> /// <remarks>Some objects isn't available (TestContext, Directory, Log, Session)</remarks> [AssemblyCleanup()] public static void AssemblyCleanup() { SIC.Test.Helper.Print.WriteSection(System.Reflection.MethodBase.GetCurrentMethod().Name.ToString()); }