Effective Strategies of Unit Testing

Step 1: Creation of a Test Plan

Step 2: Creation of Test Cases and the Test Data

Step 3: Creation of scripts to run the test cases wherever applicable

Step 4: Execution of the test cases, once the code is ready

Step 5: Fixing of the bugs if present and re testing of the code

Step 6: Repetition of the test cycle until the Unit is free from all types of bugs

What's the best strategy for unit-testing

These three unit test phases are also known as Arrange, Act and Assert, or simply AAA.

    try
    {
        // Setup:
        // Arrange:
        // Act:
        // Assert:
    }
    finally
    {
        // Teardown:
    }

https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters

https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters

https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters

https://blog.parasoft.com/unit-testing-best-practices-getting-the-most-out-of-your-test-automation

https://blog.parasoft.com/unit-testing-best-practices-getting-the-most-out-of-your-test-automation

https://blog.parasoft.com/unit-testing-best-practices-getting-the-most-out-of-your-test-automation

What Makes a Good Unit Test?

Before diving into the main part of this tutorial and writing unit tests, let’s quickly discuss the properties of a good unit test. Unit testing principles demand that a good test is:

  • Easy to write. Developers typically write lots of unit tests to cover different cases and aspects of the application’s behavior, so it should be easy to code all of those test routines without enormous effort.

  • Readable. The intent of a unit test should be clear. A good unit test tells a story about some behavioral aspect of our application, so it should be easy to understand which scenario is being tested and — if the test fails — easy to detect how to address the problem. With a good unit test, we can fix a bug without actually debugging the code!

  • Reliable. Unit tests should fail only if there’s a bug in the system under test. That seems pretty obvious, but programmers often run into an issue when their tests fail even when no bugs were introduced. For example, tests may pass when running one-by-one, but fail when running the whole test suite, or pass on our development machine and fail on the continuous integration server. These situations are indicative of a design flaw. Good unit tests should be reproducible and independent from external factors such as the environment or running order.

  • Fast. Developers write unit tests so they can repeatedly run them and check that no bugs have been introduced. If unit tests are slow, developers are more likely to skip running them on their own machines. One slow test won’t make a significant difference; add one thousand more and we’re surely stuck waiting for a while. Slow unit tests may also indicate that either the system under test, or the test itself, interacts with external systems, making it environment-dependent.

  • Truly unit, not integration. As we already discussed, unit and integration tests have different purposes. Both the unit test and the system under test should not access the network resources, databases, file system, etc., to eliminate the influence of external factors.

That’s it — there are no secrets to writing unit tests. However, there are some techniques that allow us to write testable code.

Testable and Untestable Code

Some code is written in such a way that it is hard, or even impossible, to write a good unit test for it. So, what makes code hard to test? Let’s review some anti-patterns, code smells, and bad practices that we should avoid when writing testable code.

Design Patterns

Inversion of Control (IoC)

Dependency Injection using a constructor is an implemented of IoC

Mocking database in Unit Tests using Moq

https://www.codeproject.com/Articles/478504/Moq-Mock-Database

    [AssemblyInitialize()]
    public static void AssemblyInit(TestContext context) {}

    [ClassInitialize()]
    public static void ClassInit(TestContext context) {}

    [TestInitialize()]
    public void Initialize() {}

    [TestCleanup()]
    public void Cleanup() {}

    [ClassCleanup()]
    public static void ClassCleanup() {}

    [AssemblyCleanup()]
    public static void AssemblyCleanup() {}

C# unit test with common code repeated

https://stackoverflow.com/questions/13943078/c-sharp-unit-test-with-common-code-repeated?noredirect=1&lq=1

private FooType foo;

[TestInitialize()]
public void TestInitialize()
{
    foo = CreateFooObject();
}

[TestMethod()]
public void TestToAssertThatAbcStuffGetsDone()
{
    foo.DoAbcStuff();
    Assert.IsTrue(foo.DidAbc());
}

[TestMethod()]
public void TestToAssertThatXyzStuffGetsDone()
{
    foo.DoXyzStuff();
    Assert.IsTrue(foo.DidXyz());
}

What would be an alternate to [TearDown] and [SetUp] in MSTest?

You would use [TestCleanup] and [TestInitialize] respectively.

Frontend Unit Testing

https://ringcentral.github.io/integration-blog/blog/2018/12/18/explore-a-more-complete-frontend-testing-strategy.html

https://medium.com/@unadlib/explore-a-more-complete-front-end-testing-strategy-e60b07cee621

MSDN Magazine Issues

https://msdn.microsoft.com/magazine/msdn-magazine-issues

Ebook Unit Testing

https://www.phparch.com/wp-content/uploads/2010/11/CWX_UnitTesting.pdf

Unit Test Guidelines

Integration Testing: Tests how you code integrates with different parts of a system. This can be making sure your code connects to a database properly or has created a file on the filesystem. These tests are usually very straight-forward and do not have the same constraint of "being able to run in any order." However, they require a specific configuration in order to pass which means they do float well from developer to developer.

Unit Testing: Tests your code's ability to preform a function.

https://www.automatetheplanet.com/unit-testing-guidelines/

https://www.guru99.com/unit-testing-guide.html

https://dzone.com/articles/unit-testing-best-practices-how-to-get-the-most-ou