Software testing



- Reduce bugs by identifying all the use case scenarios to reflect intent (end user's mindset, business needs, expected functionality, and business validations, and so on).
- Less-and-less time on debugging.
- Avoid collateral damage, in other words, a fix in one area may break functionality in another possibly related/unrelated area.
- Helps you achieve YAGNI that is "You Aren't Gonna Need It". In other words, saves you from writing code functionality that you don't need.
But I am a Developer, Not a Tester
First, creating a Unit Test is the developer's responsibility. Agreed, developers are not testers and that is true of testers too. But thinking of the most common scenarios worth testing that might cause failure to your code functionality is all that you need to code in your Unit Tests.
Got it, but I don't have a Testing Mind Set
Not having a Testing Mind Set is actually a genuine issue and this happens because developers usually never think of testing their code until it's deployed to QA or production. To overcome this issue you must pair with a QA Engineer or Software Development Engineer in Test (SDET) in your team. You must write all the possible test areas that you think of and get it reviewed.
Career Tip: In today's software world, a unit testing skill is a major requirement for any developer, lead, or architect position.
Requirements for other types of testing as well
Do I need to do other types of testing as well? From a developer's point of view, the short and straight answer is no, but many teams and organizations require their developers to write even Integration, Load, and Stress Tests as well. A dedicated QA/Test team is usually responsible for doing a non-unit type of testing, whether it is manual or automated.
Career Tip: Educate yourself about other types of testing.
System Under Test (SUT)
System Under Test (SUT) is the system that will be tested by Unit Tests for code accuracy and possible scenarios that might either break the functionality at runtime or not produce legitimate results.
Assume you are working on a Bank Application's Business Logic (BankApplication.dll) and your code looks as in this:
- namespace BankApplication.Savings
- {
- public class Account
- {
- private double accountBalance = 0.00;
- private bool accountStatus = false;
- private enum Roles
- {
- Customer,
- Manager
- }
- public bool IsAccountActive(string accNumber)
- {
- return accountStatus;
- }
- public double Balance(string accNumber)
- {
- return accountBalance;
- }
- public double Deposit(string accNumber, double amount)
- {
- return accountBalance = accountBalance + amount;
- }
- public double Withdwral(string accNumber, double amount)
- {
- return accountBalance = accountBalance - amount;
- }
- private bool ActivateAccount(string accNumber, Roles userRole)
- {
- accountStatus = true;
- return accountStatus;
- }
- }
- }
- Empty or missing values (such as 0, "", or null).
- Inappropriate values that are not realistic from a business point of view, such as a person's age of -1 or 200 years or so.
- DOB is tomorrow's date or time in the future.
- Duplicates in lists that shouldn't have duplicates.
- The password is the same as either First name or Last name
- Special characters or case related conditions.
- Formatting of data, for example, the name must be capitalized. For example Vidya Vrat, Agarwal.
- Type of acceptable values in a field. For example, the name can't hold a numeric, and age can't hold letters.
- Range is another critical thing to test and it's often coded as business validation rules.
Error Conditions
Building a real-world application causes real-world errors at run-time and errors do happen. Hence, you should be able to test that your code handles all such errors, for example, think of the following scenarios:
- Can't handle DivideByZeroException
- Consider the scenario of AccessDenied
- Don't ignore NullReferenceExceptions
- Check for existence; FileNotFoundException, DirectoryNotFoundException and so on
Properties of a Good Unit Test
Units Tests are very simple and usually small C# code segments, but there are a few criteria that can really define what a good Unit Test is. Here are the properties that a good Unit Test must have:
Automatic: Each Test must “Automatically” exercise small functionality in terms of invoking the test and verifying the results.
Thorough: Unit Tests are supposed to test all the possible areas of functionality that are subject to failure due to incorrect input.
Repeatable: Unit Tests must be repeatable for every build and must produce the same results. The development best practice suggests that if you are working on code that is impacting a Unit Test then you must fix the affected Unit Test as well and ensure that it passes.
Independent: Unit Tests must be independent of another test. In other words, no collateral damage. Hence, a Unit Test must focus only on a small aspect of big functionality. When this Unit Test fails, it should be easy to discover where the issue is in the code.
Professional: Even though at times Unit Tests may appear to be very simple and small, you must write Unit Tests with coding practices as good as you use for your main development coding. You may want to follow Refactoring, Code Analysis, and Code Review practices, and so on as for your Test Projects as well.
Structure of a Unit Test - Arrange, Act and Assert
An ideal unit test code is divided into the following three main sections:
- Arrange: Set up all conditions needed for testing (create any required objects, allocate any needed resources, and so on).
- Invoke the method to be tested with possible parameters or values.
- Assert: Verify that the tested method returns the output as expected.
Let's follow TDD
From the SUT we have, let's focus on a piece of production code.

- private bool accountStatus = false;
- public bool IsAccountActive(string accNumber)
- {
- return accountStatus;
- }
- [TestMethod]
- public void TestAccountStatus_Active_Success()
- {
- Assert.IsTrue(obj.IsAccountActive("1234"),"Failed Account is not Active");
- }
- public bool IsAccountActive(string accNumber)
- {
- if (accNumber != null)
- {
- accountStatus = true;
- }
- else
- {
- accountStatus = false;
- }
- return accountStatus;
- }

- // Exception is thrown if Null is passed as account number
- [TestMethod][Priority(0)]
- [ExpectedException(typeof(ArgumentException))]
- public void TestAccountStatus_ArgumentException_Success()
- {
- obj.IsAccountActive(null);
- }

- public bool IsAccountActive(string accNumber)
- {
- if (accNumber != null)
- {
- accountStatus = true;
- }
- else
- if (accNumber == null)
- {
- throw new ArgumentException("Account number Can't be Null");
- }
- else
- {
- accountStatus = false;
- }
- return accountStatus;
- }

- [TestMethod] [Priority(0)]
- [ExpectedException(typeof(ArgumentException))]
- public void TestAccountStatus_AccountNumberWhiteSpace_ArgumentException_Success()
- {
- obj.IsAccountActive(" ");
- }

- public bool IsAccountActive(string accNumber)
- {
- if (accNumber != null)
- {
- accountStatus = true;
- }
- else
- if (String.IsNullOrWhiteSpace(accNumber))
- {
- throw new ArgumentException("Account number Can't be Null or have
- White Spaces");
- }
- else
- {
- accountStatus = false;
- }
- return accountStatus;
- }






So what we discovered is that the first condition accNumber!= null is true even if WhiteSpace has been passed as the account number. Hence, it's another opportunity to refactor the production code and re-run the Test(s). The new code additions are:
- public bool IsAccountActive(string accNumber)
- {
- if (String.IsNullOrWhiteSpace(accNumber))
- {
- throw new ArgumentException("Account number Can't be Null or have
- White Spaces");
- }
- else
- {
- accountStatus = true;
- }
- return accountStatus;
- }
YouTube Video

Ahmad UzairPosted Nov 6, 2021, 10:40 AM
Thank you for writing this wonderful piece!
Kaushal PareekPosted Aug 2, 2018, 11:08 PM
Thnq for the information. Very well explained.
Emrullah DanacıPosted Jul 27, 2018, 1:32 AM
Thanks for sharing
Prakash TripathiPosted Jun 18, 2016, 5:28 AM
Good one sir. Just to add the Pex you talked about in the you tube video has been introduced again in VS 2015 using IntelliTest.
Guest UserPosted May 31, 2016, 9:44 PM
I bookmarked this master piece of article!
Sr KarthigaPosted May 6, 2016, 9:15 PM
good one sir
Sandeep Singh ShekhawatPosted May 11, 2015, 8:21 AM
Great one. Last year I worked this way using your previous article http://www.c-sharpcorner.com/UploadFile/84c85b/inside-out-tdd-using-C-Sharp/
Manish Kumar ChoudharyPosted May 9, 2015, 3:29 PM
Good one.
Manoj KulkarniPosted May 9, 2015, 2:58 AM
Nice article. Thank you for sharing
Suthish NairPosted May 9, 2015, 12:18 AM
waw man, you best explained TDD.. one day I want to work under you...
NitinPosted May 8, 2015, 12:17 PM
nice sir..thanks for sharing
Sunny SharmaPosted May 8, 2015, 7:40 AM
very nice share vidya sir!
Sibeesh VenuPosted May 8, 2015, 7:05 AM
Good one .
Santhakumar MunuswamyPosted May 7, 2015, 11:54 PM
Thanks for nice article