Can I use IntelliTest to generate sensible unit-tests?

1.9k views Asked by At

The Microsoft documentation for IntelliTest says:

IntelliTest explores your .NET code to generate test data and a suite of unit tests. For every statement in the code, a test input is generated that will execute that statement. A case analysis is performed for every conditional branch in the code. For example, if statements, assertions, and all operations that can throw exceptions are analyzed. This analysis is used to generate test data for a parameterized unit test for each of your methods, creating unit tests with high code coverage.

I'm using Visual Studio 2017. I right-clicked inside my method, selected "IntelliTest" and then "Create IntelliTest". I accepted all the defaults on the pop-up dialogue box and clicked "OK".

    public static int ScanInternalInbox()
    {
        if (<code removed>)
        {
            <code removed>;
        }

        <code removed>;

        try
        {
            <code removed>;
        }
        catch (Exception e)
        {
            <code removed>;
            return 0;
        }

        <code removed>;

        try
        {
            <code removed>;
        }
        catch (Exception e)
        {
            <code removed>;
        }

        <code removed>;
        foreach (<code removed>)
        {
            <code removed>;

            if (<code removed>)
            {
                if (<code removed>)
                {
                    <code removed>;

                    if (<code removed>)
                    {
                        foreach (<code removed>)
                        {
                            <code removed>;
                            if (<code removed>)
                            {
                                if (<code removed>)
                                {
                                    <code removed>;
                                }
                            }
                        }

                        if (<code removed>)
                        {
                            if (<code removed>)
                            {
                                <code removed>;
                            }
                            else
                            {
                                <code removed>;
                            }
                        }
                    }
                    else
                    {
                        <code removed>;
                    }
                }
                else
                {
                    <code removed>;
                }                    
            }
            else
            {
                <code removed>;
            }
        }

        <code removed>;
    }

Why then, does my method with many, many (too many) ifs just generate this unit-test code?

public partial class HMR_AgentTest {

  /// <summary>Test stub for ScanInternalInbox()</summary>
  [PexMethod]
  public int ScanInternalInboxTest() {
    int result = global::HMR_Agent.HMR_Agent.ScanInternalInbox();
    return result;
    // TODO: add assertions to method HMR_AgentTest.ScanInternalInboxTest()
  }
}

I expected to get at least one test for each if, to cover the code (almost) completely. Did I do something wrong? Is there a way to generate default tests the way Microsoft claims?

EDIT

I've now Run IntelliTest too, and it has generated the following code:

  public partial class HMR_AgentTest {

[TestMethod]
[PexGeneratedBy(typeof(HMR_AgentTest))]
[PexRaisedException(typeof(TypeInitializationException))]
public void ScanInternalInboxTestThrowsTypeInitializationException908()
{
    int i;
    i = this.ScanInternalInboxTest();
    Assert.AreEqual<int>(-1, i);
}
  }

The test fails because an Exception is thrown, even though the test expects an Exception to be thrown.

1

There are 1 answers

1
Paul Abbott On

The [PexMethod] effectively just identifies the function you want to test. You need to right click and "IntelliTest -> Run IntelliTest" on the PexMethod for the first time to generate a child .g.cs file that contains tests for all paths of execution.

You "Run IntelliTest" again only when you make changes to the code that changes execution paths or alters the behavior; if you're just refactoring code, you don't need to generate new test code, you just run the generated [TestMethod] tests in the g.cs file as normal.